Skip to content

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, you can work around this by providing a custom KeyEventDispatcher to the keyboard focus manager, catching the event before it reaches any of the JComponents.

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

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

// now we hijack the keyboard manager
KeyboardFocusManager manager =
  KeyboardFocusManager.getCurrentKeyboardFocusManager();
manager.addKeyEventDispatcher( new KeyDispatcher() );

A thought, you could pass your existing KeyListener class to the KeyEventDispatcher and have the dispatcher call the appropriate event based on criteria from the KeyEvent data.