从编辑控件传递上下文菜单快捷方式

时间:2015-07-30 19:37:07

标签: java user-interface javafx

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

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

(编辑:显然是TabPane有ContextMenu。由于某种原因,我无法理解普通Panes不能有上下文菜单,但TabPane是一个控件。不知道它是否改变了什么)< / p>

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

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();
    }
}

请注意,在TextField内部按F2不会执行任何操作,而在不在内部时按下它会打印出“操作!”

1 个答案:

答案 0 :(得分:1)

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

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;
        }
    }
}

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

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

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