I would like to listen for key combinations such as Control+S without adding key listeners to each component in my Swing application. How can I achieve this?
3 Answers
It is possible.
KeyboardFocusManager.getCurrentKeyboardFocusManager()
.addKeyEventDispatcher(new KeyEventDispatcher() {
@Override
public boolean dispatchKeyEvent(KeyEvent e) {
System.out.println("Got key event!");
return false;
}
});
That will grab all key events. Returning false allows the keyboard focus manager to resume normal key event dispatching to the various components.
If you want to catch key combos, you can keep a set of "pressed keys." Whenever a key is pressed, add it to the set and check what keys are already in the set. When a key is released, remove it from the set.

- 12,146
- 5
- 42
- 44
-
I think freshwire is still going to have to put listeners in each of the components though. Then as the `KeyEventDispatcher` sends out events, the components can listen for certain events and do their component-specific action. This actually sounds like it will be extra work. – jbranchaud Mar 17 '11 at 20:54
-
@Treebranch he just wants to catch a global ctr+s... This will work fine. – Matt Wonlaw Mar 17 '11 at 23:57
-
Okay, I agree. I was assuming freshwire would then want to push the events to the component level, but I suppose that isn't necessarily the case. – jbranchaud Mar 18 '11 at 02:11
-
KeyboardFocusManager in fact grabs all key events, whereas AWTEventListener doesn't react on all events. If you need to listen zu key event like F11 to toggel to fullscreen, KeyboardFocusManager is definitely better. AWTEventListener seems to only listen zu Component events. But when no component has focus, AWTEventListener doesn't get notified of key events. – haferblues Jan 14 '13 at 10:54
-
4This code returns all events for each key press i.e. for one key press, a KEY_PRESSED, KEY_RELEASED and a KEY_TYPED event will occur. To filter further to give one event, it is possible to add code if (KeyEvent.KEY_PRESSED == e.getID()) { ... } to filter for KEY_PRESSED events for example. – John Deverall Dec 10 '14 at 20:44
-
@haferblues I get the same behavior from KeyboardFocusManager, if no component has focus, no events will be delivered. – Anders Lindén May 29 '16 at 19:19
Very simple my friend: All you have to do is create a class KeyEventDispatcher and register to KeyboardFocusManager C.1
Then parse and extract state and key info see: C.2 Strangely enough though, you have to get the KEY STATE via ThatEvent.getID();
SEEMS LIKE A MISSNOMER TO ME.
/////////////////////////////////////////////////////////////////////////////////////////// C.1)
KeyDispatcher ThisKeyDispatcher = new KeyDispatcher();
KeyboardFocusManager ThisKbFocusMngr = KeyboardFocusManager
. getCurrentKeyboardFocusManager();
ThisKbFocusMngr . addKeyEventDispatcher(ThisKeyDispatcher);
return ThisKeyDispatcher;
///////////////////////////////////////////////////////////////////////////////////////////
C.2
public static class KeyDispatcher implements KeyEventDispatcher {
public boolean dispatchKeyEvent(final KeyEvent ThatEvent) {
KeyboardFocusManager ThisKbFocusMngr = null;
Component ThisComponent = null;
Container ThisRoot = null;
Window ThisWindow = null;
int ThisKeyStateEvent = 0;
try {
ThisKbFocusMngr = KeyboardFocusManager . getCurrentKeyboardFocusManager();
ThisComponent = ThisKbFocusMngr . getFocusOwner();
ThisRoot = ThisKbFocusMngr . getCurrentFocusCycleRoot();
ThisWindow = ThisKbFocusMngr . getActiveWindow();
ThisKeyStateEvent = ThatEvent.getID(); // i.e. KeyEvent.KEY_RELEASED
if(false == ThatEvent.isConsumed()) {
boolean RetBool = false;
if((KeyEvent.VK_BACK == ThatEvent.getKeyCode())) {
RetBool = true;
} else {
RetBool = m_CallSomeoneEvent(ThatEvent);
}
if(RetBool) {
ThatEvent.consume();
return true;
}
}
}
catch( Throwable e ) {
LogThis(". ", e);
}
return false;
}
}
-
12Thanks for the answer but I already accepted an answer over a year ago. How does your answer differ from the accepted answer? It has a lot of extra code that seems to have no purpose in the context of my question. – diolemo Jun 04 '12 at 20:58
I don't think there is a way to add a "global" key listener like you are wanting to do. This forum post with a similar question backs me up. You are just going to have to add them to each component. This should only need to be done once though, so I guess you can just get it over with and move on.

- 5,909
- 9
- 45
- 70
-
1*I don't think there is a way to add a "global" key listener like you are wanting to do* It's just wrong `Toolkit.addAWTEventListener` and you can listen anything, besides it was mentioned you can add event to addKeyEventDispatcher and you can add accel keys and so on – bestsss Mar 17 '11 at 20:46
-
@bestsss I think you misunderstood. I am not talking about the type of events that are being listened to, but the component(s) over which the listener works. – jbranchaud Mar 17 '11 at 20:50
-
1