我正在开发一个名为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();
}
}


解决方案更新


我了解到JComponant不能聚焦,因此它不接收KeyEvent,因此我们必须使用Key Bindings方法
我发现每个JComponent都具有三个由WHEN_IN_FOCUSED_WINDOW,WHEN_FOCUSED,WHEN_ANCESTOR_OF_FOCUSED_COMPONENT引用的inputMap,我们必须确保在工作中使用正确的输入映射。
有关更多信息,请查看How to use key Bindings并检查方法getInputMap()和getInputMap(int)

最佳答案

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

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

如果尝试基于KeyEvent调用某种Action,则应使用Key Bindings,而不是KeyListener。按键绑定将使您可以监听KeyStroke,即使该组件没有焦点。

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

09-09 21:38
查看更多