Reputation: 12328
Without posting too much code, in short I have a KeyListener that is behaving funny
I have a JPanel and I implement my KeyListener like this:
keyboard = new KeyBoard(); // implements KeyListener
KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
manager.addKeyEventDispatcher(new DefaultKeyEventDispatcher(keyboard));
also I have previously tried it like this:
theJPanel.addKeyListener(myKeyListener);
theJPanel.setFocusable(true);
theJPanel.requestFocusInWindow();
The main problem:
When the problem occurs, public void keyPressed(KeyEvent e)
always gets called, but public void keyReleased(KeyEvent e)
never gets called.
It seems to be unpredictable when it happens as other times everything functions as it should. The bug literally goes away if I just wait about 5 minutes and rerun the program :/
Edit: (Forgot to post the DefaultKeyEventDispatcher code)
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;
}
}
Edit 2. A sample from the KeyBoard Class
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;
}
}
Upvotes: 2
Views: 7943
Reputation: 20741
use Key handling like
textfield.addKeyListener(new KeyListener(){
@Override
public void keyTyped(KeyEvent e)
{
//Key Type Action
//example
int code = e.getKeyCode();
switch(code)
{
case KeyEvent.VK_UP:
{
JOptionPane.showMessageDialog(rootPane,"UP Key pressed");
break;
}
case KeyEvent.VK_DOWN:
{
JOptionPane.showMessageDialog(rootPane,"DOWN Key pressed");
break;
}
case KeyEvent.VK_LEFT:
{
JOptionPane.showMessageDialog(rootPane,"LEFT Key pressed");
break;
}
case KeyEvent.VK_RIGHT:
{
JOptionPane.showMessageDialog(rootPane,"RIGHT Key pressed");
break;
}
}
}
@Override
public void keyPressed(KeyEvent e) {
// key pressed action
}
@Override
public void keyReleased(KeyEvent e) {
// key released action
}
});
Upvotes: 0
Reputation: 347194
This...
keyboard = new KeyBoard(); // implements KeyListener
KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
manager.addKeyEventDispatcher(new DefaultKeyEventDispatcher(keyboard));
Is not the way to register a KeyListener
. This will allow you to see ALL the keys been processed by the application. KeyEventDispatcher
does not have keyPressed
or keyReleased
methods, only dispatchKeyEvent
.
There is no such class as DefaultKeyEventDispatcher
in the JDK so you must be using a customized version, meaning, we will have no idea about what the problem actually is, because we can neither replicate it or study it.
Without knowing what it is you are trying to achieve, it's impossible to provide accurate guidance, but you might like to start with How to Write a Key Listener
Upvotes: 4