Vaadin flow exception when using keyboard shortcuts in grid editor

106 views Asked by At

I want to use keyboard shortcuts in a vaadin flow 23 application inside an active grid editor. I get occasionally an exception in the test server which I can not reproduce locally:

java.lang.NullPointerException: Cannot invoke "com.vaadin.flow.component.Component.isVisible()" because "component" is null
2023-11-13 08:10:45.030 ERROR 1 --- [nio-8000-exec-9] c.v.flow.server.DefaultErrorHandler      : 
    at com.vaadin.flow.internal.nodefeature.ElementListenerMap.lambda$fireEvent$2(ElementListenerMap.java:447) ~[flow-server-23.3.18.jar!/:23.3.18]
    at com.vaadin.flow.component.ComponentEventBus.lambda$addDomTrigger$dd1b7957$1(ComponentEventBus.java:292) ~[flow-server-23.3.18.jar!/:23.3.18]
    at com.vaadin.flow.component.ComponentEventBus.handleDomEvent(ComponentEventBus.java:475) ~[flow-server-23.3.18.jar!/:23.3.18]
    at com.vaadin.flow.component.ComponentEventBus.fireEventForListener(ComponentEventBus.java:233) ~[flow-server-23.3.18.jar!/:23.3.18]
    at com.vaadin.flow.component.ShortcutRegistration.lambda$updateHandlerListenerRegistration$89e5c563$1(ShortcutRegistration.java:551) ~[flow-server-23.3.18.jar!/:23.3.18]
    at com.vaadin.flow.component.ShortcutRegistration.fireShortcutEvent(ShortcutRegistration.java:591) ~[flow-server-23.3.18.jar!/:23.3.18]
    at com.vaadin.flow.component.ShortcutRegistration.ancestorsOrSelfAreVisible(ShortcutRegistration.java:598) ~[flow-server-23.3.18.jar!/:23.3.18]
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) ~[na:na]
    at com.vaadin.flow.internal.nodefeature.ElementListenerMap.fireEvent(ElementListenerMap.java:447) ~[flow-server-23.3.18.jar!/:23.3.18]
    at com.vaadin.flow.server.communication.rpc.EventRpcHandler.handleNode(EventRpcHandler.java:62) ~[flow-server-23.3.18.jar!/:23.3.18]
    at com.vaadin.flow.spring.SpringServlet.service(SpringServlet.java:106) ~[vaadin-spring-23.3.18.jar!/:na]
    at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:369) ~[flow-server-23.3.18.jar!/:23.3.18]
    at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1560) ~[flow-server-23.3.18.jar!/:23.3.18]
    at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40) ~[flow-server-23.3.18.jar!/:23.3.18]
    at com.vaadin.flow.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:320) ~[flow-server-23.3.18.jar!/:23.3.18]
    at com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:115) ~[flow-server-23.3.18.jar!/:23.3.18]
    at com.vaadin.flow.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:419) ~[flow-server-23.3.18.jar!/:23.3.18]
    at com.vaadin.flow.server.communication.ServerRpcHandler.handleInvocationData(ServerRpcHandler.java:438) ~[flow-server-23.3.18.jar!/:23.3.18]
    at com.vaadin.flow.server.communication.ServerRpcHandler.lambda$handleInvocations$1(ServerRpcHandler.java:419) ~[flow-server-23.3.18.jar!/:23.3.18]
    at com.vaadin.flow.server.communication.rpc.AbstractRpcInvocationHandler.handle(AbstractRpcInvocationHandler.java:75) ~[flow-server-23.3.18.jar!/:23.3.18]

I want the shortcuts only to be active while the editor is opened. Therefore my code looks like this:

editColumn.setEditorComponent(getEditRowButtonsLayout());

private HorizontalLayout getEditRowButtonsLayout() {
    saveEditButton = new Button();
    cancelEditButton = new Button();
    saveEditButton.addClickListener(event -> save());
    cancelEditButton.addClickListener(event -> editor.cancel());

    return new HorizontalLayout(saveEditButton, cancelEditButton);  
}

editor.addOpenListener(event -> registerShortcuts());
editor.addCloseListener(event -> removeShortcuts());

private void registerShortcuts() {
    enterShortcut = saveEditButton.addClickShortcut(Key.ENTER);
    numpadEnterShortcut = saveEditButton.addClickShortcut(Key.NUMPAD_ENTER);
    escapeShortcut = cancelEditButton.addClickShortcut(Key.ESCAPE);
}

private void removeShortcuts() {
    enterShortcut.remove();
    numpadEnterShortcut.remove();
    escapeShortcut.remove();
}

Is this a bug in the event firing mechanism or am I implementing this feature wrong?

UPDATE: Unfortunately rejoyed too soon. I changed the code as suggested and still get occasionally the exception as described above. Can not reproduce it either.

private void registerShortcuts() {
    enterShortcut = UI.getCurrent().addShortcutListener(this::saveEdited, Key.ENTER);
    numpadEnterShortcut = UI.getCurrent().addShortcutListener(this::saveEdited, Key.NUMPAD_ENTER);
    escapeShortcut = UI.getCurrent().addShortcutListener(event -> editor.cancel(), Key.ESCAPE);
}

To me it looks like a bug because there is a "isVisible()" check in the ShorcutRegistration class without null check. Still can't wrap it up because it is not reproducible and works most of the time.

0

There are 0 answers