java - 当 JOptionPane 窃取焦点时 JButton 保持按下状态

标签 java swing jtextfield joptionpane inputverifier

我是 Swing 新手,遇到了一些情况。我正在设计一个基于 xml 文件 input(meta-data) 动态呈现 GUI 组件的应用程序。现在我的大多数 JTextFields 都设置了 InputVerifier,用于验证目的。只要输入无效,输入 validator 就会弹出 JOptionPane。

现在,如果用户输入无效数据并向前移动并单击面板上的按钮,则会弹出一个对话框,用户必须对其做出响应。但在那之后按钮也不会绘制到释放状态。它看起来仍然像是被按下了,但实际上并没有。由于整个代码非常困惑,我将问题场景放在下面的代码中:-

我应该怎么做才能让 JButton 看起来没有被按下?如果逻辑也得到解释,我将不胜感激。

提前致谢。

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 的好地方。

您可以考虑多种方法来解决您的问题:

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

这是后一个选项的一小段:

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 是一个好方法申请)。

关于java - 当 JOptionPane 窃取焦点时 JButton 保持按下状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12500494/

相关文章:

java - 将请求范围的 bean 注入(inject) session 范围的 bean

Java 到 Arduino 的通信不同步 - 跳跃运动

java - 无论是否使用 ImageIcon,都对齐 JMenuItem 文本

java - JPanel 中的 JButtons 仅在鼠标悬停时出现

java - 动态更改 JTextField?

java - JTextField 未出现在 GUI 中

java - SELECT * FROM <table> BETWEEN <JTextField 中键入的值> AND <idem>

java - 如何使用 Scala 类作为跨类加载器的共享根对象?

Java - 字符中的重复大小写标签

java - JTabbedPane、Jpanel 和 Gridbaglayout