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.
You can add or set a click shortcut to a button to set it as "default" button; pressing the defined key, typically Enter, in any component in the window causes a click event for the button.
You can define a click shortcut with the
setClickShortcut()
shorthand method:
// Have an OK button and set it as the default button Button ok = new Button("OK"); ok.setClickShortcut(KeyCode.ENTER); ok.addStyleName("primary");
The primary
style name highlights a button to show the
default button status; usually with a bolder font than usual, depending on
the theme. The result can be seen in Figure 12.9, “Default Button with Click Shortcut”.
You can define a shortcut key that sets the focus to a field component
(any component that inherits AbstractField
) by
adding a FocusShortcut
as a shortcut listener to
the field.
// A field with Alt+N bound to it TextField name = new TextField("Name (Alt+N)"); name.addShortcutListener( new AbstractField.FocusShortcut(name, KeyCode.N, ModifierKey.ALT)); layout.addComponent(name); // A field with Alt+A bound to it TextField address = new TextField("Address (Alt+A)"); address.addShortcutListener( new AbstractField.FocusShortcut(address, KeyCode.A, ModifierKey.ALT)); layout.addComponent(address);
The constructor of the FocusShortcut
takes the
field component as its first parameter, followed by the key code, and an
optional list of modifier keys, as listed in Section 12.6.4, “Supported Key Codes and Modifier Keys”.
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
ShortcutAction
s 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 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
Panel
s and Window
s. 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:
A
to Z
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
ModifierKey.CTRL
ModifierKey.SHIFT
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));
The actual possible key combinations vary greatly between browsers, as most browsers have a number of built-in shortcut keys, which can not be used in web applications. For example, Mozilla Firefox allows binding almost any key combination, while Opera does not even allow binding Alt shortcuts. Other browsers are generally in between these two. Also, the operating system can reserve some key combinations and some computer manufacturers define their own system key combinations.