当JOptionPane窃取焦点时,JButton保持按下状态 [英] JButton stays pressed when focus stolen by JOptionPane

查看:116
本文介绍了当JOptionPane窃取焦点时,JButton保持按下状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Swing的新手,但我遇到了情况.我正在设计一个基于xml文件input(meta-data)动态呈现GUI组件的应用程序.现在,我的大多数JTextField都将InputVerifier设置为它们,以进行验证.每当输入无效时,输入验证器都会弹出JOptionPane.

I am new to Swing and I have a situation. I am designing an application that renders the GUI components dynamically based on an xml file input(meta-data) . Now most of my JTextFields have InputVerifier set to them, for validation purpose. The input verifier pops up JOptionPane whenever there is an invalid input.

现在,如果用户输入无效数据并向前移动并单击面板上的按钮,则将弹出对话框,用户必须对此做出响应.但此后该按钮也不会绘画以释放状态.它看起来仍然像被按下,但实际上并非如此.由于整个代码非常混乱,因此我将问题场景放在下面的代码中:-

Now, if a user enter an invalid data and moves ahead and clicks a button on the Panel, then a dialog pops up and the user have to respond to it. but after that also the button does not paint to release state. It still looked like it is pressed but actually it is not. As the whole code is pretty messy, I am putting the problem scenario in the code below:-

我应该怎么做才能使JButton看起来不受压?如果逻辑也得到了解释,我将不胜感激.

What should I do so that the JButton looks unpressed? I would appreciate if the logic is also explained.

先谢谢了.

package test;

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.InputVerifier;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

public class VerifierTest extends JFrame {

    private static final long serialVersionUID = 1L;

    public VerifierTest() {
        JTextField tf;
        tf = new JTextField("TextField1");

        getContentPane().add(tf, BorderLayout.NORTH);
        tf.setInputVerifier(new PassVerifier());

        final JButton b = new JButton("Button");
        b.setVerifyInputWhenFocusTarget(true);
        getContentPane().add(b, BorderLayout.EAST);
        b.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (b.hasFocus())
                    System.out.println("Button clicked");
            }
        });

        addWindowListener(new MyWAdapter());
    }

    public static void main(String[] args) {
        Frame frame = new VerifierTest();
        frame.setSize(400, 200);
        frame.setVisible(true);
        //frame.pack();
    }

    class MyWAdapter extends WindowAdapter {

        public void windowClosing(WindowEvent event) {
            System.exit(0);
        }
    }

    class PassVerifier extends InputVerifier {

        public boolean verify(JComponent input) {
            JTextField tf = (JTextField) input;
            String pass = tf.getText();
            if (pass.equals("Manish"))
                return true;
            else {
                String message = "illegal value: " + tf.getText();
                JOptionPane.showMessageDialog(tf.getParent(), message,
                        "Illegal Value", JOptionPane.ERROR_MESSAGE);

                return false;
            }
        }
    }
}

推荐答案

方法verify实际上不是打开JOptionPane的好地方.

The method verify is actually not a good place to open a JOptionPane.

您可以考虑采用几种方法来解决问题:

There are several approaches you could consider to solve your problem:

  1. 您希望此JOptionPane在每次文本字段失去焦点且输入不正确时出现:在JTextField上使用FocusListener并对适当的事件采取行动
  2. 您希望每次按下按钮时都显示此JOptionPane:如果输入不正确,请使用ActionListener进行操作.

这是后一种选择的一小段:

Here is a small snippet of the latter option:

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.InputVerifier;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

public class VerifierTest extends JFrame {

    private static final long serialVersionUID = 1L;

    public VerifierTest() {
        final JTextField tf = new JTextField("TextField1");

        getContentPane().add(tf, BorderLayout.NORTH);
        tf.setInputVerifier(new PassVerifier());

        final JButton b = new JButton("Button");
        b.setVerifyInputWhenFocusTarget(true);
        getContentPane().add(b, BorderLayout.EAST);
        b.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (!tf.getInputVerifier().verify(tf)) {
                    JOptionPane.showMessageDialog(tf.getParent(), "illegal value: " + tf.getText(), "Illegal Value",
                            JOptionPane.ERROR_MESSAGE);
                }
                if (b.hasFocus()) {
                    System.out.println("Button clicked");
                }
            }
        });
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        Frame frame = new VerifierTest();
        frame.setSize(400, 200);
        frame.setVisible(true);
    }

    class PassVerifier extends InputVerifier {

        @Override
        public boolean verify(JComponent input) {
            final JTextField tf = (JTextField) input;
            String pass = tf.getText();
            return pass.equals("Manish");
        }
    }
}

也可以考虑设置JFrame的默认关闭操作,而不是添加窗口侦听器(但是,如果要弹出对话框询问用户是否确定要退出您的对话框,使用WindowListener是一个好方法应用程序.)

Also consider setting the default close operation of the JFrame instead of adding a window listener (but it is a good approach to use a WindowListener if you want to pop up a dialog asking the user if he is sure he wants to exit your application).

这篇关于当JOptionPane窃取焦点时,JButton保持按下状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆