关于java:JTextField和DefaultButton关于ENTER键的使用

JTextField and DefaultButton regarding ENTER key consumption

在SSCCE波纹管中,我有一个带有注册KeyListener的JTextField。
如果键为ENTER,则KeyRelease函数将显示JOptionPane。

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

有任何线索吗?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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时对话框关闭,而在keyReleased时打开对话框。让我们看一下它如何运行:

  • 您按Enteron文本字段,什么都不会发生。
  • 您释放Enter,弹出对话框。
  • 您按Enter,对话框关闭,并且文本字段获得焦点。
  • 释放Enter,(因为您按下了它以关闭对话框),然后对话框再次弹出。
  • 对于Enter,我建议您采用以下解决方案:按下JTextField

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

    亲自检查一下,您会发现它的表现非常完美。

    现在,如果您想使用按键侦听器,则将需要更多的努力才能安全地实现它。也许焦点侦听器可以首先识别出未在文本字段中按下Enter的时间(在对话框中被按下,但是在文本字段中被释放)。

    我猜也有其他解决方法,但是我建议您使用动作侦听器。