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

问题描述 投票:0回答:2

我正在开发一个名为Lemmings的旧游戏项目,并且Principle Game Panel运行良好并且接收了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不可调焦,因此它不会收到KeyEvent所以我们必须使用Key Bindings方法
  • 我发现每个JComponent都有三个由WHEN_IN_FOCUSED_WINDOW,WHEN_FOCUSED,WHEN_ANCESTOR_OF_FOCUSED_COMPONENT引用的inputMaps,我们必须确保我们正在使用正确的工作来完成我们的工作
  • 有关更多信息,请查看How to use key Bindings并检查方法getInputMap()和getInputMap(int)
java swing key-bindings jcomponent key-events
2个回答
1
投票

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

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

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

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


0
投票

如果我们不需要创建Actions和东西,只需在JFrame中添加KeyListener即可解决问题

只有在没有可聚焦的其他组件的情况下才能实现此解决方案。

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

window.addKeyListener(new KeyAdapter() {
        @Override
        public void keyPressed (KeyEvent e) {
            super.keyPressed(e);
            System.out.println("test "+e.getKeyChar());
        }
    }); 
© www.soinside.com 2019 - 2024. All rights reserved.