Important Notice - Forums is archived
To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.
Generic keypress listener
Is there a way of binding a general keylistener to the UI or the root layout or even a panel?
I'm trying to avoid the soft keyboard on mobile devices by avoiding TextFields on a view. I sort of managed to hook up a shortcut listener for keys 0-9 (each one adds a digit to a label and enter searches/clears) but it looks a bit silly. And with some barcodes, that's not even enough. And on IE the root layout doesn't get initial focus(?).
I'd love to do it from within Vaadin if possible...
Thanks in advance,
Nik
Hi Nicklas,
Nicklas Karlsson: Is there a way of binding a general keylistener to the UI or the root layout or even a panel?
If you have a panel you can bind generic shortcut actions i.e:
Panel panel = new Panel();
panel.addActionHandler(new Handler() {
Action action_0 = new ShortcutAction("key 0", ShortcutAction.KeyCode.NUM0, null);
Action action_1 = new ShortcutAction("key 1", ShortcutAction.KeyCode.NUM1, null);
@Override
public void handleAction(Action action, Object sender, Object target) {
if (action == action_0) {
// handle action
}
if (action == action_1) {
// handle action
}
}
@Override
public Action getActions(Object target, Object sender) {
return new Action { action_0, action_1 };
}
});
You can find further details in the documentation for "Generic Shortcut Actions".
Hope this helps,
Goran
Thanks for the pointer but that approach has the drawback that I would have to register one action for all alphanumeric keys. It would be handy if there would be some sort of
new ShortcutAction("any key", ShortcutAction.KeyCode.ANY, null) and whatever was pressed could be read in a handler...
You can do that by creating a javascript extension.
For example the java extension :
@JavaScript({
"KeyListener.js"
})
public class KeyListener extends AbstractJavaScriptExtension implements Serializable{
private static final long serialVersionUID = 1L;
public KeyListener(AbstractComponent comp) {
addFunction("keypress", new JavaScriptFunction() {
@Override
public void call(JsonArray arguments) {
int keycode = (int) arguments.getNumber(0);
Notification.show("Key : " + keycode);
}
});
}
@Override
protected KeyListenerState getState(){
return (KeyListenerState) super.getState();
}
}
The state (even if you don't have to share frome the server to the client)
package com.atalante.application.ui.composants.js;
import com.vaadin.shared.JavaScriptExtensionState;
public class KeyListenerState extends JavaScriptExtensionState {
}
the js file : (i used jquery for simplification but you can write it without using it)
the keypress in js will trigger the remote server method with the argument of the keycode
window.com_atalante_application_ui_composants_js_KeyListener = function(){
var self = this;
//Gère le chargement et les modifications côté serveur
this.onStateChange = function() {
$(document).keydown(function(e){
self.keypress(e.which);
});
};
}
and finally you can attach this to any component.
For example in the ui
new KeyListener().extend(ui);
Thanks, it looks promising, haven't ventured into JS extensions yet but now is a good a time as any!