Class KeyStrokeManager

java.lang.Object
ca.corbett.extras.io.KeyStrokeManager

public class KeyStrokeManager extends Object
This class allows very easy registration of keyboard shortcuts for a given Window. Shortcuts can be specified in string format (for example: "shift+F1" or "Ctrl+O") or in KeyStroke format. Actions can be registered to respond to those shortcuts, and all associated Actions will be executed when the relevant shortcut is pressed. Multiple Actions can be registered for the same shortcut, in which case all associated actions will be triggered when the shortcut is pressed. The same Action can be registered multiple times for different shortcuts, in case you want to allow multiple ways of launching the same action.

Usage Example:

     // Create a KeyStrokeManager for your main window:
     KeyStrokeManager ksm = new KeyStrokeManager(mainWindow);

     // Add some basic shortcuts:
     ksm.registerHandler("ctrl+O", openFileAction);
     ksm.registerHandler("ctrl+S", saveFileAction);
     ksm.registerHandler("ctrl+A", aboutAction);

     // That's literally all there is to it!
     // As long as your main window is active,
     // those shortcuts will trigger the associated actions.

     // You can temporarily disable the manager if needed:
     ksm.setEnabled(false); // disables shortcut processing
     ksm.setEnabled(true);  // re-enables shortcut processing

     // And you can reassign shortcuts as needed:
     ksm.reassignHandler(saveFileAction, "ctrl+shift+S");
 

You should also look at the KeyStrokeProperty and KeyStrokeField classes to allow easy user customization of your shortcuts! With KeyStrokeProperty, you can easily add these to your application settings, where they will be automatically persisted between application sessions.

Since:
swing-extras 2.7
Author:
scorbo2
  • Constructor Details

    • KeyStrokeManager

      public KeyStrokeManager(Window window)
      Creates a KeyStrokeManager for the given window. This KeyStrokeManager is immediately installed into the given window and enabled. You can use setEnabled(false) to temporarily disable it if needed.
      Parameters:
      window - the window that must be active to receive shortcuts.
  • Method Details

    • dispose

      public void dispose()
      Disposes this KeyStrokeManager, removing its key event dispatcher from the KeyboardFocusManager and clearing all registered key bindings. If your KeyStrokeManager is attached to your application's main window, you don't need to invoke this method. It's intended more for temporary windows or dialogs that may be created and destroyed multiple times during the application's lifetime.

      Can safely be called multiple times; subsequent calls after the first will have no effect.

    • addWindow

      public void addWindow(Window window)
      Adds a new window to this KeyStrokeManager
    • removeWindow

      public void removeWindow(Window window)
      Removes an specified window from this KeyStrokeManager
    • isEnabled

      public boolean isEnabled()
      Reports whether this KeyStrokeManager is currently enabled.
    • isWarnIfMultipleHandlers

      public boolean isWarnIfMultipleHandlers()
      Returns whether this KeyStrokeManager will warn when multiple handlers are registered for the same keystroke.
      Returns:
      true if warnings are enabled, false otherwise
    • setWarnIfMultipleHandlers

      public KeyStrokeManager setWarnIfMultipleHandlers(boolean warnIfMultipleHandlers)
      Sets whether this KeyStrokeManager should warn when multiple handlers are registered for the same keystroke. When enabled, a warning will be logged if registerHandler is called for a keystroke that already has at least one handler registered.
      Parameters:
      warnIfMultipleHandlers - true to enable warnings, false to disable
      Returns:
      this manager, for fluent-style method chaining
    • setEnabled

      public KeyStrokeManager setEnabled(boolean enabled)
      Can be used to enable or disable this KeyStrokeManager. When disabled, no keyboard shortcuts will be processed. This does not unregister any assigned actions! It simply means those actions will not be invoked until we are re-enabled.
    • suspend

      public void suspend()
      Shorthand for setEnabled(false).
    • resume

      public void resume()
      Shorthand for setEnabled(true).
    • isKeyStrokeValid

      public boolean isKeyStrokeValid(String shortcut)
      Use this method to check if a given shortcut string is valid.
      Parameters:
      shortcut - Any candidate keyboard shortcut string. Example: "ctrl+P"
      Returns:
      true if the shortcut is valid, false otherwise
    • getKeyStrokesForAction

      public List<KeyStroke> getKeyStrokesForAction(Action action)
      Returns the KeyStroke(s) currently assigned to the given Action, or an empty list if the given Action is not found.
      Parameters:
      action - The action to search for.
      Returns:
      A List of KeyStrokes assigned to the action. Empty if none found.
    • getActionsForKeyStroke

      public List<Action> getActionsForKeyStroke(KeyStroke keyStroke)
      Returns the Action(s) currently assigned to the given KeyStroke, or an empty list if the KeyStroke is not found.
      Parameters:
      keyStroke - The KeyStroke to search for.
      Returns:
      A List of Actions assigned to the KeyStroke. Empty if none found.
    • getActionsForKeyStroke

      public List<Action> getActionsForKeyStroke(String keyStroke)
      Returns the Action(s) currently assigned to the given KeyStroke, or an empty list if the KeyStroke is not found.
      Parameters:
      keyStroke - The String version of the KeyStroke to search for.
      Returns:
      A List of Actions assigned to the KeyStroke. Empty if none found.
      Throws:
      IllegalArgumentException - if the given keyStroke string is invalid
    • clear

      public KeyStrokeManager clear()
      Removes all registered keyboard shortcuts and their associated actions. This will also clear the accelerator keys from all associated Actions.
    • isEmpty

      public boolean isEmpty()
      Reports whether any keyboard shortcuts are currently registered.
    • isRegistered

      public boolean isRegistered(Action action)
      Reports whether an action is already registered.
      Parameters:
      action - The action to search for.
      Returns:
      true if the action has at least one registered shortcut, false otherwise
    • isAvailable

      public boolean isAvailable(KeyStroke keyStroke)
      Shorthand for !hasHandlers(keyStroke)
    • isAvailable

      public boolean isAvailable(String keyStroke)
      Shorthand for !hasHandlers(keyStroke)
    • hasHandlers

      public boolean hasHandlers(KeyStroke keyStroke)
      Reports whether any actions are registered for the given KeyStroke.
      Parameters:
      keyStroke - The KeyStroke to check.
      Returns:
      true if at least one action is registered for the KeyStroke, false otherwise
    • hasHandlers

      public boolean hasHandlers(String keyStroke)
      Reports whether any actions are registered for the given KeyStroke.
      Parameters:
      keyStroke - The String version of the KeyStroke to check.
      Returns:
      true if at least one action is registered for the KeyStroke, false otherwise
      Throws:
      IllegalArgumentException - If the given keyStroke string is invalid
    • checkForMultipleHandlers

      public List<KeyStroke> checkForMultipleHandlers()
      Returns a list of all keystrokes that have more than one handler registered. This can be used to programmatically detect and handle duplicate handler assignments. An empty list is returned if no keystrokes have multiple handlers.
      Returns:
      A List of KeyStrokes that have more than one handler registered. Empty if none found.
    • registerHandler

      public KeyStrokeManager registerHandler(String keyStroke, Action action)
      Registers a keyboard shortcut with an action. Accepts shortcuts in the format: "ctrl+P", "alt+F4", "ctrl+shift+S", etc. If the given shortcut already has an action registered, the new action will be added to the list of actions to be executed when that shortcut is pressed. If the given shortcut is invalid, an IllegalArgumentException will be thrown.

      IllegalArgumentException will be thrown if any parameter is null.

      Parameters:
      keyStroke - the String version of the KeyStroke to register
      action - the action to execute when the shortcut is pressed
      Returns:
      this manager, for fluent-style method chaining
      Throws:
      IllegalArgumentException - if the given shortcut string is invalid
    • registerHandler

      public KeyStrokeManager registerHandler(String keyStroke, KeyAction action)
      A convenience method to allow registration of simple KeyActions without having to create a whole Action object. With lambdas, this can reduce the adding of a handler to a single line, in the case where your application doesn't have a ready-made Action to use. For example:
           ksm.registerHandler("Esc", e -> dispose());
       

      This is as opposed to the old way, forcing callers to create an Action or AbstractAction:

           ksm.registerHandler("Esc", new AbstractAction() {
               @Override
               public void actionPerformed(ActionEvent e) {
                   dispose(); // That's a lot of boilerplate!
               }
           });
       

      The drawback of this approach is that you will be unable to invoke unregisterHandler() with your KeyAction to remove your handler later, because we wrapped it in an AbstractAction that is not exposed. However, you can use the unregisterHandler() overload that accepts a keystroke to remove all handlers for that keystroke, or you can call clear() to remove all handlers if needed.

      Parameters:
      keyStroke - the String version of the KeyStroke to register
      action - the KeyAction to execute when the shortcut is pressed
      Returns:
      this manager, for fluent-style method chaining
    • registerHandler

      public KeyStrokeManager registerHandler(KeyStroke keyStroke, Action action)
      Registers a keyboard shortcut with an action. Accepts shortcuts in the format: "ctrl+P", "alt+F4", "ctrl+shift+S", etc. If the given shortcut already has an action registered, the new action will be added to the list of actions to be executed when that shortcut is pressed. If the given shortcut is invalid, an IllegalArgumentException will be thrown.

      IllegalArgumentException will be thrown if any parameter is null.

      Parameters:
      keyStroke - the KeyStroke to register
      action - the action to execute when the keyStroke is pressed
      Returns:
      this manager, for fluent-style method chaining
    • registerHandler

      public KeyStrokeManager registerHandler(KeyStroke keyStroke, KeyAction action)
      A convenience method to allow registration of simple KeyActions without having to create a whole Action object. With lambdas, this can reduce the adding of a handler to a single line, in the case where your application doesn't have a ready-made Action to use. For example:
           ksm.registerHandler("Esc", e -> dispose());
       

      This is as opposed to the old way, forcing callers to create an Action or AbstractAction:

           ksm.registerHandler("Esc", new AbstractAction() {
               @Override
               public void actionPerformed(ActionEvent e) {
                   dispose(); // That's a lot of boilerplate!
               }
           });
       

      The drawback of this approach is that you will be unable to invoke unregisterHandler() with your KeyAction to remove your handler later, because we wrapped it in an AbstractAction that is not exposed. However, you can use the unregisterHandler() overload that accepts a keystroke to remove all handlers for that keystroke, or you can call clear() to remove all handlers if needed.

      Parameters:
      keyStroke - the KeyStroke to register
      action - the KeyAction to execute when the shortcut is pressed
      Returns:
      this manager, for fluent-style method chaining
    • unregisterHandler

      public KeyStrokeManager unregisterHandler(Action action)
      Unregisters the given action, removing its keyboard shortcut. If the named action was not found, this method does nothing.
      Parameters:
      action - The action to unregister.
      Returns:
      this manager, for fluent-style method chaining
    • unregisterHandler

      public KeyStrokeManager unregisterHandler(String keyStroke)
      Unregisters any handlers associated with the given KeyStroke, removing their keyboard shortcuts. If there were no handlers for the given KeyStroke, this method does nothing.
      Parameters:
      keyStroke - The KeyStroke to unregister.
      Returns:
      this manager, for fluent-style method chaining
    • unregisterHandler

      public KeyStrokeManager unregisterHandler(KeyStroke keyStroke)
      Unregisters any handlers associated with the given KeyStroke, removing their keyboard shortcuts. If there were no handlers for the given KeyStroke, this method does nothing.
      Parameters:
      keyStroke - The KeyStroke to unregister.
      Returns:
      this manager, for fluent-style method chaining
      Throws:
      IllegalArgumentException - if the given keyStroke is null
    • reassignHandler

      public KeyStrokeManager reassignHandler(Action action, String newKeyStroke)
      If the given action is registered, reassigns its keyboard shortcut to the newKeyStroke. If the action is not found, this method does nothing. If this action was previously registered to multiple keystrokes, the previous assignments are removed. If that is not the intention, then consider calling registerHandler() instead to add a new shortcut without removing existing ones.

      This is therefore equivalent to unregisterHandler(action) followed by registerHandler(newShortcut, action).

      Parameters:
      action - The action to reassign.
      newKeyStroke - The new keystroke in string format (e.g., "ctrl+P", "F5"). Must be valid!
      Returns:
      this manager, for fluent-style method chaining
      Throws:
      IllegalArgumentException - if the given newShortcut string is invalid
    • reassignHandler

      public KeyStrokeManager reassignHandler(Action action, KeyStroke newKeyStroke)
      If the given action is registered, reassigns its keyboard shortcut to the newKeyStroke. If the action is not found, this method does nothing. If this action was previously registered to multiple shortcuts, the previous assignments are removed. If that is not the intention, then consider calling registerHandler() instead to add a new shortcut without removing existing ones.

      This is therefore equivalent to unregisterHandler(action) followed by registerHandler(newShortcut, action).

      Parameters:
      action - The action to reassign.
      newKeyStroke - The new keyboard shortcut string (e.g., "ctrl+P", "F5"). Must be valid!
      Returns:
      this manager, for fluent-style method chaining
    • parseKeyStroke

      public static KeyStroke parseKeyStroke(String shortcut)
      Parses a string representation of a keyboard shortcut into a KeyStroke. Supports formats like: "ctrl+P", "alt+F4", "ctrl+shift+S", "F5", etc.
      Parameters:
      shortcut - the shortcut string
      Returns:
      the KeyStroke, or null if invalid
    • getKeyCode

      protected static int getKeyCode(String keyName)
      Gets the key code for a given key name.
    • keyStrokeToString

      public static String keyStrokeToString(KeyStroke keyStroke)
      Converts a KeyStroke to its string representation. Produces formats like: "Ctrl+P", "Alt+F4", "Ctrl+Shift+S", "F5", etc.
      Parameters:
      keyStroke - the KeyStroke to convert
      Returns:
      the string representation, or null if keyStroke is null
    • getKeyName

      protected static String getKeyName(int keyCode)
      Gets the string name for a given key code.