So I have been working on a program in java for a while now, but I have yet to solve a annoying problem, the JFrame seems to stop listen to the keyboard, I have tried with KeyListener and KeyEventDispatcher. But not matter which one I use, it still happens. I need to program to listen to the keyboard without fail, no matter where the focus are, well it’s okay if it doesn’t when the program is minimized.
I used to have a Keyboard class which implements KeyListener, like in example below:
public class Keyboard implements KeyListener{
private boolean[] keys = new boolean[256];
public boolean up, down, left, right, esc;
public void update(){
up = keys[KeyEvent.VK_UP] || keys[KeyEvent.VK_W];
down = keys[KeyEvent.VK_DOWN] || keys[KeyEvent.VK_S];
left = keys[KeyEvent.VK_LEFT] || keys[KeyEvent.VK_A];
right = keys[KeyEvent.VK_RIGHT] || keys[KeyEvent.VK_D];
esc = keys[KeyEvent.VK_ESCAPE];
}
public void keyPressed(KeyEvent e) {
keys[e.getKeyCode()] = true;
}
public void keyReleased(KeyEvent e) {
keys[e.getKeyCode()] = false;
}
public void keyTyped(KeyEvent e) {
}
}
And in the Main class I had an istance for Keyboard, attributed as parameter for function “addKeyListener(MY KEYBOARD ISTANCE)”. And the update function from Keyboard updated in the main update function. I hope that helps you.
Sadly that doesn’t work for me.
Here is my code I made, it’s my own little Listener, and it works fine for a while, and then it suddenly stops working.
private final KeyEventDispatcher toScanner = new KeyEventDispatcher(){
@Override
public boolean dispatchKeyEvent(KeyEvent event){
if(event.getID() != KeyEvent.KEY_RELEASED)
return false;
if(event.getKeyCode() == 10){
if(System.currentTimeMillis() - scanTime < 1000){
for(ScanListener l : listeners)
l.onScanComplete(createScanEvent(null));
scan = null;
}
event.consume();
return true;
}
if(scan == null){
scan = new StringBuilder();
scanTime = System.currentTimeMillis();
for(ScanListener l : listeners)
l.onScanBeing(createScanEvent(event.getKeyChar()));
}
if(scan != null){
for(ScanListener l : listeners)
l.onScanInProgress(createScanEvent(event.getKeyChar()));
scan.append(event.getKeyChar());
}
event.consume();
return false;
}
};
The scannerEngine.getKeyEventDispatcher returns toScanner.
KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(scannerEngine.getKeyEventDispatcher());
You said that your Listener no longer listen to your keyboard, by function
removeKeyEventDispatcher()
you remove the listner, so in your main function, maybe in constructor, you should have
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(scannerEngine.getKeyEventDispatcher());
, and maybe wherever you want to stop the listener, you will use what you write,
KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(scannerEngine.getKeyEventDispatcher());
I can’t believe that I missed that one “addKeyEventDispatcher” was a “removeKeyEventDispatcher”… Now I just feel dumb.
Java can only listen to window events, when they are dispatched to window itself. If the window you have your key listener is not focused, keyboard input will not be received.
If you want to get input events from the keyboard itself, here is a very simple and awesome library I have used in one of my past projects.