如何让 KeyStroke 像 JButton 一样为 JLabel 工作?

问题描述

我有一个像这张图片一样的登录表单。

enter image description here

登录按钮是一个带有图标的 JLabel。我希望能够按“ENTER”并登录

我已将登录逻辑放入名为 doAction() 的方法中;我在登录标签上有一个 MouseEvent,它按预期工作,并在我单击登录 Jlabel 时调用 doAction()。我希望任何时候按“ENTER”都会发生同样的事情。我试过这个:

        Keystroke keystroke = Keystroke.getKeystroke("ENTER");
        int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
        InputMap inputMap = login.getInputMap(condition);
        ActionMap actionMap = login.getActionMap();
        inputMap.put(keystroke,keystroke.toString());
        actionMap.put(keystroke.toString(),new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                doAction();
            }
        });

问题是,只有当我在 passwordField 中有光标时,这才有效。如果我在 usernameField 中使用光标,则它不起作用

解决方法

很难说“确切”发生了什么,因为我们只有一小段断章取义的片段,但我倾向于避免 KeyStroke.getKeyStroke("ENTER"),因为它并不总能产生预期的结果。相反,我直接使用 KeyEvent 虚拟键。

例如

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;

            add(new JTextField(10),gbc);
            add(new JPasswordField(10),gbc);

            add(new JLabel("..."),gbc);

            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0),"Login");
            am.put("Login",new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent evt) {
                    System.out.println("Do stuff here");
                }
            });
        }

    }
}