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,

If you have a panel you can bind generic shortcut actions i.e:

[code]
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 };
}
});
[/code]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 :

[code]
@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();
}

}
[/code]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!