关于 ENTER 键消耗的 JTextField 和 DefaultButton
JTextField and DefaultButton regarding ENTER key consumption
在下面的 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
时关闭,但您在 keyReleased
时打开对话框。让我们通过一个例子看看它是如何运行的:
- 您在文本字段上按 Enter,没有任何反应。
- 你RELEASE输入,弹出对话框
- 您按 Enter,对话框关闭,文本字段获得焦点。
- 您松开 Enter,(因为您按下它是为了关闭对话框),然后对话框再次弹出。
我建议您使用以下解决方案,当涉及到 输入 时,请按 JTextField
:
tf.addActionListener(e -> {
JOptionPane.showMessageDialog(f, "Invalid input value, Press ENTER");
});
你自己检查一下,你会发现它表现完美。
现在,如果您想使用您的密钥侦听器,则需要付出更多的努力才能安全地实现它。也许是一个焦点侦听器,它可以识别何时没有在文本字段中首先按下输入(它是在对话框中按下的,但在文本字段上已释放)。
我想还有其他解决方法,但我建议您使用动作侦听器。
在下面的 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
时关闭,但您在 keyReleased
时打开对话框。让我们通过一个例子看看它是如何运行的:
- 您在文本字段上按 Enter,没有任何反应。
- 你RELEASE输入,弹出对话框
- 您按 Enter,对话框关闭,文本字段获得焦点。
- 您松开 Enter,(因为您按下它是为了关闭对话框),然后对话框再次弹出。
我建议您使用以下解决方案,当涉及到 输入 时,请按 JTextField
:
tf.addActionListener(e -> {
JOptionPane.showMessageDialog(f, "Invalid input value, Press ENTER");
});
你自己检查一下,你会发现它表现完美。
现在,如果您想使用您的密钥侦听器,则需要付出更多的努力才能安全地实现它。也许是一个焦点侦听器,它可以识别何时没有在文本字段中首先按下输入(它是在对话框中按下的,但在文本字段上已释放)。
我想还有其他解决方法,但我建议您使用动作侦听器。