Java Global JFrame Key Listener

Do you know what happens when you add a KeyListener to JFrame to capture global keystrokes? Nothing.

Much to my frustration, I discovered recently that KeyEvents are not bubbled up through the JComponent hierarchy by default. The only component that consumes the event is the one currently focused. This means that As soon as you add children to the JFrame, the focus is stolen from the JFrame which can no longer  capture “global” key events.

Fortunately, there is an easy fix that I will show you. It involves providing a custom KeyEventDispatcher to the keyboard manager, catching the event before it reaches any of the JComponents.


//Hijack the keyboard manager
KeyboardFocusManager manager =
         KeyboardFocusManager.getCurrentKeyboardFocusManager();
manager.addKeyEventDispatcher( new KeyDispatcher() );

//Custom dispatcher
class KeyDispatcher implements KeyEventDispatcher {
    public boolean dispatchKeyEvent(KeyEvent e) {
        if(e.getID() == KeyEvent.KEY_TYPED)
            System.out.println( "typed" + e.getCharCode() )

        //Allow the event to be redispatched
        return false;
    }
}

A thought, you could pass your existing KeyListener class to the KeyEventDispatcher and have the dispatcher call the appropriate event based on the event ID (KEY_TYPED, KEY_PRESSED, KEY_RELEASED)