java - 我遇到了 CardLayout 问题,其中一个 JPanel 没有收到键盘事件
问题描述
我只会提供代码的相关部分,因为它非常大。帮助我弄清楚为什么我从来没有在 GameBoard JPanel 上收到键盘事件。游戏代码运行得很好,直到我添加了我希望它有一个欢迎屏幕的新功能。
编辑:如果您想查看整个项目(它是一个 Eclipse 项目),这里是下载它的链接Eclipse 项目,老实说,我无法在 StackOverflow 上格式化近 1000 行代码,即使对于你。
主.java
private void initUI() throws IOException {
cardLayout = new CardLayout();
mainPanel = new JPanel(cardLayout);
welcomeMenu = new Welcome(cardLayout, mainPanel);
mainPanel.add(welcomeMenu, "welcome");
game = new GameBoard();
mainPanel.add(game, "game");
add(mainPanel);
setTitle("Pacman");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(380, 420);
setLocationRelativeTo(null);
}
这是欢迎/菜单面板(其中的某些部分)。Welcome.java(作为菜单的服务器)
@Override
public void actionPerformed(ActionEvent evt) {
if (evt.getActionCommand() == Actions.EXIT.name()) {
System.exit(0);
} else if (evt.getActionCommand() == Actions.CONFIG.name()) {
JOptionPane.showMessageDialog(null, "Not yet implemented");
} else if (evt.getActionCommand() == Actions.PLAY.name()) {
// The part that switches to game, works as expected.
cl.show(mp, "game");
}
}
GameBoard 类中有一个 KeyAdapter 类,用于监听关键事件,但是,在使用 CardLayout 添加新功能时,我无法将关键事件发送到面板,所以我的 PacMan 只是卡在一个地方打开和像鱼一样闭上嘴。
游戏板.java
private void initBoard() {
addKeyListener(new TAdapter());
setFocusable(true);
setBackground(Color.black);
initGame();
}
...
class TAdapter extends KeyAdapter {
@Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (inGame) {
if (key == KeyEvent.VK_LEFT) {
req_dx = -1;
req_dy = 0;
} else if (key == KeyEvent.VK_RIGHT) {
req_dx = 1;
req_dy = 0;
} else if (key == KeyEvent.VK_UP) {
req_dx = 0;
req_dy = -1;
} else if (key == KeyEvent.VK_DOWN) {
req_dx = 0;
req_dy = 1;
} else if (key == KeyEvent.VK_ESCAPE && timer.isRunning()) {
inGame = false;
} else if (key == KeyEvent.VK_PAUSE) {
if (timer.isRunning()) {
timer.stop();
} else {
timer.start();
}
}
} /*
* else { if (key == 's' || key == 'S') { inGame = true; initGame(); } }
*/
}
@Override
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == Event.LEFT || key == Event.RIGHT || key == Event.UP || key == Event.DOWN) {
req_dx = 0;
req_dy = 0;
}
}
}
解决方案
当我应该在GameBoard JPanel中使用Key Binding时,问题是使用Key Listener 。所以代替这个,
class TAdapter extends KeyAdapter {
@Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (inGame) {
...
} else if (key == KeyEvent.VK_UP) {
req_dx = 0;
req_dy = -1;
} else if (key == KeyEvent.VK_DOWN) {
...
}
}
}
我用这种方法替换了它(我只会演示 Arrow Up 场景),
private class UpAction extends AbstractAction {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
if (!inGame)
return;
req_dx = 0;
req_dy = -1;
}
}
...
private void setupKeyListeners() {
getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "doUp");
...
getActionMap().put("doUp", new UpAction());
...
}
而后来,
private void initBoard() {
setupListeners();
setFocusable(true);
setBackground(Color.black);
initGame();
}
推荐阅读
- apache-spark - 使用 spark sql 将字符串转换为 spark 数据框中的日期
- command - 如何使用 AT+COMMAND 解锁密码
- html - HTML5 画布(Animate CC)使用按钮从舞台上删除影片剪辑
- typescript - TypeScript 3 的通用 curry 函数
- python - 在 PyCharm 中执行部分脚本并将数据框等保存在内存中
- java - JSF 保留旧数据
- prometheus - Prometheus 查询一个时间间隔下的总体平均值
- phpmailer - PHP Mailer - 联系表格问题
- r - 当我从列表中获取列名时,dplyr summarise 不起作用?
- java - 如果我没有显式调用 ReceiverAdapter 类中的重写方法,例如 jgroups 中的 viewAccepted() 方法,如何调用它们?