KeyListener 随机停止工作。键绑定?
Posted
技术标签:
【中文标题】KeyListener 随机停止工作。键绑定?【英文标题】:KeyListener randomly stops working. KeyBindings? 【发布时间】:2017-03-15 03:40:51 【问题描述】:我正在使用 RealTutsGML 的教程制作游戏,所以如果你看过他 2013 年的一些旧视频,你会看到这段代码的大纲来自哪里。
(顺便说一下,我对 Java 并不陌生,但我对 AWT 和 Swing 以及所有这些都相当陌生,因为我曾经/现在有时会编写 Minecraft Bukkit/Spigot 插件。我可以理解相当多的Java 常规语言/语法,但 AWT 和 Swing...)
无论如何,我正在使用 KeyAdapter 来控制按键。但是,它一开始可以工作,然后随机停止工作。我调试过了,好像不是游戏中的对象,是KeyAdapter。我已经查找了一些其他解决方案,人们说它失去了焦点或其他东西,我应该使用 KeyBindings 代替。这很奇怪,因为 KeyListener RANDOMLY 停止为我工作。
无论如何,这是我正在使用的代码:
Handler handler;
public KeyInput(Handler handler)
this.handler = handler;
public void keyPressed(KeyEvent e)
int key = e.getKeyCode();
for (int i = 0; i < handler.object.size(); i++)
GameObject tempObject = handler.object.get(i);
if (tempObject.getId() == ObjectId.Player)
if (key == KeyEvent.VK_SPACE && !tempObject.isJumping())
tempObject.setJumping(true);
tempObject.setVelY(-10);
if (key == KeyEvent.VK_Y)
tempObject.setY(100);
if (key == KeyEvent.VK_A)
System.out.println("Pressed A");
tempObject.setVelX(-5);
if (key == KeyEvent.VK_D)
System.out.println("Pressed D");
tempObject.setVelX(5);
public void keyReleased(KeyEvent e)
int key = e.getKeyCode();
for (int i = 0; i < handler.object.size(); i++)
GameObject tempObject = handler.object.get(i);
if (tempObject.getId() == ObjectId.Player)
if (key == KeyEvent.VK_D)
for (int velX = (int) tempObject.getVelX(); velX >= 0; velX--)
tempObject.setVelX(velX);
if (key == KeyEvent.VK_A)
for (int velX = (int) tempObject.getVelX(); velX <= 0; velX++)
tempObject.setVelX(velX);
如您所见,我正在使用 KeyAdapter 来执行此操作。这是我在主类中的初始化方法:
private void init()
WIDTH = getWidth();
HEIGHT = getHeight();
handler = new Handler();
handler.addObject(new Player(100, 100, handler, ObjectId.Player));
handler.createTestLevel();
this.addKeyListener(new KeyInput(handler));
init 方法在 "this.requestFocusInWindow()" 之前被调用
我查阅了一些相关信息,发现 KeyBindings 可以解决其他人的问题。但是,我认为您必须向 JComponents 添加键绑定,而我不知道如何在游戏中获得其中之一。 new JComponent() 不起作用,我的 JFrame 正在添加我的主类(我相信它充当组件,而不是 JComponent)。
如果有人可以提供帮助,那就太好了!谢谢!
编辑#1:
我切换到 KeyBindings!这是 KeyInput 类:
Handler handler;
public JComponent component;
public KeyInput(Handler handler, JComponent component)
this.handler = handler;
this.component = component;
register();
public void register()
Actions actions = new Actions();
component.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "pressSpace");
component.getActionMap().put("pressSpace", actions.pressSpace());
component.getInputMap().put(KeyStroke.getKeyStroke("A"), "pressLeft");
component.getActionMap().put("pressLeft", actions.pressLeft());
component.getInputMap().put(KeyStroke.getKeyStroke("released A"), "releaseLeft");
component.getActionMap().put("releaseLeft", actions.releaseXMovement());
component.getInputMap().put(KeyStroke.getKeyStroke("D"), "pressRight");
component.getActionMap().put("pressRight", actions.pressRight());
component.getInputMap().put(KeyStroke.getKeyStroke("released D"), "releaseRight");
component.getActionMap().put("releaseRight", actions.releaseXMovement());
public JComponent finish()
return component;
public class Actions
public Actions()
public Action pressRight()
Action action = new AbstractAction()
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e)
for (int i = 0; i < handler.object.size(); i++)
GameObject temp = handler.object.get(i);
if (temp.getId() == ObjectId.Player)
temp.setVelX(5);
System.out.println("pressed right debug");
;
return action;
public Action releaseXMovement()
Action action = new AbstractAction()
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e)
for (int i = 0; i < handler.object.size(); i++)
GameObject temp = handler.object.get(i);
if (temp.getId() == ObjectId.Player)
temp.setVelX(0);
;
return action;
public Action pressLeft()
Action action = new AbstractAction()
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e)
for (int i = 0; i < handler.object.size(); i++)
GameObject temp = handler.object.get(i);
if (temp.getId() == ObjectId.Player)
temp.setVelX(-5);
;
return action;
public Action pressSpace()
Action action = new AbstractAction()
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e)
for (int i = 0; i < handler.object.size(); i++)
GameObject temp = handler.object.get(i);
if (temp.getId() == ObjectId.Player)
if (!temp.isJumping())
temp.setJumping(true);
temp.setVelY(-10);
;
return action;
但是,我仍然遇到同样的冻结问题。调试消息不会被发送,这意味着它与我的 setVel 方法没有任何关系。我不知道为什么监听器停止工作...... (起初它可以工作,但随着我不断按键,它最终会停止)。
这是我获得 JComponent 的方式:
JComponent comp = (JComponent) frame.getContentPane();
KeyInput input = new KeyInput(handler, comp);
frame.add(input.finish());
【问题讨论】:
如果您需要更具体的帮助,那么根据我的回答,您需要创建并发布有效的minimal reproducible example 作为对当前问题的编辑。与往常一样,代码应该以代码格式的文本而不是链接形式发布。 查看编辑以回答您问题的底部。同样,MCVE 的帮助是不可估量的。 @HovercraftFullOfEels 不在链接中是什么意思?我的帖子中没有任何链接。 【参考方案1】:它不会“随机”停止工作。相反,它可能(如果没有您的有效MCVE,我们无法确定)在收听的组件不再具有焦点时停止工作。选择是创建一个 kludge 以强制关注组件(坏)或使用键绑定(好)。
关于:
我查阅了一些相关信息,发现 KeyBindings 可以解决其他人的问题。但是,我认为您必须向 JComponents 添加键绑定,而我不知道如何在游戏中获得其中之一。 new JComponent() 不起作用,我的 JFrame 正在添加我的主类(我相信它充当组件,而不是 JComponent)。
您的 GUI 充满了 JComponents,从 JFrame 的 contentPane 开始,一直到您要编程的任何其他 GUI 组件——请记住,大多数 所有 Swing 组件都从 JComponent 扩展而来,并且这些是添加绑定的有效组件。您可能会将其添加到 GUI 的主 JPanel 或 JComponent 中。
【讨论】:
好的!我使用 KeyBindings 并编辑了上面的帖子以显示我所做的更改。但是,我仍然遇到冻结问题。 @Blockhead7360:我无法编译和运行您发布的代码。如果您仍然遇到问题,请考虑创建并发布有效的minimal reproducible example。这是一个 small 可编译和可运行的程序,在您的问题中以代码格式文本(不在链接中)的形式发布,向我们展示了您的问题。祝你好运!以上是关于KeyListener 随机停止工作。键绑定?的主要内容,如果未能解决你的问题,请参考以下文章