Binding hotkeys to actions

The Esc key in HelloAcorus is an example of a hotkey.

Hotkeys in Acorus include not only keyboard keys but also the buttons on mice, joysticks, and game controllers. Each hotkey is identified in 3 ways:

  • by its "universal code" (int value)

  • by its US name (String value), and

  • by its localized name (also a String).

On systems with "US" QWERTY keyboards, the US name and the localized name are identical.

TestHotkeys

TestHotkeys is a test application that displays a continuously updated list active hotkeys. It is a useful tool for identifying hotkeys. Please run the app, press some keyboard keys, click some mouse buttons, and see what information appears!

TestHotkeys overrides the default binding of Esc to "SIMPLEAPP_Exit". In order to terminate the application, you’ll have to use some mechanism provided by your window manager: typically a window decoration ("X" button or red disc) or a combination such as Alt+F4.

Binding hotkeys

To execute some code each time a hotkey is pressed or released, the hotkey should be bound to an action.

There are several ways to bind hotkeys to actions. The usual way is to invoke inputMode.bind(actionName, code1, code2, …​)

HelloBind

HelloBind is an example application that binds 12 hotkeys to 4 custom actions. Those actions cause colored squares to appear in (or disappear from) the display.

When multiple hotkeys are bound to a single action (as here), the help node separates the alternatives with slashes.

To conserve screen area in help nodes, the buildNode() method often abbreviates hotkey names. For example, the HelloBind help node indicates "num4", which is an abbreviated form of "numpad 4", the name of 4 on the numeric keypad.

In Acorus, input bindings are grouped into input modes. In HelloBind, the 12 custom bindings are added to an (automatically created) mode called the default input mode.

An input mode’s bindings don’t become effective (mapped) until the mode is activated (enabled). Acorus activates the default input mode during initialization, just after invoking the moreDefaultBindings() callback. That makes moreDefaultBindings() the ideal place to customize the default input mode.

public void moreDefaultBindings() {
    InputMode dim = getDefaultInputMode();
    dim.bind("toggle blue",
            KeyInput.KEY_F1, KeyInput.KEY_1, KeyInput.KEY_NUMPAD1);
    dim.bind("toggle green",
            KeyInput.KEY_F2, KeyInput.KEY_2, KeyInput.KEY_NUMPAD2);
    dim.bind("toggle red",
            KeyInput.KEY_F3, KeyInput.KEY_3, KeyInput.KEY_NUMPAD3);
    dim.bind("toggle white",
            KeyInput.KEY_F4, KeyInput.KEY_4, KeyInput.KEY_NUMPAD4);
}

An action handler is simply a method with the onAction(String, boolean, float) signature. This signature is defined by JMonkeyEngine’s ActionListener interface. All Acorus applications and input modes implement that interface.

When a bound hotkey is pressed, Acorus first invokes the action handler of the active input mode. The mode may handle the action, ignore it, or forward it to the application.

In HelloBind, the action handler of the (default) input mode doesn’t handle "toggle" actions. It forwards them to the application’s action handler, which includes the following:

public void onAction(String actionString, boolean ongoing, float tpf) {
    if (ongoing) {
        switch (actionString) {
            case "toggle blue":
                toggle(blueSquare);
                return;
            case "toggle green":
                toggle(greenSquare);
                return;
            case "toggle red":
                toggle(redSquare);
                return;
            case "toggle white":
                toggle(whiteSquare);
                return;

Summary

  • Hotkeys include keyboard keys, mouse buttons, and joystick buttons.

  • Each hotkey has both a US name and a localized name; they might be identical.

  • To make something happen each time a hotkey is pressed, bind it to an action.

  • You can bind multiple hotkeys to the same action.

  • Bindings are grouped into input modes.

  • An input mode’s bindings take effect when the mode is activated.

  • During initialization, Acorus creates a default input mode and activates it.

  • Actions not handled by the active input mode can be forwarded to the application.