当前位置: 首页 > 面试题库 >

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

戚均
2023-03-14
问题内容

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



 类似资料:
  • 当我将RecycerView放入嵌套的scrollview中时,屏幕总是跳到RecycerView的顶部,而不是页面的顶部。这里有一个简单的例子。 在这个示例中,我在Recyview上有一个350dp高的空视图,因为您需要在Recyview上有一些内容才能明显显示出来。Recyview iteself包含100个虚拟文本视图。 启动活动后,滚动位于Recyview的顶部,而不是页面的顶部。这一定是

  • JavaFX有一个问题,当我弹出一个新阶段时,该新窗口将从具有当前焦点的任何Windows应用程序中获取焦点 我希望它弹出到前面,但不对焦,所以如果用户在其他地方打字,他们可以继续打字等。 在Swing中,您可以通过以下方式解决此问题: JavaFx中似乎没有类似的选项。 下面的例子,当你点击按钮时,它将弹出一个新的阶段,获得焦点(注意,我不想要求焦点回来,因为在真正的应用程序中,当弹出发生时,用

  • 当我点击ListFragment中的EditText(请参见“您的答案…”字段是下面的屏幕上限)时,它不会保持焦点,因此无法使用。文本光标一出现在EditText字段上,它就会迅速消失,EditText域就会失去焦点。 我发现了一些相关的堆栈帖子,并怀疑有什么东西可能从EditText中窃取了焦点。请参阅此处的相关帖子。我也读过关于强迫聚焦的帖子,但没有什么意义。 我可以以编程方式构建视图,但是使

  • 页面上有两个按钮,当你点击其中一个时,它会改变颜色。 如何让这个焦点点击旁边的空字段后不会消失?

  • 有什么方法可以防止新舞台抢走主舞台的焦点? 我指的是每个新的<代码>阶段。show() 从我的主舞台上偷走了焦点。 我不想把我的JavaFX和Swing混在一起,所以没有将内容嵌入JFrame的选项。此外,这将是伟大的不使用任何弹出,只是纯粹的阶段。 有什么外部库允许我这么做吗?