我这么问是因为我希望当用户点击 enter 时调用我的 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
最佳答案
- 您的问题可能是焦点问题 - GamePanel 中的某些内容可能会窃取焦点,这是 KeyListener 的非常常见问题。
- 一般建议:对于此类需求,倾向于使用键绑定(bind),而不是 KeyListener。
有用的链接:
- Swing Resources
- 请检查我对 StackOverflow 问题的回答中的第二个示例程序 here .
- Overall Swing Tutorials
- Key Bindings
- Swing Timer
- Concurrency in 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");
}
}
关于java - 我是否正确构建了这个关键监听器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23254166/