无需发布太多代码,简而言之,我有一个行为有趣的 KeyListener
我有一个 JPanel,我像这样实现我的 KeyListener:
keyboard = new KeyBoard(); // implements KeyListener
KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
manager.addKeyEventDispatcher(new DefaultKeyEventDispatcher(keyboard));
我以前也试过这样:
theJPanel.addKeyListener(myKeyListener);
theJPanel.setFocusable(true);
theJPanel.requestFocusInWindow();
主要问题:
当问题发生时,public void keyPressed(KeyEvent e)
总是被调用,但public void keyReleased(KeyEvent e)
永远不会被调用。
当它发生时似乎是不可预测的,因为其他时候一切都按应有的方式运行。如果我等待大约 5 分钟并重新运行程序,该错误就会消失:/
编辑:(忘记发布 DefaultKeyEventDispatcher 代码)
package game.keyboard;
import java.awt.KeyEventDispatcher;
import java.awt.event.KeyEvent;
public class DefaultKeyEventDispatcher implements KeyEventDispatcher {
private KeyBoard keyboard;
public DefaultKeyEventDispatcher(KeyBoard keyboard) {
this.keyboard = keyboard;
}
@Override
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_PRESSED) {
keyboard.keyPressed(e);
} else if (e.getID() == KeyEvent.KEY_RELEASED) {
keyboard.keyReleased(e);
} else if (e.getID() == KeyEvent.KEY_TYPED) {
keyboard.keyTyped(e);
}
return false;
}
}
编辑 2. KeyBoard 类的示例
package game.keyboard;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class KeyBoard implements KeyListener {
private boolean[] keys;
private long[] keyPressedTime;
public KeyBoard() {
keys = new boolean[KeyEvent.KEY_LAST];
keyPressedTime = new long[KeyEvent.KEY_LAST];
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
keys[e.getKeyCode()] = true;
keyPressedTime[e.getKeyCode()] = System.currentTimeMillis();
}
@Override
public void keyReleased(KeyEvent e) {
keys[e.getKeyCode()] = false;
keyPressedTime[e.getKeyCode()] = -1;
}
public long keyPressedTime(int k) {
return keyPressedTime[k];
}
public boolean isKeyPressed(int k) {
return keys[k];
}
public boolean isKeyCombo(int[] k) {
boolean ret = true;
for(int i = 0;i < k.length; i++) {
ret &= keys[k[i]];
}
return ret;
}
}