Vaadin provides simple ways for defining shortcut keys for field components and a default button, and a lower-level generic shortcut key binding API based on actions.

Shortcut keys can be defined as actions using the ShortcutAction class. ShortcutAction extends the generic Action class that is used for example in Tree and Table for context menus. Currently, the only classes that accept ShortcutActions are Window and Panel.

To handle key presses, you need to define an action handler by implementing the Handler interface. The interface has two methods that you need to implement: getActions() and handleAction().

The getActions() method must return an array of Action objects for the component, specified with the second parameter for the method, the sender of an action. For a keyboard shortcut, you use a ShortcutAction. The implementation of the method could be following:

// Have the unmodified Enter key cause an event
Action action_ok = new ShortcutAction("Default key",
        ShortcutAction.KeyCode.ENTER, null);

// Have the C key modified with Alt cause an event
Action action_cancel = new ShortcutAction("Alt+C",
        ShortcutAction.KeyCode.C,
        new int[] { ShortcutAction.ModifierKey.ALT });

Action[] actions = new Action[] {action_cancel, action_ok};

public Action[] getActions(Object target, Object sender) {
    if (sender == myPanel)
        return actions;

    return null;
}

The returned Action array may be static or you can create it dynamically for different senders according to your needs.

The constructor of ShortcutAction takes a symbolic caption for the action; this is largely irrelevant for shortcut actions in their current implementation, but might be used later if implementors use them both in menus and as shortcut actions. The second parameter is the key code and the third a list of modifier keys, which are listed in Section 12.6.4, “Supported Key Codes and Modifier Keys”.

The following example demonstrates the definition of a default button for a user interface, as well as a normal shortcut key, Alt+C for clicking the Cancel button.

public class DefaultButtonExample extends CustomComponent
                                  implements Handler {
    // Define and create user interface components
    Panel panel = new Panel("Login");
    FormLayout formlayout = new FormLayout();
    TextField username = new TextField("Username");
    TextField password = new TextField("Password");
    HorizontalLayout buttons = new HorizontalLayout();

    // Create buttons and define their listener methods.
    Button ok = new Button("OK", this, "okHandler");
    Button cancel = new Button("Cancel", this, "cancelHandler");

    // Have the unmodified Enter key cause an event
    Action action_ok = new ShortcutAction("Default key",
            ShortcutAction.KeyCode.ENTER, null);

    // Have the C key modified with Alt cause an event
    Action action_cancel = new ShortcutAction("Alt+C",
            ShortcutAction.KeyCode.C,
            new int[] { ShortcutAction.ModifierKey.ALT });

    public DefaultButtonExample() {
        // Set up the user interface
        setCompositionRoot(panel);
        panel.addComponent(formlayout);
        formlayout.addComponent(username);
        formlayout.addComponent(password);
        formlayout.addComponent(buttons);
        buttons.addComponent(ok);
        buttons.addComponent(cancel);

        // Set focus to username
        username.focus();

        // Set this object as the action handler
        System.out.println("adding ah");
        panel.addActionHandler(this);

        System.out.println("start done.");
    }

    /**
     * Retrieve actions for a specific component. This method
     * will be called for each object that has a handler; in
     * this example just for login panel. The returned action
     * list might as well be static list.
     */
    public Action[] getActions(Object target, Object sender) {
        System.out.println("getActions()");
        return new Action[] { action_ok, action_cancel };
    }

    /**
     * Handle actions received from keyboard. This simply directs
     * the actions to the same listener methods that are called
     * with ButtonClick events.
     */
    public void handleAction(Action action, Object sender,
                             Object target) {
        if (action == action_ok) {
            okHandler();
        }
        if (action == action_cancel) {
            cancelHandler();
        }
    }

    public void okHandler() {
        // Do something: report the click
        formlayout.addComponent(new Label("OK clicked. "
                + "User=" + username.getValue() + ", password="
                + password.getValue()));
    }

    public void cancelHandler() {
        // Do something: report the click
        formlayout.addComponent(new Label("Cancel clicked. User="
                + username.getValue() + ", password="
                + password.getValue()));
    }
}

Notice that the keyboard actions can currently be attached only to Panels and Windows. This can cause problems if you have components that require a certain key. For example, multi-line TextField requires the Enter key. There is currently no way to filter the shortcut actions out while the focus is inside some specific component, so you need to avoid such conflicts.

The shortcut key definitions require a key code to identify the pressed key and modifier keys, such as Shift, Alt, or Ctrl, to specify a key combination.

The key codes are defined in the ShortcutAction.KeyCode interface and are:

Keys A to Z
Normal letter keys
F1 to F12

Function keys

BACKSPACE, DELETE, ENTER, ESCAPE, INSERT, TAB

Control keys

NUM0 to NUM9

Number pad keys

ARROW_DOWN, ARROW_UP, ARROW_LEFT, ARROW_RIGHT

Arrow keys

HOME, END, PAGE_UP, PAGE_DOWN

Other movement keys

Modifier keys are defined in ShortcutAction.ModifierKey and are:

ModifierKey.ALT
Alt key
ModifierKey.CTRL
Ctrl key
ModifierKey.SHIFT
Shift key

All constructors and methods accepting modifier keys take them as a variable argument list following the key code, separated with commas. For example, the following defines a Ctrl+Shift+N key combination for a shortcut.

TextField name = new TextField("Name (Ctrl+Shift+N)");
name.addShortcutListener(
        new AbstractField.FocusShortcut(name, KeyCode.N,
                                        ModifierKey.CTRL,
                                        ModifierKey.SHIFT));