Documentation

Documentation versions (currently viewingVaadin 23)

You are viewing documentation for Vaadin 23. View latest documentation

Keyboard Shortcuts

Shortcuts allow you to assign keyboard shortcuts to your components to improve end-user experience.

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 interface has a single method called execute(), which 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, which provides a fluent API that you can use to further configure your shortcuts.

Configuring the Active Scope of Shortcuts

By default, shortcuts are registered to the global scope. This means that the shortcut is triggered when the user presses the correct keys, regardless of where their cursor is or which element is in focus on the screen.

You can configure the availability of a shortcut (for example, only when the user focuses on 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 it is 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 types input into either TextField and then presses Esc, 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, which offers the most generic method for creating shortcuts.

See Shortcut Lifecycle Owners below for more.

Removing Shortcuts

You can remove a registered shortcut using the Registration.remove() method.

A 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 Lifecycle Owners

Shortcuts have a lifecycle that’s 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 these conditions aren’t both met, the shortcut can’t be triggered.

  • For focus and click shortcuts, the lifecycle 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 lifecycle owner is the UI. This means that the shortcut only stops functioning when it’s removed.

You can use the Shortcuts.addShortcutListener(…​) method to create a shortcut with a lifecycle bound to a specific component.

Example: Binding a shortcut to the lifecycle 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 the lifecycleOwner component.

  • This code binds the Alt+G shortcut to the lifecycle 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 lifecycle of a click shortcut to another component using the bindLifecycleTo() method.

Grid<User> usersList = new Grid<>();
Button newUserButton = new Button("Add user", event -> {
        // show new user form
});
newUserButton.addClickShortcut(Key.KEY_N, KeyModifier.CONTROL)
        .bindLifecycleTo(usersList);

The keyboard shortcut for clicking the “Add user” button is active when the usersList component is visible on the page. Once the usersList component is detached or it becomes invisible, the shortcut is no longer active.

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-related
   }
};

UI.getCurrent().addShortcutListener(listener,
        Key.KEY_G, KeyModifier.ALT);
UI.getCurrent().addShortcutListener(listener,
        Key.KEY_J, KeyModifier.ALT);
  • The listener handles events triggered by multiple shortcuts; both Alt+G and Alt+J invoke the listener.

  • The ShortcutEvent provides the matches(Key, KeyModifier…​) method to determine which shortcut triggered the event. For additional comparisons, you can use getSource() (which returns the listenOn component) and getLifecycleOwner() (which returns the lifecycleOwner 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, which 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 browser DOM events, you can control whether an event should propagate upwards in the DOM tree (component hierarchy), and whether it should allow default browser behavior.

By default, shortcuts consume the event, which means that:

  • events don’t propagate upwards in the DOM tree (component hierarchy), and

  • the default browser behavior is prevented; for example, the characters used in the shortcut aren’t inserted into the input field, or clicking on a link prevents the browser from following the URL. See Event.preventDefault() for more information.

As an exception, click shortcuts created with the ClickNotifier::addClickShortcut(Key, KeyModifier…​) method allow default browser behavior by default.

You can change the default behavior using the allowEventPropagation() (fluent), allowBrowserDefault() (fluent), setEventPropagationAllowed(boolean), and setBrowserDefaultAllowed(boolean) methods.

Example: Using the allowBrowserDefault() method to change the default behavior of a focus shortcut.

Input input = new Input();
input.addFocusShortcut(Key.KEY_F)
        // the character 'f' is entered
        // into the input, if it's focused
        .allowBrowserDefault();

Example: Using the allowEventPropagation() method to react to a shortcut event and change the styles of a form.

TextField name = new TextField("Name");
TextField address = new TextField("Address");
VerticalLayout form = new VerticalLayout(name, address);
add(form);

name.addFocusShortcut(Key.KEY_N, KeyModifier.CONTROL)
        .listenOn(form)
        // the shortcut event is propagated from the text field to the
        // form and higher in the hierarchy
        .allowEventPropagation();

// the listener attached to the view (this) can now catch the
// shortcut event and change the form styles
Shortcuts.addShortcutListener(this,
        () -> form.setClassName("red-border"),
        Key.KEY_N, KeyModifier.CONTROL)
        .listenOn(this);

Once the "Name" field has focus and the shortcut is activated, the event is propagated higher in the component hierarchy and caught by the view component.

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.

C949BD20-2809-4BD0-81FF-9A9A4E6F96E5