我遇到了Java中KeyListener的问题,当按下字母键(例如“s”或“a”)时,我第一次正确地获得了键事件(keyPressed,keyTyped,keyReleased)但是下次我按键盘上的任意键(字母或不是键)时,我只会收到一个键发布的事件。
应该注意的是,按住箭头键不会导致键监听器停止工作,也不会按下字母键。只持有一个字母键可以阻止关键监听器在将来处理任何键,并且keyReleased事件永远不会停止工作。
我还应该注意,字母键似乎没有keyPress事件重复,而按住方向键会导致重复按下keyPress事件。
这是我用来跟踪关键状态的类。我在关键监听器事件上有println语句来尝试和调试。
我一直在努力解决这个问题,并且非常感谢你能给予的任何帮助。谢谢。
public class KeyboardInput implements KeyListener {
private static final int KEY_COUNT = 256;
private enum KeyState {
RELEASED, // Not down
PRESSED, // Down, but not the first time
ONCE // Down for the first time
}
// Current state of the keyboard
private boolean[] currentKeys = null;
// Polled keyboard state
private KeyState[] keys = null;
public KeyboardInput() {
currentKeys = new boolean[ KEY_COUNT ];
keys = new KeyState[ KEY_COUNT ];
for( int i = 0; i < KEY_COUNT; ++i ) {
keys[ i ] = KeyState.RELEASED;
}
}
public synchronized void poll() {
for( int i = 0; i < KEY_COUNT; ++i ) {
// Set the key state
if( currentKeys[ i ] ) {
// If the key is down now, but was not
// down last frame, set it to ONCE,
// otherwise, set it to PRESSED
if( keys[ i ] == KeyState.RELEASED )
keys[ i ] = KeyState.ONCE;
else
keys[ i ] = KeyState.PRESSED;
} else {
keys[ i ] = KeyState.RELEASED;
}
}
}
public boolean keyDown( int keyCode ) {
return keys[ keyCode ] == KeyState.ONCE ||
keys[ keyCode ] == KeyState.PRESSED;
}
public boolean keyDownOnce( int keyCode ) {
return keys[ keyCode ] == KeyState.ONCE;
}
public synchronized void keyPressed( KeyEvent e ) {
System.out.println("Press " + e.getKeyChar());
int keyCode = e.getKeyCode();
if( keyCode >= 0 && keyCode < KEY_COUNT ) {
currentKeys[ keyCode ] = true;
}
}
public synchronized void keyReleased( KeyEvent e ) {
System.out.println("release " + e.getKeyChar());
int keyCode = e.getKeyCode();
if( keyCode >= 0 && keyCode < KEY_COUNT ) {
currentKeys[ keyCode ] = false;
}
}
public void keyTyped( KeyEvent e ) {
System.out.println("type " + e.getKeyChar());
}
}