JavaFX-当textfield有焦点时加速器不工作

JavaFX-当textfield有焦点时加速器不工作,java,javafx,javafx-8,accelerator,Java,Javafx,Javafx 8,Accelerator,在我的应用程序中,我有一个使用加速器的屏幕。我正在使用功能键F3在我的应用程序中执行一个操作。每次都可以正常工作,但当我点击屏幕上的任何文本字段时,功能键不会执行 下面是我设置加速器的代码: scene.getAccelerators().put( new KeyCodeCombination(KeyCode.F3), new Runnable() { @Override pu

在我的应用程序中,我有一个使用加速器的屏幕。我正在使用功能键F3在我的应用程序中执行一个操作。每次都可以正常工作,但当我点击屏幕上的任何文本字段时,功能键不会执行

下面是我设置加速器的代码:

    scene.getAccelerators().put(
            new KeyCodeCombination(KeyCode.F3),
            new Runnable() {
                @Override
                public void run() {
                    // do sth here
                }
            }
    );
当我点击我的文本字段,然后点击F3功能键时,它不起作用。
有人知道解决方案吗?

这对我使用Java 1.8.0\u 45很有效。但是,我在可编辑的组合框字段中遇到了类似的问题

编辑:

经过进一步的调查,它似乎也发生在文本字段中。我使用以下自定义类代替文本字段来解决此问题:

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();  
                }
            }
        }); 
    }
}
公共类ShortcutFriendlyTextField扩展了TextField{
public ShortcutFriendlyTextField(){
超级();
addEventHandler(KeyEvent.KEY_已发布,新的EventHandler(){
@凌驾
公共无效句柄(KeyEvent事件){
//处理快捷方式(如果已定义)
Runnable r=getScene().getAccelerators().get(新的KeyCodeCombination(event.getCode());
如果(r!=null){
r、 run();
}
}
}); 
}
}
此答案基于的。我添加了处理修改键的代码

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()]));
}
if(!event.getCode().isModifierKey()){
使用者运行加速器=(修饰符)->{
Runnable r=getScene().getAccelerators().get(新的KeyCodeCombination(event.getCode(),modifiers));
如果(r!=null){
r、 run();
}
};
列表修饰符=新的ArrayList();
if(event.isControlDown())modifiers.add(KeyCodeCombination.CONTROL\u DOWN);
if(event.isShiftDown())modifiers.add(KeyCodeCombination.SHIFT\u DOWN);
if(event.isAltDown())modifiers.add(KeyCodeCombination.ALT_DOWN);
运行accelerator.apply(modifiers.toArray(新的KeyCombination.Modifier[modifiers.size()]);
}

编辑:修复消费者拼写

如果在其他位置(如菜单栏)设置了加速器,则使用某些其他解决方案将导致快捷方式执行两次

在我的例子中,将修改器与我的快捷方式(SHIFT+F3)一起使用在文本区域中处于焦点时有效,但在仅使用诸如F3之类的加速器时无效

我将我的设置为仅对不使用修饰符的快捷方式使用事件处理程序

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();
                    }
                }
            }
        });
    }
}
公共静态final double JAVA_VERSION=double.parseDouble(System.getProperty(“JAVA.specification.VERSION”); 公共静态void makeInputFieldShortCutFriendly(节点){ //这个错误直到9.0才被修复 如果(JAVA_版本<9){ node.addEventHandler(KeyEvent.KEY_已释放,(KeyEvent事件)->{ 如果(!event.getCode().isModifierKey()){ 如果(!event.isAltDown()&&&!event.isShiftDown()&&!event.isAltDown()){ Runnable r=node.getScene().getAccelerators().get(新的KeyCodeCombination(event.getCode(),KeyCodeCombination.SHORTCUT_ANY)); 如果(r!=null){ r、 run(); } } } }); } }
编辑:Java9中没有修复任何修改器快捷方式。鉴于目前JDK 8的流行,我们可能应该提供一些向后的功能,或者请求用户将JRE更新到9+。

这看起来很有趣,但代码正确吗?
修饰符
变量似乎是在定义之前使用的?此外,该准则的目的是什么?即使在更简单的版本中,我的带有修改器的加速器似乎也可以正常工作(用JavaFX8测试)。我对修改器的看法是错误的-在其他代码中,它们处理得不好,修改器键本身在试图处理其发布时会引发异常。我仍然确信代码的顺序是错误的。@Suma第一个
修饰符
变量是lambda表达式的参数。换句话说,它是runAccelerator对象的本地对象。它不是指定义为
列表的那一个。谢谢你的解释,我现在明白了。请参阅此问题,以获得不需要修改控件的更好答案:似乎在fx9中已修复,也就是说,如果textField是焦点,加速器(在菜单中并手动安装)正在工作。问题似乎在fx9中已修复,也就是说,如果textField处于焦点位置,加速器(在菜单中并手动安装)正在工作