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