Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaFX:TabPane上下文菜单,取决于所选选项卡_Java_User Interface_Javafx_Tabs - Fatal编程技术网

JavaFX:TabPane上下文菜单,取决于所选选项卡

JavaFX:TabPane上下文菜单,取决于所选选项卡,java,user-interface,javafx,tabs,Java,User Interface,Javafx,Tabs,我想要一个有多个选项卡的选项卡窗格,每个选项卡都有不同的上下文菜单 在TabPane上设置ContextMenu显然会导致使用相同的ContextMenu,而不考虑所选的选项卡。我尝试在不同的选项卡上设置不同的上下文菜单,但这有两个不必要的效果: 仅当右键单击选项卡标题时,关联菜单才会打开(而在选项卡窗格中设置它时,允许右键单击选项卡内的任何位置)。我希望用户能够从选项卡内的任何位置访问上下文菜单,而不仅仅是标题 在一个选项卡标题上单击鼠标右键,同时选择另一个选项卡标题,仍然会打开所单击选项卡的

我想要一个有多个选项卡的选项卡窗格,每个选项卡都有不同的上下文菜单

在TabPane上设置ContextMenu显然会导致使用相同的ContextMenu,而不考虑所选的选项卡。我尝试在不同的选项卡上设置不同的上下文菜单,但这有两个不必要的效果:

  • 仅当右键单击选项卡标题时,关联菜单才会打开(而在选项卡窗格中设置它时,允许右键单击选项卡内的任何位置)。我希望用户能够从选项卡内的任何位置访问上下文菜单,而不仅仅是标题

  • 在一个选项卡标题上单击鼠标右键,同时选择另一个选项卡标题,仍然会打开所单击选项卡的上下文菜单-我希望上下文菜单取决于当前选择的选项卡

  • 我能想到的唯一方法是捕获onContextMenuRequested,查看当前选择的选项卡,并设置各种MenuItems可见/不可见,但这似乎很愚蠢。有更好的方法吗


    编辑:Calrification-选项卡内容是窗格(VBox、GridPane等),因此无法直接在内容上设置ContextMenu

    我可以看到两种解决方案。一种是在选项卡窗格上设置一个上下文菜单。使用所选选项卡注册侦听器,并在选择更改时重新填充上下文菜单

    另一个解决方案就是在选项卡的内容上设置上下文菜单。请注意,通过注册
    contextMenuRequested
    事件的处理程序,可以在任何节点上设置上下文菜单,并显示上下文菜单。您可以在选项卡上设置相同的上下文菜单

    此示例演示了两种技术:

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    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.layout.HBox;
    import javafx.scene.layout.Pane;
    import javafx.stage.Stage;
    
    public class TabPanesWithContextMenu extends Application {
    
        @Override
        public void start(Stage primaryStage) {
            TabPane tabPane1 = new TabPane();
            ContextMenu contextMenu = new ContextMenu();
            tabPane1.setContextMenu(contextMenu);
    
            List<MenuItem> tab1Items = new ArrayList<>();
            tab1Items.add(new MenuItem("Choice 1"));
            tab1Items.add(new MenuItem("Choice 2"));
    
            List<MenuItem> tab2Items = new ArrayList<>();
            tab2Items.add(new MenuItem("Choice 3"));
            tab2Items.add(new MenuItem("Choice 4"));
    
            Tab tab1 = new Tab("Tab 1");
            tab1.setContent(new Pane());
            Tab tab2 = new Tab("Tab 2");
            tab2.setContent(new Pane());
            tabPane1.getTabs().addAll(tab1, tab2);
    
            Map<Tab, List<MenuItem>> itemsByTab = new HashMap<>();
            itemsByTab.put(tab1, tab1Items);
            itemsByTab.put(tab2, tab2Items);
    
            tabPane1.getSelectionModel().selectedItemProperty().addListener((obs, oldTab, newTab) -> 
               contextMenu.getItems().setAll(itemsByTab.get(newTab)) );
    
            contextMenu.getItems().addAll(tab1Items);
    
            TabPane tabPane2 = new TabPane();
    
            Tab tab3 =  createTabWithContextMenu("Tab 3", new MenuItem("Choice 5"), new MenuItem("Choice 6"));
            Tab tab4 =  createTabWithContextMenu("Tab 4", new MenuItem("Choice 7"), new MenuItem("Choice 8"));
    
            tabPane2.getTabs().addAll(tab3, tab4);
    
            HBox root = new HBox(10, tabPane1, tabPane2);
    
            primaryStage.setScene(new Scene(root, 600, 600));
            primaryStage.show();
        }
    
        private Tab createTabWithContextMenu(String title, MenuItem... items) {
            Tab tab = new Tab(title);
            ContextMenu contextMenu = new ContextMenu(items);
            tab.setContextMenu(contextMenu);
    
            Pane content = new Pane();
            content.setOnContextMenuRequested(e -> 
                contextMenu.show(content, e.getScreenX(), e.getScreenY()));
            tab.setContent(content);
    
            return tab ;
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    
    import java.util.ArrayList;
    导入java.util.HashMap;
    导入java.util.List;
    导入java.util.Map;
    导入javafx.application.application;
    导入javafx.scene.scene;
    导入javafx.scene.control.ContextMenu;
    导入javafx.scene.control.MenuItem;
    导入javafx.scene.control.Tab;
    导入javafx.scene.control.TabPane;
    导入javafx.scene.layout.HBox;
    导入javafx.scene.layout.Pane;
    导入javafx.stage.stage;
    公共类选项卡PanesWithContextMenu扩展应用程序{
    @凌驾
    公共无效开始(阶段primaryStage){
    TabPane tabPane1=新TabPane();
    ContextMenu ContextMenu=新建ContextMenu();
    tabPane1.setContextMenu(contextMenu);
    List tab1Items=new ArrayList();
    表1添加项目(新菜单项(“选择1”);
    表1添加项目(新菜单项(“选择2”);
    List tab2Items=new ArrayList();
    表2添加(新菜单项(“选项3”));
    表2添加项目(新菜单项(“选择4”);
    Tab tab1=新选项卡(“Tab 1”);
    tab1.setContent(新窗格());
    Tab tab2=新选项卡(“Tab 2”);
    tab2.setContent(新窗格());
    tabPane1.getTabs().addAll(tab1,tab2);
    Map itemsByTab=新HashMap();
    itemsByTab.put(表1,表1项);
    itemsByTab.put(表2,表2项);
    tabPane1.getSelectionModel().SelectEditeProperty().addListener((obs、oldTab、newTab)->
    contextMenu.getItems().setAll(itemsByTab.get(newTab));
    contextMenu.getItems().addAll(tab1Items);
    TabPane tabPane2=新TabPane();
    Tab tab3=createTabWithContextMenu(“tab3”、新菜单项(“选项5”)、新菜单项(“选项6”);
    Tab tab4=createTabWithContextMenu(“tab4”,新菜单项(“选项7”),新菜单项(“选项8”);
    tabPane2.getTabs().addAll(tab3,tab4);
    HBox根=新的HBox(10,tabPane1,tabPane2);
    原始阶段。设置场景(新场景(根,600600));
    primaryStage.show();
    }
    私有选项卡createTabWithContextMenu(字符串标题、菜单项…项){
    Tab Tab=新选项卡(标题);
    ContextMenu ContextMenu=新建ContextMenu(项目);
    tab.setContextMenu(contextMenu);
    窗格内容=新建窗格();
    content.setOnContextMenuRequested(e->
    show(content,e.getScreenX(),e.getScreenY());
    tab.设置内容(content);
    返回选项卡;
    }
    公共静态void main(字符串[]args){
    发射(args);
    }
    }
    
    为什么不在选项卡内容上设置上下文菜单?@James_D Ah,我应该提到-选项卡内容是一个窗格(通常是VBox或GridPane),JavaFX不允许在窗格上设置上下文菜单(仅在控件上)。您可以在任何节点上使用上下文菜单。只需设置一个
    comtextMenuRequested
    处理程序,并在context menuOk上调用
    show()
    ,这看起来像是一个可行的解决方法(可惜JavaFX没有更好的支持)。唯一的问题是,我需要重复使用它:在每个内容中,而不仅仅是在选项卡窗格上。当然,另一个选项是在
    选项卡窗格上使用单个上下文菜单,并在所选选项卡上使用侦听器更新上下文菜单的内容。