mirror of
https://github.com/vaadin/framework.git
synced 2024-07-30 08:18:58 +02:00
![Michael Forstner](/assets/img/avatar_default.png)
* Add missing FocusShortcutListener Was removed from 8.0 and not readded. Fixes #8297 * Update Release note for this change
285 lines
10 KiB
Plaintext
285 lines
10 KiB
Plaintext
---
|
|
title: Shortcut Keys
|
|
order: 5
|
|
layout: page
|
|
---
|
|
|
|
[[advanced.shortcuts]]
|
|
= Shortcut Keys
|
|
|
|
Vaadin provides simple ways to define shortcut keys for field components, as
|
|
well as to a default button, and a lower-level generic shortcut API based on
|
|
actions.
|
|
|
|
A __shortcut__ is an action that is executed when a key or key combination is
|
|
pressed within a specific scope in the UI. The scope can be the entire
|
|
[classname]#UI# or a [classname]#Window# inside it.
|
|
|
|
[[advanced.shortcuts.defaultbutton]]
|
|
== Shortcut Keys for Default Buttons
|
|
|
|
You can add a __click shortcut__ to a button to set it as "default" button;
|
|
pressing the defined key, typically kbd:[Enter], in any component in the scope
|
|
(sub-window or UI) causes a click event for the button to be fired.
|
|
|
|
You can define a click shortcut with the [methodname]#setClickShortcut()#
|
|
shorthand method:
|
|
|
|
|
|
[source, java]
|
|
----
|
|
// Have an OK button and set it as the default button
|
|
Button ok = new Button("OK");
|
|
ok.setClickShortcut(KeyCode.ENTER);
|
|
ok.addStyleName(ValoTheme.BUTTON_PRIMARY);
|
|
----
|
|
|
|
The [methodname]#setClickShortcut()# is a shorthand method to create, add, and
|
|
manage a [classname]#ClickShortcut#, rather than to add it with
|
|
[methodname]#addShortcutListener()#.
|
|
|
|
Themes offer special button styles to show that a button is special. In the Valo
|
|
theme, you can use the [literal]#++BUTTON_PRIMARY++# style name. The result can
|
|
be seen in <<figure.advanced.shortcuts.defaultbutton>>.
|
|
|
|
[[figure.advanced.shortcuts.defaultbutton]]
|
|
.Default Button with Click Shortcut
|
|
image::img/shortcut-defaultbutton.png[]
|
|
|
|
|
|
[[advanced.shortcuts.focus]]
|
|
== Field Focus Shortcuts
|
|
|
|
You can define a shortcut key that sets the focus to any focusable component (implements [interface]#Focusable#), usually field components, by adding a
|
|
[interface]#FocusShortcut# as a shortcut listener to the component.
|
|
|
|
The constructor of the [classname]#FocusShortcut# takes the focusable component as
|
|
its first parameter, followed by the key code, and an optional list of modifier
|
|
keys, as listed in <<advanced.shortcuts.keycodes>>.
|
|
|
|
|
|
[source, java]
|
|
----
|
|
// A field with Alt+N bound to it
|
|
TextField name = new TextField("Name (Alt+N)");
|
|
name.addShortcutListener(
|
|
new FocusShortcut(name, KeyCode.N,
|
|
ModifierKey.ALT));
|
|
layout.addComponent(name);
|
|
----
|
|
|
|
You can also specify the shortcut by a shorthand notation, where the shortcut
|
|
key is indicated with an ampersand ( [literal]#++&++#).
|
|
|
|
|
|
[source, java]
|
|
----
|
|
// A field with Alt+A bound to it, using shorthand notation
|
|
TextField address = new TextField("Address (Alt+A)");
|
|
address.addShortcutListener(
|
|
new FocusShortcut(address, "&Address"));
|
|
----
|
|
|
|
This is especially useful for internationalization, so that you can determine
|
|
the shortcut key from the localized string.
|
|
|
|
|
|
[[advanced.shortcuts.actions]]
|
|
== Generic Shortcut Actions
|
|
|
|
Shortcut keys can be defined as __actions__ using the
|
|
[classname]#ShortcutAction# class. It extends the generic [classname]#Action#
|
|
class that is used for example in [classname]#Tree# and [classname]#Table# for
|
|
context menus. Currently, the only classes that accept
|
|
[classname]##ShortcutAction##s are [classname]#Window# and [classname]#Panel#.
|
|
|
|
To handle key presses, you need to define an action handler by implementing the
|
|
[classname]#Handler# interface. The interface has two methods that you need to
|
|
implement: [methodname]#getActions()# and [methodname]#handleAction()#.
|
|
|
|
The [methodname]#getActions()# method must return an array of
|
|
[classname]#Action# objects for the component, specified with the second
|
|
parameter for the method, the [parameter]#sender# of an action. For a keyboard
|
|
shortcut, you use a [classname]#ShortcutAction#. The implementation of the
|
|
method could be following:
|
|
|
|
|
|
[source, java]
|
|
----
|
|
// 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 [classname]#Action# array may be static or you can create it
|
|
dynamically for different senders according to your needs.
|
|
|
|
The constructor of [classname]#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 <<advanced.shortcuts.keycodes>>.
|
|
|
|
The following example demonstrates the definition of a default button for a user
|
|
interface, as well as a normal shortcut key, kbd:[Alt+C] for clicking the
|
|
[guibutton]#Cancel# button.
|
|
|
|
|
|
[source, java]
|
|
----
|
|
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", event -> okHandler());
|
|
Button cancel = new Button("Cancel", event -> 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
|
|
panel.addActionHandler(this);
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
[classname]##Panel##s and [classname]##Window##s. This can cause problems if you
|
|
have components that require a certain key. For example, multi-line
|
|
[classname]#TextField# requires the kbd:[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.
|
|
|
|
|
|
[[advanced.shortcuts.keycodes]]
|
|
== Supported Key Codes and Modifier Keys
|
|
|
|
The shortcut key definitions require a key code to identify the pressed key and
|
|
modifier keys, such as kbd:[Shift], kbd:[Alt], or kbd:[Ctrl], to specify a key combination.
|
|
|
|
The key codes are defined in the [classname]#ShortcutAction.KeyCode# interface
|
|
and are:
|
|
|
|
Keys [parameter]#A# to [parameter]#Z#:: Normal letter keys
|
|
[parameter]#F1# to [parameter]#F12#:: Function keys
|
|
|
|
[parameter]#BACKSPACE#, [parameter]#DELETE#, [parameter]#ENTER#, [parameter]#ESCAPE#, [parameter]#INSERT#, [parameter]#TAB#:: Control keys
|
|
|
|
[parameter]#NUM0# to [parameter]#NUM9#:: Number pad keys
|
|
|
|
[parameter]#ARROW_DOWN#, [parameter]#ARROW_UP#, [parameter]#ARROW_LEFT#, [parameter]#ARROW_RIGHT#:: Arrow keys
|
|
|
|
[parameter]#HOME#, [parameter]#END#, [parameter]#PAGE_UP#, [parameter]#PAGE_DOWN#:: Other movement keys
|
|
|
|
|
|
|
|
Modifier keys are defined in [classname]#ShortcutAction.ModifierKey# and are:
|
|
|
|
[parameter]#ModifierKey.ALT#:: kbd:[Alt] key
|
|
[parameter]#ModifierKey.CTRL#:: kbd:[Ctrl] key
|
|
[parameter]#ModifierKey.SHIFT#:: kbd:[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 kbd:[Ctrl+Shift+N] key combination for a shortcut.
|
|
|
|
|
|
[source, java]
|
|
----
|
|
TextField name = new TextField("Name (Ctrl+Shift+N)");
|
|
name.addShortcutListener(
|
|
new FocusShortcut(name, KeyCode.N,
|
|
ModifierKey.CTRL,
|
|
ModifierKey.SHIFT));
|
|
----
|
|
|
|
=== Supported Key Combinations
|
|
|
|
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 kbd:[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.
|