捕获鼠标事件但不捕获键事件 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();
}
}
更新解决方案
- 我了解到 JComponants 不可聚焦,因此它不接收 KeyEvents,因此我们必须使用 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 教程部分,了解更多信息和工作示例。
只要在 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());
}
});
我正在开发一个名为 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();
}
}
更新解决方案
- 我了解到 JComponants 不可聚焦,因此它不接收 KeyEvents,因此我们必须使用 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 教程部分,了解更多信息和工作示例。
只要在 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());
}
});