Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

org.fxmisc.wellbehaved.event.EventPattern.keyTyped with parameters depends on keyboard layout #15

Closed
appsofteng opened this issue Mar 2, 2018 · 5 comments

Comments

@appsofteng
Copy link

Hi,

when I use standard JavaFX handler I can simply check the character of the key event independently of the keyboard layout. I ignore modifiers.

       area.setOnKeyTyped(e -> {
           if (e.getCharacter().equals("}")) {
               System.out.println(e);
           }
       });

This is not possible with the EventPattern because KeyTypedCombination matches the modifiers with the event.
The code below will not print because the "}" is typed Shift + } thus the event has the Shift modifier.
consume(keyTyped("}"), e -> System.out.println(e))

It is necessary to use the Shift modifier which is unintuitive because I am only interested in the character independently of the keyboard layout.
consume(keyTyped("}", SHIFT_DOWN), e -> System.out.println(e))

I think that if a caller puts no modifiers then the event modifiers should be ignored.

@JordanMartinez
Copy link
Contributor

I see your point. Will that end up breaking something else if the fixed was added?

You could also easily create your own static factory method that will do the same thing:

public static EventPattern<Event, KeyEvent> keyTyped(String character) {
    return EventPattern.keyTyped().onlyIf(e -> e.getCharacter().equals(character));

@appsofteng
Copy link
Author

Thanks. I leave the consideration to you. My opinion is that the change would make it more consistent. Take the examples below. Now they behave differently based on whether you type the key on the main keyboard or on the numerical keyboard. Typing on the main keyboard is with Shift and thus does not pass the modifier check. Typing on the numerical keyboard is without Shift and the handler is called.

    consume(keyTyped("*"), e -> System.out.println(e)),
    consume(keyTyped(k -> k.equals("+")), e -> System.out.println(e)),

@JordanMartinez
Copy link
Contributor

Looking at those examples, I agree. Checking whether the modifiers are pressed only make sense if it's needed and your use case doesn't need such a thing.

However, I won't spend my time implementing this. If you'd like fix this, please submit a PR. If not, then you can implement the quick fix above in your own code.

@JordanMartinez
Copy link
Contributor

After implementing this and trying it out in RichTextFX, I no longer think this is the best idea. By turning all modifiers to ANY, it means that one has to put more work into specifying how multiple InputMaps are sequenced together. For example, if I sequence it this way:

InputMapTemplate<GenericStyledAreaBehavior, KeyEvent> editsBase = sequence(
        // short for DELETE + Any other modifiers
        consume(keyPressed(DELETE),                     GenericStyledAreaBehavior::deleteForward),
        consume(keyPressed(DELETE,     SHORTCUT_DOWN),  GenericStyledAreaBehavior::deleteNextWord)
);

the problem is that Delete will match all the time and Shortcut+Delete will never match. As a developer, I would need to specify my code in such a way that all the modifier-related things appear first in the sequence of InputMaps rather than last. However, that doesn't read well. Usually the inputs without modifiers appear first and the modifiers adjust the default behavior in a small way (e.g. deleteOneCharForward vs deleteOneWordForward).

Thus, the 0.3.2 release isn't a minor release as it does break backwards compatibility, not at the source level but at the function level.

Your use case is a real situation that should be addressed in this project so that others don't need to reimplement it again and again. However, I think it should be handled differently. Since keyTyped(String) by itself expands to keyTyped(String, Modifier...) (and the same for keyPressed and keyReleased), I think there should be another method named keyTypedNoMod(String) that will reduce to keyTyped().onlyIf(e -> e.getText.matches(string)).

@JordanMartinez
Copy link
Contributor

Closed by #21

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants