Why the Listener is propagated to all components in the form?

I have a simple login view:
User:
Pwd:
(Button Log)
Until now, u needed to press the button to send the request and bla bla …
I wanted that behaviour pressing Enter key on Pwd too, so after a short research I did this:

[code]
pwdField.addShortcutListener(new ShortcutListener(“enterAction”, ShortcutAction.KeyCode.ENTER, null) {

        @Override
        public void handleAction(Object sender, Object target) {
            login();
        }
    });

[/code]and testing this amazing enhancement in the login View, I discovered the TextField userField is also trigging the listener!!, that I explicitly added JUST TO pwdField… and here is the title of this topic… WHY?
I already read
https://vaadin.com/forum/#!/thread/77601/7736664
and found this tricky workaround
http://ramontalaverasuarez.blogspot.com.ar/2014/06/vaadin-7-detect-enter-key-in-textfield.html

And want to know if this is an oooold bug unsolved or what? how adding a listener to a specifict component anothers trigger it too?

Hi

forget about the textboxes, set the shortcut for the button itself

Button login = new Button("Login");
login.setClickShortcut(KeyCode.ENTER);

Hi Hamed and thanks, but I’m looking for an answer not for alternative solutions.
My example is very simple, but I got more complex form to create with a lot of “key enter compoment to do” (like money fields, ID fields, Date validation fields and so on…) to implement and this is a serious problem

I thought It would be helpful. I hope you’ll find it soon :slight_smile:

Mmm, I haven’t visited the shortcut actions for some time, but as far as I understand the problem, shortcut actions are shortcuts to execute some action in wider context, such as a panel or UI.

Typically, you have a UI, sub-window, or panel with a number of components, and use a ShortcutListener to focus or click one of them. They are
shortcut
keys to perform one action within a certain scope. Hence, the scope of a ShortcutListener is not the component, as you assume in your code, but the Panel, Window, or UI in which the component is contained in.

Perhaps this should be mentioned more clearly in the documentation. Actually, it looks like the book section is outdated in that respect: previously it was only possible to add shortcuts to Panel and Window, and the current API is maybe a bit confusing in that respect, that you might think that it’s inside a component.

To clarify this further, the “sender” in the shortcut action is the scope (action manager) of the action – it’s either UI, Window, or Panel.

The “target” is the target of the action, which with shortcut actions means the component in which the event occurred. In your case, you could use it to check in which field the user pressed Enter, by comparing it to references to the fields, and then perform the login() only if it == pwdField.

the tricky workaround from Ramon’s blog is much more elegant than being asking “who component trigger me?!” (specially if we are talking about a much more complex form than a login) and the lacking of .addKeyListener() for each component

And I just tested, if I add shortcuts for each component (userField, pwdField, and created a 3rdField ) with a simple System.out.println(“asdfae”);, just userField works, the 2 others are not trigged, PD: loginButton still works.

Yes, that’s because the shortcuts are actually not added to the components, but to the ActionManager in the containing Panel, Window, or UI. The action manager defines the scope of the shortcuts, and a key can only trigger one action in the scope.

… so in your case that would go something like:

loginPanel.addShortcutListener(new ShortcutListener("enterAction", ShortcutAction.KeyCode.ENTER, null) {
    @Override
    public void handleAction(Object sender, Object target) {
        if (target == pwdField)
            login();
    }
});