2015-11-30 116 views
0

我想要一個帶有多個選項卡的TabPane,並且每個選項卡的上下文菜單都不相同。JavaFX:TabPane上下文菜單,取決於選定的選項卡

在TabPane上設置ContextMenu顯然會導致使用相同的ContextMenu而不管選定的選項卡。我試着設置不同的選項卡不同ContextMenus,但這樣做有兩個有害的影響:

  1. 當在選項卡標題右擊(而將其設置在TabPane可以右擊任何地方內的上下文菜單隻開該選項卡)。我希望用戶能夠從標籤內的任何地方訪問上下文菜單,而不僅僅是標題。

  2. 右鍵單擊一個選項卡標題,而選擇另一個選項卡仍然會打開點擊選項卡的上下文菜單 - 我想要上下文菜單取決於當前選定的選項卡。

我能想到的是如何做的唯一的辦法是捕捉onContextMenuRequested,看哪個選項卡當前選擇,並設置不同的MenuItems可見/不可見,但似乎非常愚蠢的。有沒有更好的方法來做到這一點?

編輯:Calrification - 標籤內容是窗格(VBox,GridPane等),所以直接在內容上設置ContextMenu是不可能的。

+0

爲什麼不設置選項卡內容的上下文菜單? –

+0

@James_D啊,我應該提到 - 標籤內容是一個窗格(通常是VBox或GridPane),並且JavaFX不允許在窗格上使用ContextMenu(僅在控件上) – Itai

+0

您可以在任何節點上使用上下文菜單。只需設置一個'comtextMenuRequested'處理函數並在上下文菜單 –

回答

1

我可以看到兩個解決方案。一種是在選項卡窗格上設置一個上下文菜單。向選定的選項卡註冊偵聽器,並在選擇更改時重新填充上下文菜單。

另一種解決方案是隻設置標籤內容的上下文菜單。請注意,您可以在任何節點上設置上下文菜單,方法是註冊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); 
    } 
} 
相關問題