代码之家  ›  专栏  ›  技术社区  ›  Eugene

当我单击不相关的按钮时,为什么我的密钥绑定无法工作?

  •  3
  • Eugene  · 技术社区  · 10 年前

    我创建了一个简单的演示。如果您在主面板上触发特定按键Stroke事件,将显示消息“a is typed”。然而,当我按下主面板下面的按钮后,它就不起作用了。 下面是KeybindingTest类及其内部类:

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    public class KeybindingTest {
        private JFrame frame;
        private MainPanel mainPanel;
        private ButtonPanel buttonPanel;
        public static void main(String[] args) {
            KeybindingTest test = new KeybindingTest();
            test.createUI();
        }
    
        public void createUI(){
            frame = new JFrame("Keybing Test");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            mainPanel = new MainPanel();
            buttonPanel = new ButtonPanel();
            frame.add(mainPanel,BorderLayout.CENTER);
            frame.add(buttonPanel,BorderLayout.SOUTH);
            KeybindingListener.getInstance().keybinding(mainPanel);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    
        @SuppressWarnings("serial")
        class MainPanel extends JPanel{
            @Override
            public Dimension getPreferredSize() {
                // TODO Auto-generated method stub
                return new Dimension(400, 300);
            }
        }
    
        @SuppressWarnings("serial")
        class ButtonPanel extends JPanel{
            public ButtonPanel(){
                setBackground(Color.green);
                JButton enableButton = new JButton("enable");
                enableButton.addActionListener(new EnableButtonListener());
                JButton disableButton = new JButton("disable");
                disableButton.addActionListener(new DisableButtonListener());
                add(enableButton);
                add(disableButton);
            }
        }
    
        class EnableButtonListener implements ActionListener{
            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                System.out.println("enabled");
            }
    
        }
    
        class DisableButtonListener implements ActionListener{
            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                System.out.println("disabled");
            }
    
        }
    }
    

    下面是KeybindingListener类及其内部类:

    import java.awt.event.ActionEvent;
    import java.awt.event.KeyEvent;
    
    import javax.swing.AbstractAction;
    import javax.swing.JPanel;
    import javax.swing.KeyStroke;
    
    public class KeybindingListener {
        private static KeybindingListener keybindingListener;
        private final String mapKey = "a";
    
        private KeybindingListener(){
            //singleton
        }
    
        public static KeybindingListener getInstance(){
            if (keybindingListener == null) {
                keybindingListener = new KeybindingListener();
                return keybindingListener;
            }else {
                return keybindingListener;
            }
        }
    
        public void keybinding(JPanel mainPanel){
            mainPanel.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_A , 0),mapKey);
            mainPanel.getActionMap().put(mapKey, new keyAction());
        }
    
        @SuppressWarnings("serial")
        class keyAction extends AbstractAction{
    
            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                System.out.println("a is typed");
            }
    
        }
    }
    

    提前感谢您的帮助。

    1 回复  |  直到 10 年前
        1
  •  5
  •   Community Egal    7 年前

    如中所述 this answer , JComponent#getInputMap() 是一种方便的方法 JComponent#getInputMap(WHEN_FOCUSED) 。由于要将密钥绑定添加到 JPanel 这意味着您的小组必须专注于正确工作,这是不可能的。

    您可以按原样将键绑定添加到面板中的所有组件,也可以按如下方式向面板添加键绑定:

    public void keybinding(JPanel mainPanel){
        mainPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_A , 0),mapKey);
        mainPanel.getActionMap().put(mapKey, new keyAction());
    }
    

    看见 How Key Bindings Work 为了更好地解释这件事。