这个键绑定我做错了什么?
What am I doing wrong with this key binding?
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class Menu{
JFrame frame = new JFrame();
Image icon = Toolkit.getDefaultToolkit().getImage("image1.png");
Action escapePressed;
public Menu() {
frame.setVisible(true);
frame.setIconImage(icon);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setMinimumSize(new Dimension(500, 500));
frame.setTitle("Nine Games");
frame.setFocusable(true);
frame.setResizable(true);
frame.add(new StartScreen());
escapePressed = new EscapePressed();
frame.getInputMap().put(KeyStroke.getKeyStroke('w'), "escapePressed");
frame.getActionMap().put("escapePressed", escapePressed);
}
public class EscapePressed extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Escape Pressed");
System.exit(0);
}
}
}
我不知道为什么,但是这个程序说 getInputMap
和 getActionMap
不存在。这很奇怪。我可以发誓我把它全部正确地输入了。我什至遵循了教程,但似乎没有任何效果。
我不想使用 KeyStroke.getKeyStroke
,因为在如何触发击键方面存在一定程度的歧义,这是个人问题,但我浪费了太多时间尝试调试相关问题
相反,我更喜欢使用 KeyStroke.getKeyStroke(KeyEvent.VK_W, 0)
。这(对我而言)更容易理解,我也可以通过它配置“按下”或“释放”功能。
getInputMap()
的默认行为是生成事件 WHEN_FOCUSED
,这与您对 KeyListener
的期望相同,但您要将键绑定添加到 JFrame
,它不太可能获得焦点(它是一个复合组件,因此这样做没有意义)。
相反,您应该尝试类似...
frame.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "escapePressed");
frame.getActionMap().put("escapePressed", escapePressed);
现在,就我个人而言,我认为通过将组件添加到框架中来维护这种东西可能会更好,但这就是我。
几个问题:
- a JFrame 没有 InputMap 和 ActionMap。只有从 JComponent 扩展的组件才能使用键绑定。因此,要处理退出 KeyStroke,您可能想使用
JRootPane
添加绑定
- 您不想使用默认的
WHEN_FOCUSED
InputMap,因为根窗格不会获得焦点,因为您添加到框架的其他一些组件将获得焦点。相反,您想使用 WHEN_IN_FOCUSED_WINDOW
InputMap.
所以你的代码可能是这样的:
//frame.getInputMap().put(KeyStroke.getKeyStroke('w'), "escapePressed");
//frame.getActionMap().put("escapePressed", escapePressed);
frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('w'), "escapePressed");
frame.getRootPane().getActionMap().put("escapePressed", escapePressed);
阅读 How to Use Key Bindings 上的 Swing 教程部分了解更多信息。
另请查看 Using Top Level Containers 了解有关根窗格的更多信息。
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class Menu{
JFrame frame = new JFrame();
Image icon = Toolkit.getDefaultToolkit().getImage("image1.png");
Action escapePressed;
public Menu() {
frame.setVisible(true);
frame.setIconImage(icon);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setMinimumSize(new Dimension(500, 500));
frame.setTitle("Nine Games");
frame.setFocusable(true);
frame.setResizable(true);
frame.add(new StartScreen());
escapePressed = new EscapePressed();
frame.getInputMap().put(KeyStroke.getKeyStroke('w'), "escapePressed");
frame.getActionMap().put("escapePressed", escapePressed);
}
public class EscapePressed extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Escape Pressed");
System.exit(0);
}
}
}
我不知道为什么,但是这个程序说 getInputMap
和 getActionMap
不存在。这很奇怪。我可以发誓我把它全部正确地输入了。我什至遵循了教程,但似乎没有任何效果。
我不想使用 KeyStroke.getKeyStroke
,因为在如何触发击键方面存在一定程度的歧义,这是个人问题,但我浪费了太多时间尝试调试相关问题
相反,我更喜欢使用 KeyStroke.getKeyStroke(KeyEvent.VK_W, 0)
。这(对我而言)更容易理解,我也可以通过它配置“按下”或“释放”功能。
getInputMap()
的默认行为是生成事件 WHEN_FOCUSED
,这与您对 KeyListener
的期望相同,但您要将键绑定添加到 JFrame
,它不太可能获得焦点(它是一个复合组件,因此这样做没有意义)。
相反,您应该尝试类似...
frame.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "escapePressed");
frame.getActionMap().put("escapePressed", escapePressed);
现在,就我个人而言,我认为通过将组件添加到框架中来维护这种东西可能会更好,但这就是我。
几个问题:
- a JFrame 没有 InputMap 和 ActionMap。只有从 JComponent 扩展的组件才能使用键绑定。因此,要处理退出 KeyStroke,您可能想使用
JRootPane
添加绑定 - 您不想使用默认的
WHEN_FOCUSED
InputMap,因为根窗格不会获得焦点,因为您添加到框架的其他一些组件将获得焦点。相反,您想使用WHEN_IN_FOCUSED_WINDOW
InputMap.
所以你的代码可能是这样的:
//frame.getInputMap().put(KeyStroke.getKeyStroke('w'), "escapePressed");
//frame.getActionMap().put("escapePressed", escapePressed);
frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('w'), "escapePressed");
frame.getRootPane().getActionMap().put("escapePressed", escapePressed);
阅读 How to Use Key Bindings 上的 Swing 教程部分了解更多信息。
另请查看 Using Top Level Containers 了解有关根窗格的更多信息。