Shortcut keys can be defined as actions using the
ShortcutAction class. ShortcutAction extends 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.
This may change in the future. Table is a good
candidate to support ShortcutActions.
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() interface 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 created dynamically for different senders according to your needs.
The constructor method 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 in both menus and as shortcut actions.
The second parameter is the keycode, as defined in
ShortcutAction.KeyCode interface. Currently, the
following keycodes are allowed:
Function keys
Control keys
Number pad keys
Arrow keys
Other movement keys
The third parameter is an array of modifier keys, as defined in the
ShortcutAction.ModifierKey interface. The
following modifier keys are allowed: ALT,
CTRL, and SHIFT. The modifier
keys can be combined; for example, the following defines shortcut key
combination
Ctrl-Shift-S:
ShortcutAction("Ctrl+Shift+S",
ShortcutAction.KeyCode.S, new int[] {
ShortcutAction.ModifierKey.CTRL,
ShortcutAction.ModifierKey.SHIFT});
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.
import com.itmill.toolkit.event.Action;
import com.itmill.toolkit.event.ShortcutAction;
import com.itmill.toolkit.event.Action.Handler;
import com.itmill.toolkit.ui.Button;
import com.itmill.toolkit.ui.CustomComponent;
import com.itmill.toolkit.ui.FormLayout;
import com.itmill.toolkit.ui.HorizontalLayout;
import com.itmill.toolkit.ui.Label;
import com.itmill.toolkit.ui.Panel;
import com.itmill.toolkit.ui.TextField;
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.