【问题标题】:Invoke a serie of actions when Enter key is pressed按下 Enter 键时调用一系列动作
【发布时间】:2020-11-13 07:22:41
【问题描述】:

我有一个 Swing 项目,我在 JTextField 上有一个动作监听器,用于 Tab 键,如下所示。

动作监听器中有一个JOptionPane.showMessageDialog()。当 Tab 被按下时,选项窗格将显示一条信息消息。

我的问题是,当我在信息消息对话框的 OK 按钮上按 Enter 时,会调用一系列动作,即 JTextFieldTab 动作>EnterbtnNewButton的动作。

如果我用鼠标点击错误消息对话框的确定​​按钮,一切都很好,没有问题。

我可以使用键绑定而不是键侦听器来解决这个问题吗?

请提出解决方案

import java.awt.EventQueue;
import java.awt.KeyboardFocusManager;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Collections;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

public class Test extends JFrame {
    private JPanel contentPane;
    private JTextField textField;
    private JButton btnNewButton;
    private JDialog dialog;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Test frame = new Test();
                    frame.setVisible(true);
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public Test() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        setLocationRelativeTo(null);
        contentPane.setLayout(null);

        textField = new JTextField();
        textField.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
                Collections.emptySet());
        textField.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                if (evt.getKeyCode() == KeyEvent.VK_TAB) {
                    JOptionPane.showMessageDialog(dialog, " Please Press ENTER Key", "information",
                            JOptionPane.INFORMATION_MESSAGE);

                    btnNewButton.grabFocus();
                }
            }
        });
        textField.setBounds(73, 28, 178, 28);
        contentPane.add(textField);
        textField.setColumns(10);

        btnNewButton = new JButton("New button");
        btnNewButton.addKeyListener(new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                    JOptionPane.showMessageDialog(dialog, " That Invoked New Button Also", "Error",
                            JOptionPane.ERROR_MESSAGE);
                }
            }
        });
        btnNewButton.setBounds(223, 137, 117, 25);
        contentPane.add(btnNewButton);

        JLabel lblNewLabel = new JLabel("Please Press TAB Key");
        lblNewLabel.setBounds(83, 55, 183, 15);
        contentPane.add(lblNewLabel);

        dialog = new JDialog();
        dialog.setAlwaysOnTop(true);
    }
}

【问题讨论】:

  • “我可以使用键绑定而不是键监听器来解决这个问题吗?” 嗯,.. 是的,你可以,但我首先想到的是 DocumentListener一般提示: 1) 使用合乎逻辑且一致的形式缩进代码行和块。缩进是为了让代码流更容易理解!大多数 IDE 都有专门用于格式化代码的键盘快捷键。 2) 为了尽快获得更好的帮助,edit 添加minimal reproducible exampleShort, Self Contained, Correct Example。 3) Java GUI 必须在不同的操作系统、屏幕尺寸、屏幕分辨率等上工作。..
  • .. 在不同的语言环境中使用不同的 PLAF。因此,它们不利于像素完美布局。而是使用布局管理器,或 combinations of them 以及 white space 的布局填充和边框。
  • @Andrew 我已经编辑了代码,现在可以重现了。请建议我进行必要的修改。

标签: java swing keylistener key-bindings actionevent


【解决方案1】:

问题是您正在覆盖方法keyReleased()JOptionPanekeyReleased() 方法被调用之前关闭,并且由于您在 JOptionPane 关闭之后使 btnNewButton 成为焦点组件,因此将调用 keyReleased() 方法 - 它显示另一个 JOptionPane

只需将方法重命名为keyPressed()

另外,您不需要dialog 成员。 JOptionPane#showMessageDialog 的第一个参数应该是 JFrame

这是您的代码以及我的更正。

import java.awt.EventQueue;
import java.awt.KeyboardFocusManager;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Collections;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

public class Test extends JFrame {
    private JPanel contentPane;
    private JTextField textField;
    private JButton btnNewButton;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Test frame = new Test();
                    frame.setVisible(true);
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public Test() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        setLocationRelativeTo(null);
        contentPane.setLayout(null);

        textField = new JTextField();
        textField.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
                Collections.emptySet());
        textField.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                if (evt.getKeyCode() == KeyEvent.VK_TAB) {
                    JOptionPane.showMessageDialog(Test.this, " Please Press ENTER Key", "information",
                            JOptionPane.INFORMATION_MESSAGE);
                    btnNewButton.grabFocus();
                }
            }
        });
        textField.setBounds(73, 28, 178, 28);
        contentPane.add(textField);
        textField.setColumns(10);

        btnNewButton = new JButton("New button");
        btnNewButton.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                    JOptionPane.showMessageDialog(Test.this, " That Invoked New Button Also", "Error",
                            JOptionPane.ERROR_MESSAGE);
                }
            }
        });
        btnNewButton.setBounds(223, 137, 117, 25);
        contentPane.add(btnNewButton);

        JLabel lblNewLabel = new JLabel("Please Press TAB Key");
        lblNewLabel.setBounds(83, 55, 183, 15);
        contentPane.add(lblNewLabel);
    }
}

请注意(至少在 JDK 15 中)不需要为JFrame 显式设置默认关闭操作,因为默认 EXIT_ON_CLOSE

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-25
    • 1970-01-01
    • 1970-01-01
    • 2012-11-29
    • 2015-09-25
    • 1970-01-01
    • 2010-11-03
    相关资源
    最近更新 更多