javaswingkey-eventsjtextcomponent

Swing: Global keyboard shorcuts


So Swing text components provide a way to ahve global keyboard shorcuts. JTextComponent.getKeyMap(JTextComponent.DEFAULT_KEYMAP) provides a way to modify the global, default keymap inherited by all Swing text components. But do other components have a way to set key bindings globally?

The reason I'm asking this is because at work we have a legacy Swing application that we're working on, and there are behaviors that are pretty standard to other applications that we just don't have in it. Things like pressing escape to close a dialog, for example. While I could go through the entire codebase, find every instance of a dialog, and add this behavior, it would be nice to be able to add key bindings globally to components.

Ideally, this global behavior would be able to be applied to specific classes (ie, some to JDialog, some to JFrame, etc), but if it has to be 100% global that's fine.

Any ideas?


Solution

  • Each Swing component has an InputMap that is shared by all components of the same type. Changes to this InputMap will affect all components.

    For example all JTextAreas share a focusInputMap. To disable the ability to select all the text using Control-A you can use code like:

    InputMap im = (InputMap) UIManager.get("TextArea.focusInputMap");
    KeyStroke keyStroke = KeyStroke.getKeyStroke("control A");
    im.put(keyStroke, "none"); 
    

    You can check out UIManager Defaults to see which InputMaps are implemented for a given Swing component.

    Frame and Dialog don't appear in the UIManager so I don't know if InputMaps are supported for them or not. You can try adding "Dialog.ancestorInputMap" and creating your own bindings to see if this works.

    Otherwise you can try using "RootPane.ancestorInputMap" although I would guess this InputMap would be shared by frames and dialogs.

    You can also check out Escape Key and Dialog for an Action that is bound to the InputMap of a JRootPane.