JavaFX上下文菜单加速器从错误选项卡触发

JavaFX上下文菜单加速器从错误选项卡触发,javafx,tabs,contextmenu,javafx-8,Javafx,Tabs,Contextmenu,Javafx 8,我有一个带有两个选项卡的TabPane,每个选项卡都有一个带有上下文菜单的TableView。这两个上下文菜单有重复的加速器,但我希望只有当前选择的选项卡会响应。但所发生的只是最后添加的选项卡似乎得到了事件,即使它没有被选中。 下面是完整的示例代码: package sample; import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.*; import jav

我有一个带有两个选项卡的
TabPane
,每个选项卡都有一个带有上下文菜单的
TableView
。这两个上下文菜单有重复的加速器,但我希望只有当前选择的选项卡会响应。但所发生的只是最后添加的
选项卡
似乎得到了事件,即使它没有被选中。 下面是完整的示例代码:

package sample;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.input.KeyCombination;
import javafx.stage.Stage;

public class Main extends Application {

@Override
public void start(Stage primaryStage) throws Exception{
    Tab t1 = new Tab("Tab 1");
    TableView<Void> tv1 = new TableView<>();
    t1.setContent(tv1);
    MenuItem mi1 = new MenuItem("Action 1");
    mi1.setAccelerator(KeyCombination.valueOf("F3"));
    mi1.setOnAction(event->System.out.println("Action 1!"));
    ContextMenu ctx1 = new ContextMenu(mi1);
    tv1.setContextMenu(ctx1);

    Tab t2 = new Tab("Tab 2");
    TableView<Void> tv2 = new TableView<>();
    t2.setContent(tv2);
    MenuItem mi2 = new MenuItem("Action 2");
    mi2.setAccelerator(KeyCombination.valueOf("F3"));
    mi2.setOnAction(event->System.out.println("Action 2!"));
    ContextMenu ctx2 = new ContextMenu(mi2);
    tv2.setContextMenu(ctx2);

    TabPane tabPane = new TabPane(t1, t2);
    tabPane.setTabClosingPolicy(TabPane.TabClosingPolicy.UNAVAILABLE);
    primaryStage.setScene(new Scene(tabPane));
    primaryStage.show();
}


public static void main(String[] args) {
    launch(args);
}
}
包装样品;
导入javafx.application.application;
导入javafx.scene.scene;
导入javafx.scene.control.*;
导入javafx.scene.input.KeyCombination;
导入javafx.stage.stage;
公共类主扩展应用程序{
@凌驾
public void start(Stage primaryStage)引发异常{
表t1=新表(“表1”);
TableView tv1=新的TableView();
t1.设置内容(tv1);
MenuItem mi1=新MenuItem(“操作1”);
mi1.设置加速器(键组合.valueOf(“F3”));
设置操作(事件->系统.out.println(“操作1!”);
ContextMenu ctx1=新的ContextMenu(mi1);
tv1.setContextMenu(ctx1);
表t2=新表(“表2”);
TableView tv2=新的TableView();
t2.设置内容(tv2);
MenuItem mi2=新MenuItem(“操作2”);
mi2.设置加速器(键组合.valueOf(“F3”));
设置操作(事件->系统.out.println(“操作2!”);
ContextMenu ctx2=新的ContextMenu(mi2);
tv2.设置上下文菜单(ctx2);
TabPane TabPane=新的TabPane(t1,t2);
tabPane.setTabClosingPolicy(tabPane.TabClosingPolicy.UNAVAILABLE);
设置场景(新场景(选项卡窗格));
primaryStage.show();
}
公共静态void main(字符串[]args){
发射(args);
}
}
我希望在选择选项卡1时打印“操作1!”,在选择选项卡2时打印“操作2!”,但实际上,无论选择哪个选项卡,都会打印“操作2!”。
我如何解决这个问题,以便根据当前可见的选项卡(TableView)执行正确的操作?

我想您已经遇到了(请参见此处了解解决方法)。JavaFX并没有为在多个菜单中安装同一个加速器做好准备。

hmm。。每个应用程序的加速器都是唯一的(不过,afaik并不完全确定)。一种解决方法可能是在选项卡窗格的选择侦听器中设置/取消设置菜单项上的加速器。谢谢@kleopatra,我担心可能是这样的。你有这方面的链接或消息来源吗?我试图找到一些关于加速器如何在JavaFX中工作的东西,但找不到任何简洁的东西。不,我还没有遇到这个问题。我会调查的。有时候,看到JavaFX是多么的落后让人沮丧。好吧,链接中建议的解决方法似乎已经解决了我的问题。事实上,一个bug——我错误地期望在contextMenu中每个应用程序都有一个唯一的加速器;-)这是一个很好的解决办法!是否使用释放或按下事件可能取决于操作系统-在win7上,我必须使用按下。好奇:为什么要搜索聚焦节点(而不是使用scene.getFocusOwner)?@sillyfly否,没有现成的内容:调用someControl.setContextMenu(..)时注册contextMenu菜单项的加速器。我想不出一种方法可以在任何时候注销所有其他绑定(不知道它们)。