【问题标题】:JTextField and DefaultButton regarding ENTER key consumption关于 ENTER 键消耗的 JTextField 和 DefaultButton
【发布时间】:2020-09-10 01:02:24
【问题描述】:

在下面的 SSCCE 中,我有一个带有已注册 KeyListener 的 JTextField。 KeyRelease 函数,如果键是 ENTER,将显示一个 JOptionPane。

问题是:如果用户使用 ENTER 键验证 JOptionPane,选项窗​​格将再次出现! 似乎 ENTER 键没有被消耗并转发到 JTextField。

有什么线索吗?

import java.awt.EventQueue;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

public class DefaultButtonAndTextFieldKeypress {
    private static void createGUI() {
        JFrame f = new JFrame("Test");
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        JTextField tf = new JTextField("Press ENTER");
        tf.addKeyListener(new KeyListener() {           
            @Override
            public void keyTyped(KeyEvent e) {}

            @Override
            public void keyReleased(KeyEvent e) {
                System.out.println("TextField::keyReleased");
                if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                    JOptionPane.showMessageDialog(f, "Invalid input value, Press ENTER");
                }
            }

            @Override
            public void keyPressed(KeyEvent e) {}
        });

        f.add(tf);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                createGUI();
            }
        });
    }
}

【问题讨论】:

  • 如果您改为从keyPressed 函数打开JOptionPane 会怎样?另外,我没有看到你自己消费关键事件。

标签: java swing jtextfield joptionpane


【解决方案1】:

这是因为对话框在keyPressed 时关闭,但您在keyReleased 时打开对话框。让我们通过一个例子来看看它是如何运行的:

  1. 您在文本字段上按 Enter,没有任何反应。
  2. RELEASE Enter,弹出对话框。
  3. 您按下 Enter,对话框关闭并且文本字段获得焦点。
  4. 你松开Enter,(因为你按下它来关闭对话框),对话框再次弹出。

我建议您使用以下解决方案,当涉及到 Enter 时,请按 JTextField:

tf.addActionListener(e -> {
    JOptionPane.showMessageDialog(f, "Invalid input value, Press ENTER");
});

自己检查一下,你会发现它的表现很完美。

现在,如果您想使用关键侦听器,则需要付出更多努力才能安全地实现它。也许一个焦点侦听器可以识别何时没有在文本字段中按下输入(它是在对话框上按下,但在文本字段上被释放)。

我想还有其他解决方法,但我建议你使用动作监听器。

【讨论】:

  • 非常感谢,我很清楚这里发生了什么。而且我确实需要 keyListener 因为这是我的应用程序的简化部分(以说明问题),而我当前的 JTextField 正在管理其他键;(
  • 我按照建议将 ENTER 键管理从 keyListener 移动到动作监听器,并保留其他键,这很棒!所以对我来说,这回答了我的问题并挽救了我的一天;)
  • @Staifi78 很高兴能帮到你。由于您是新用户,请查看What should I do when someone answers my question
猜你喜欢
  • 2012-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 2011-12-24
相关资源
最近更新 更多