Using Keyboard Shortcuts in Components
Shortcuts allow you to assign keyboard shortcuts to your components to improve end-user experience.
You can add available shortcuts, create your own custom shortcuts, and configure the reaction when a shortcut is triggered.
A shortcut key combination consists of one primary key and 0 to 4 key modifiers (Alt, Ctrl, Meta, Shift).
Adding Click Shortcuts
Click shortcuts define alternatives to the click action in components that implement the ClickNotifier
interface.
You can add a click shortcut using the addClickShortcut
method.
Example: Using the addClickShortcut
method to add a click shortcut to a Button
component.
TextField userName = new TextField("User name");
PasswordField password = new PasswordField("Password");
Button login = new Button("Login");
login.addClickListener(event -> this.login());
login.addClickShortcut(Key.ENTER);
-
Instead of clicking the button, the user can use the Enter key to perform the action tied to the button click.
Adding Focus Shortcuts
Focus shortcuts place focus on a Focusable
component, like an input field.
You can add a focus shortcut using the addFocusShortcut
method.
Example: Using the addFocusShortcut
method to add a focus shortcut to a TextTield
.
TextField textField = new TextField("Label");
textField.addFocusShortcut(Key.KEY_F, KeyModifier.ALT);
-
The user can focus on the
Label
text field using the ALT+F keyboard shortcut.
Adding Custom Shortcuts
You can use the addShortcutListener
method to add a shortcut that executes custom code when the shortcut is triggered.
Assume you have a custom method, public void openCustomerCreation()
, that opens an input form in which users can enter new customer information.
Example: Using the addShortcutListener
method to add a custom shortcut that executes the openCustomerCreation
method.
UI.getCurrent().addShortcutListener(
this::openCustomerCreation, Key.KEY_N,
KeyModifier.CONTROL, KeyModifier.ALT);
-
When the user presses Ctrl+Alt+N the form opens and the user can input the new customer information.
You can configure a shortcut to run any code that complies with the Command
functional interface. This interfaces has a single method called execute
that accepts zero arguments.
Example: Using the addShortcutListener
method to show
a notification
UI.getCurrent().addShortcutListener(
() -> Notification.show("Shortcut triggered"),
Key.SPACE);
Note
|
All methods that allow you to add shortcuts return an instance of ShortcutRegistration that provides a fluent API that you can use to further configure your shortcuts.
|
Configuring Shortcuts' Active Scope
By default, shortcuts are registered to the global scope. This means the shortcut is triggered when the user presses the correct keys, regardless where their cursor is or which element is focused on the screen.
You can configure when a shortcut is available, for example only when the user focuses an element, using the addShortcutListener
method made available by the fluent ShortcutRegistration
API.
Example: Using the addShortcutListener
method to define the component to which the listener attaches.
public class Scope extends Div {
public Scope() {
TextField firstName = new TextField();
TextField lastName = new TextField();
add(firstName, lastName);
Command command = () -> {
firstName.setValue("");
lastName.setValue("");
firstName.focus();
};
// first parameter is the lifecycle owner
// of the shortcut and will be discussed later.
Shortcuts.addShortcutListener(this,
command, Key.ESCAPE)
// defines the component onto which
// the shortcuts listener is attached:
.listenOn(this);
}
}
-
The shortcut is tied to the parent component (
Scope
) of the input components. -
If the user enters input into either
TextField
and then presses Escape, both input fields are cleared and focus is returned to the first field. -
This is useful where the same action should be triggered by a shortcut configured on all fields contained inside the same scope, but not outside of the enveloping component.
-
The shortcut is created using the factory class
Shortcuts
that offers the most generic method for creating shortcuts.
See Shortcut Life Cycle Owners below for more.
Removing Shortcuts
You can remove a registered shortcut using the Registration.remove()
method.
Each method that adds or registers a shortcut returns either a Registration
or ShortcutRegistration
object.
Example: Using the registration.remove
method to remove a shortcut.
TextField textField = new TextField("Label");
ShortcutRegistration registration =
textField.addFocusShortcut(Key.KEY_F,
KeyModifier.ALT);
// something happens here
registration.remove(); // shortcut removed!
Shortcut Life Cycle Owners
Shortcuts have a life cycle that is controlled by an associated Component
, called the lifecycleOwner
component.
When the component acting as a lifecycleOwner
is both attached and visible, the shortcut is active. If both conditions are not met, the shortcut cannot be triggered.
-
For focus and click shortcuts, the life cycle owner is the component itself. It only makes sense for the click shortcut to be active when the button or input field is both in the layout and visible.
-
For shortcuts registered through
UI
, the life cycle owner is theUI
. This means that the shortcut only stops functioning when it is removed.
You can use the Shortcuts.addShortcutListener(…)
method to create a shortcut with a life cycle bound to a specific component.
Example: Binding a shortcut to the life cycle of the Paragraph
component using the Shortcuts.addShortcutListener(…)
method.
Paragraph paragraph =
new Paragraph("When you see me, try ALT+G!");
Shortcuts.addShortcutListener(paragraph,
() -> Notification.show("Well done!"),
Key.KEY_G, KeyModifier.ALT);
add(paragraph);
-
The first parameter of the
Shortcuts.addShortcutListener(Component, Command, Key, KeyModifier…);
method is thelifecycleOwner
component. -
This code binds the ALT+G shortcut to the life cycle of
paragraph
and is only active when the component is both attached and visible.
You can also use the bindLifecycleTo
method to reconfigure the lifecycleOwner
component of shortcuts.
Example: Binding the life cycle of a global shortcut to anotherComponent
using the bindLifecycleTo
method.
UI.getCurrent().addShortcutListener(
() -> {/* do a thing*/}, Key.KEY_F)
.bindLifecycleTo(anotherComponent);
Listening for Shortcut Events
The addShortcutListener
method has an overload method that accepts a ShortcutEventListener
instead of the Command
parameter. When the shortcut is detected, the event listener receives a ShortcutEvent
that contains the Key
, KeyModifiers
, and both listenOn
and lifecycleOwner
components.
Example: Registering a ShortcutEventListener
and using it with the addShortcutListener
overload method.
// handles multiple shortcuts
ShortcutEventListener listener = event -> {
if (event.matches(Key.KEY_G, KeyModifier.ALT)) {
// do something G-related
}
else if (event.matches(Key.KEY_J, KeyModifier.ALT)) {
// do something J-releated
}
};
UI.getCurrent().addShortcutListener(listener,
Key.KEY_G, KeyModifier.ALT);
UI.getCurrent().addShortcutListener(listener,
Key.KEY_J, KeyModifier.ALT);
-
The
listener
is responsible for handling events triggered by multiple shortcuts: both ALT+G and ALT+J invoke the listener. -
The
ShortcutEvent
provides the.matches(Key, KeyModifier…)
method to evaluate which shortcut is in question. For additional comparisons, you can use.getSource()
(which returns thelistenOn
component), and.getLifecycleOwner()
(which returns thelifecycleOwner
component).
Shorthands for Shortcut Modifiers
ShortcutRegistration
includes shorthands for assigning key modifiers to a shortcut.
Example: Using the .withAlt()
and .withShift()
key modifiers with the addFocusShortcut
method.
Input input = new Input();
input.addFocusShortcut(Key.KEY_F).withAlt().withShift();
-
The focus shortcut is triggered with Alt+Shift+F.
ShortcutRegistration
also has the .withModifiers(KeyModifiers…modifiers)
method that can be used to configure all modifiers simultaneously, or to remove all modifiers. Calling withModifiers(…);
without parameters removes all modifiers from the shortcut.
Shortcut Event Behavior on the Client Side
ShortcutRegistration
provides methods to define the behavior of events on the client side. With DOM events you can control if an event should propagate upwards in the DOM tree, and if it should allow default browser behavior.
By default, shortcuts created by Vaadin Flow consume the event. This means, by default:
-
Events do not propagate upwards in the DOM tree, and
-
Default browser behavior is prevented, for example the characters used in the shortcut are not inserted into the input field.
You can change the default behavior using the allowEventPropagation()
(fluent), allowBrowserDefault()
(fluent), setEventPropagationAllowed(boolean)
, and setBrowserDefaultAllowed(boolean)
methods.
Example: Using the allowEventPropagation
method to change the default behavior of a focus shortcut.
Input input = new Input();
input.addFocusShortcut(Key.KEY_F)
// other handlers can now catch this event
.allowEventPropagation()
// the character 'f' will be written out,
// if a text field is focused
.allowBrowserDefault();
Note that there is one exception to these rules: click shortcuts created with the ClickNotifier::addClickShortcut(Key, KeyModifier…)
method allow default browser behavior, by default.
Checking Shortcut States
ShortcutRegistration
offers a variety of methods to check the internal state of a shortcut, and all configurable values that have corresponding getter methods.
In addition, you can use the boolean isShortcutActive()
method to check whether the shortcut is enabled on the client side.
3A0F02F2-BB3B-4993-9DE6-5D3C51ECADD8