从编辑控件传递上下文菜单快捷方式 [英] Pass Context menu shortcuts up from editing control

查看:124
本文介绍了从编辑控件传递上下文菜单快捷方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个JavaFX窗格(TabPane,如果重要的话),并带有与之关联的上下文菜单。上下文菜单中定义了一些快捷键(F2,F3),实际上当按下它们时,会执行正确的操作。
但是,当在TextField或ComboBox中时,完全忽略快捷键。

I have a JavaFX pane (TabPane, if it matters) with a context menu associated with it. The context menu has a few shortcut keys (F2, F3) defined in it, and indeed when they are pressed the correct action is performed. However, when inside a TextField or ComboBox the shortcut keys are completely ignored.

为什么会发生这种情况,我该如何克服这个问题?
如果可能,我想避免为每个控件设置onKeyPressed。

Why is this happening, and how can I overcome this? If possible, I would like to avoid setting "onKeyPressed" for every single control.

(编辑:显然它是具有ContextMenu的TabPane。我无法理解正常Panes的一些原因不能有上下文菜单,但TabPane是一个控件。不知道它是否有任何变化)

( Apparently it is the TabPane that has the ContextMenu. For some reason which I can't fathom normal Panes can't have context menus, but TabPane is a Control. Don't know if it changes anything)

编辑:提供是一个最小的例子:

Provided is a minimal example:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Example extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {

        VBox vbox = new VBox();
        vbox.getChildren().add(new TextField());

        TabPane tp = new TabPane();
        Tab t = new Tab("foo");
        t.setContent(vbox);

        tp.getTabs().add(t);

        ContextMenu cm = new ContextMenu();
        MenuItem mi = new MenuItem("Action");
        mi.setAccelerator(KeyCombination.keyCombination("F2"));
        mi.setOnAction(ev->{ System.out.println("Action!"); });
        cm.getItems().add(mi);

        tp.setContextMenu(cm);
        Scene sc = new Scene(tp);

        stage.setScene(sc);

        stage.show();
    }
}

请注意按 F2 虽然在TextField中没有做任何事情,但在不在里面时按下它会打印出动作!

Note that pressing F2 while inside the TextField does nothing, while pressing it while not inside it prints out "Action!"

推荐答案

我找到了这个问题的迂回解决方案:
在TabPane上添加 EventFilter - 即使编辑控件具有焦点,这也会触发:

I have found this roundabout solution to the problem: Add an EventFilter on the TabPane - this fires even when an editing control has focus:

tabPane.addEventFilter(KeyEvent.KEY_PRESSED, this::keyPressed);

将此用作 keyPressed 函数:

private void keyPressed(KeyEvent event) {
  for (MenuItem mi : tabPane.getContextMenu().getItems())
     {
        if (mi.getAccelerator()!=null && mi.getAccelerator().match(event))
        {
            mi.getOnAction().handle(null);
            event.consume();
            return;
        }
    }
}

消费事件,所以如果没有选择编辑控件,它将不会被触发两次。
如果您有嵌套菜单,这显然不起作用,但在我的情况下,它是一个平面上下文菜单。

It is important to consume the event, so in case no editing control is selected it won't get fired twice. This obviously won't work if you have nested menus, but in my case it is a flat context menu.

如果这个解决方案有任何可怕的错误,或者解决这个问题的方法更直接 - 请告诉我!

If there is anything horribly wrong with this solution, or a more straightforward way to solve this problem - please let me know!

编辑:可能需要将!mi.isDisable()添加到触发条件,以避免触发禁用事件菜单项。

Edit: It may be desirable to add !mi.isDisable() to the firing condition, to avoid firing events for disabled menu items.

这篇关于从编辑控件传递上下文菜单快捷方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆