捕获鼠标事件但不捕获键事件 Java JComponent

MouseEvents are Captured but not KeyEvents Java JComponant

我正在开发一个名为 Lemmings 的老游戏项目,Principle Game Panel 运行良好并且接收到 MouseEvents 而不是 KeyEvents,这对我来说不是很合乎逻辑,所以我复制了这个代码存档给大家看看是怎么回事。

GamePanel class 扩展了 JComponent SWING class

public class GameFrame {

private class GamePanel extends JComponent {

    GamePanel(Dimension dim) {

        setPreferredSize(dim);

         //first version of the question was with the keyListner
        /*addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                super.keyPressed(e);
                System.out.println(e.getKeyCode());
                //nothing show up
            }
        });*/

         //I tried using this, but it didn't work
        //getInputMap().put(KeyStroke.getKeyStroke("A"), "action");

         // this works cause we use the right inputMap not the one by default 
         getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke("A"), "action");
         getActionMap().put("action",new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("A is pressed");
                //now it works
            }
        });

        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                System.out.println(e.getPoint());
            }
        });
        setVisible(true);
    }
}

private JFrame window;
private GamePanel panel; 

public GameFrame() {
    window = new JFrame("Test");
    window.setLocationRelativeTo(null);
    panel = new GamePanel(new Dimension(400, 400));
    window.setContentPane(panel);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setVisible(true);
}

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

更新解决方案

按键事件仅分派给可聚焦的组件。

默认情况下,JPanel 不可聚焦,因此它不会接收按键事件。

如果您试图基于 KeyEvent 调用某种 Action,那么您应该使用 Key Bindings,而不是 KeyListener。键绑定将允许您监听 KeyStroke,即使组件没有焦点。

阅读有关 How to Use Key Bindings 的 Swing 教程部分,了解更多信息和工作示例。

只要在 JFrame 中添加一个 KeyListener 就可以解决这个问题,因为我们不需要创建 Actions 之类的东西

此解决方案只有在没有其他组件可聚焦时才有可能。

在文件中 GameFrame.java 在函数 void init(); 添加

window.addKeyListener(new KeyAdapter() {
        @Override
        public void keyPressed (KeyEvent e) {
            super.keyPressed(e);
            System.out.println("test "+e.getKeyChar());
        }
    });