MouseEvents是捕获的,但不是KeyEvents Java JComponant

时间:2017-12-21 15:51:44

标签: java swing key-bindings jcomponent key-events

我正在开发一个名为Lemmings的旧游戏项目,而且主游戏面板运行良好并且接收了MouseEvents而不是KeyEvents,这对我来说不是很合乎逻辑,所以我复制了这个代码为你们提供文件,了解最新情况。

GamePanel类扩展了JComponent SWING类

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();
}
}

更新解决方案

  • 我了解到JComponants不可调焦,因此它没有收到KeyEvents所以我们必须使用Key Bindings方法
  • 我发现每个JComponent都有三个由WHEN_IN_FOCUSED_WINDOW,WHEN_FOCUSED,WHEN_ANCESTOR_OF_FOCUSED_COMPONENT引用的inputMaps,我们必须确保我们正在使用正确的工作
  • 了解更多信息,请查看How to use key Bindings并检查方法 getInputMap() getInputMap(int)

2 个答案:

答案 0 :(得分:1)

关键事件仅发送到可聚焦组件。

默认情况下,JPanel不可聚焦,因此不会收到关键事件。

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

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

答案 1 :(得分:0)

只要我们不需要创建操作和内容,就可以通过向JFrame添加KeyListener来解决问题

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

文件GameFrame.java中的

在函数void init(); 添加

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