JavaFX - Accelerator not working when textfield ha

2019-06-26 07:02发布

In my application I have a screen where I use Accelerators. I'm using the function key F3 to execute an operation in my application. It works fine everytime, but when I click in any TextField on this screen the function key doesn't execute.

Here is the code where I set the Accelerator:

    scene.getAccelerators().put(
            new KeyCodeCombination(KeyCode.F3),
            new Runnable() {
                @Override
                public void run() {
                    // do sth here
                }
            }
    );

When I click my textfield and then hit the F3 function key it doesn't work. Someone knows the solution?

3条回答
Bombasti
2楼-- · 2019-06-26 07:31

This answer is based on tikerman's. I added the code to handle modifier keys.

if (!event.getCode().isModifierKey()) {
    Consumer<KeyCombination.Modifier[]> runAccelerator = (modifiers) -> {
        Runnable r = getScene().getAccelerators().get(new KeyCodeCombination(event.getCode(), modifiers));
        if (r != null) {
            r.run();
        }
    };

    List<KeyCombination.Modifier> modifiers = new ArrayList<>();
    if (event.isControlDown()) modifiers.add(KeyCodeCombination.CONTROL_DOWN);
    if (event.isShiftDown()) modifiers.add(KeyCodeCombination.SHIFT_DOWN);
    if (event.isAltDown()) modifiers.add(KeyCodeCombination.ALT_DOWN);

    runAccelerator.apply(modifiers.toArray(new KeyCombination.Modifier[modifiers.size()]));
}

Edit: fix consumer spelling.

查看更多
The star\"
3楼-- · 2019-06-26 07:33

This works for me using Java 1.8.0_45. However I encounter a similar issue with an editable Combobox field.

Edited:

Upon further investigation it does seem to occur with text field as well. I worked around it using the following custom class in place of text field:

public class ShortcutFriendlyTextField extends TextField{

    public ShortcutFriendlyTextField() {
        super();
        addEventHandler(KeyEvent.KEY_RELEASED,new EventHandler<KeyEvent>() {

            @Override
            public void handle(KeyEvent event) {
                //handle shortcuts if defined
                Runnable r=getScene().getAccelerators().get(new KeyCodeCombination(event.getCode()));
                if(r!=null) {
                    r.run();  
                }
            }
        }); 
    }
}
查看更多
混吃等死
4楼-- · 2019-06-26 07:42

If you have accelerators setup else where, such as a MenuBar, using some of the other solutions will cause the shortcut to be executed twice.

In my case, using modifiers with my shortcut (SHIFT + F3) works while in focus in the text area, but not while using just an accelerator such as just F3.

I set mine up to only use the event handler for shortcuts that do not use a modifier.

public  static final double JAVA_VERSION = Double.parseDouble(System.getProperty("java.specification.version"));
public static void makeInputFieldShortCutFriendly(Node node) {
    //this bug wasn't fixed until 9.0
    if (JAVA_VERSION < 9) {
        node.addEventHandler(KeyEvent.KEY_RELEASED, (KeyEvent event) -> {
            if (!event.getCode().isModifierKey()) {
                if (!event.isAltDown() && !event.isShiftDown() && !event.isAltDown()) {
                    Runnable r = node.getScene().getAccelerators().get(new KeyCodeCombination(event.getCode(), KeyCodeCombination.SHORTCUT_ANY));

                    if (r != null) {
                        r.run();
                    }
                }
            }
        });
    }
}

Edit: No modifier shortcuts was fixed in Java 9. Given the popularity of JDK 8 right now, we should probably provide some backwards capatability or request users update there JRE to 9+.

查看更多
登录 后发表回答