我是否正确构建了此关键侦听器?

我问,因为我希望在用户点击输入时调用我的GamePanel类中的addShot()方法,“这会初始化一个代表从船上发射的导弹的镜头对象,但它没有做任何事情。是否有这里的可见性问题,还是我只是构造了关键事件和监听器关系错误?我只发布相关代码,但我可以在必要时发布其余的代码。

这是代码:

 public static class GameTest extends JFrame { private static final int WINDOW_WIDTH = 800; private static final int WINDOW_HEIGHT = 500; public GamePanel gamePanel; public GameTest() throws IOException { super("Deep Fried Freedom"); setResizable(false); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(WINDOW_WIDTH, WINDOW_HEIGHT); setLayout(new BorderLayout()); gamePanel = new GamePanel(); add(gamePanel); center(this); setVisible(true); this.addKeyListener(new aKeyListener()); this.setFocusable(true); } // end constructor public void center(JFrame frame) { GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); Point center = ge.getCenterPoint(); int w = frame.getWidth(); int h = frame.getHeight(); int x = center.x - w / 2, y = center.y - h / 2; frame.setBounds(x, y, w, h); frame.validate(); }//end of center method public class aKeyListener implements KeyListener { @Override public void keyTyped(KeyEvent e) { }//end empty keyTyped method @Override public void keyPressed(KeyEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_A: Launcher.lRun = -20; gamePanel.move(gamePanel); break; case KeyEvent.VK_D: Launcher.lRun = 20; gamePanel.move(gamePanel); break; case KeyEvent.VK_ENTER: gamePanel.addShot(); break; default: Launcher.lRun = 0; } }//end keyPressed method @Override public void keyReleased(KeyEvent e) { }//end empty keyReleased method }//end aKeyListener class }//end GameTest class 

  1. 你的可能是一个焦点问题 – 在GamePanel中可能会窃取焦点,这是KeyListeners的一个非常常见的问题。
  2. 一般建议:赞成使用Key Bindings,而不是KeyListener来满足此类需求。

有用的链接:

  • Swing资源
  • 请在我对StackOverflow问题的回答中查看我的第二个示例程序。
  • 整体Swing教程
  • 关键绑定
  • 摆动计时器
  • Swing中的并发性

编辑
例如:

 import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import javax.swing.*; public class GameTest extends JFrame { private static final int WINDOW_WIDTH = 800; private static final int WINDOW_HEIGHT = 500; public GamePanel gamePanel; public GameTest() { super("Deep Fried Freedom"); setResizable(false); // setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); // setSize(WINDOW_WIDTH, WINDOW_HEIGHT); // never do this gamePanel = new GamePanel(); setUpKeyBinding(gamePanel); add(gamePanel); pack(); setLocationRelativeTo(null); // to center! setVisible(true); } @Override public Dimension getPreferredSize() { return new Dimension(WINDOW_WIDTH, WINDOW_HEIGHT); } private void setUpKeyBinding(GamePanel gamePanel2) { // only need window to have focus int condition = JComponent.WHEN_IN_FOCUSED_WINDOW; // get the GamePanel's InputMap and ActionMap as these will be used to set // up our Key Bindings InputMap inputMap = gamePanel2.getInputMap(condition); ActionMap actionMap = gamePanel2.getActionMap(); // bind the A key to move back 20 pixels KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_A, 0); inputMap.put(keyStroke, keyStroke.toString()); actionMap.put(keyStroke.toString(), new MoveAction(gamePanel2, -20)); // bind the D key to move forward 20 pixels keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_D, 0); inputMap.put(keyStroke, keyStroke.toString()); actionMap.put(keyStroke.toString(), new MoveAction(gamePanel2, 20)); // bind the ENTER key keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0); inputMap.put(keyStroke, keyStroke.toString()); actionMap.put(keyStroke.toString(), new EnterAction(gamePanel2)); } public static void main(String[] args) { new GameTest(); } // our Action classes that will bound to key strokes private class MoveAction extends AbstractAction { private GamePanel gamePanel2; private int distance; public MoveAction(GamePanel gamePanel2, int distance) { this.gamePanel2 = gamePanel2; this.distance = distance; } @Override public void actionPerformed(ActionEvent e) { gamePanel2.moveItem(distance); } } private class EnterAction extends AbstractAction { private GamePanel gamePanel2; public EnterAction(GamePanel gamePanel2) { this.gamePanel2 = gamePanel2; } @Override public void actionPerformed(ActionEvent e) { gamePanel2.addShot(); } } } // a trivial GamePanel class to just show that everything is working as expected class GamePanel extends JPanel { public void moveItem(int i) { // your moveItem method will instead actually move something, a distance of i System.out.println("Move Item Method distance: " + i); } public void addShot() { // your addShot method will actually shoot System.out.println("Add Shot Method"); } }