2013-05-28 29 views
4

我正在编写一个javafx UI,并希望从被单击的MenuItem的eventHandler中获取contextMenu的所有者节点。Javafx 2.0 - 在EventHandler中获取ContextMenu父节点

我的代码:

TabPane tabPane = new TabPane(); 
Tab tab1 = new Tab(); 
Tab tab2 = new Tab(); 

tabPane.getTabs().addAll(tab1,tab2); 

ContextMenu contextMenu = new ContextMenu(); 
MenuItem menuItem = new MenuItem("Do Some Action"); 

menuItem.setOnAction(new EventHandler<ActionEvent>(){ 
    @override 
    public void handle(ActionEvent e){ 
     // Get the tab which was clicked on and do stuffs with it 
    } 
}); 

contextMenu.getItems().add(menuItem); 

for(Tab tab: tabPane.getTabs()){ 
    tab.setContextMenu(contextMenu); 
} 

我想这样做的就是到了它的文本菜单中选择的选项卡的参考。

我能得到什么似乎是菜单项的文本菜单用下面的代码手柄(ActionEvent的五)内部方法的菜单项事件处理程序的引用:

ContextMenu menu = ((ContextMenu)((MenuItem)e.getSource()).getParentPopup()); 

我的想法从那里是在菜单上使用ContextMenu的.getOwnerNode()方法,然后对该选项卡进行引用,但运行时我得到了一个我无法理解的项目的引用。

.getOwnerNode()返回的对象的toString()方法返回“TabPaneSkin $ TabHeaderSkin $ 3 @ 14f59cef”,我无法弄清楚它的含义。

我的方法是试图按照我的方式向上链,直到我到达节点正确或有一个完全不同的方法,这会更好地工作吗?

我需要的就是ContextMenu的功能,并且当点击MenuItem时,我需要引用选中ContextMenu的选项卡,以便我可以使用它进行很酷的操作。

回答

4
  1. 为每个选项卡创建一个ContextMenu。
  2. 使每个标签最终。
  3. 直接引用上下文菜单的菜单项事件处理程序中的最终选项卡。

下面的代码片段:

final Tab tab = new Tab("xyzzy"); 
ContextMenu contextMenu = new ContextMenu(); 
MenuItem menuItem = new MenuItem("Do Some Action"); 
menuItem.setOnAction(new EventHandler<ActionEvent>(){ 
    @Override public void handle(ActionEvent e){ 
    tab.setText("Activated by User"); 
    } 
}); 

每次用户右键点击一个选项卡标题,并选择“伯爵点击”菜单,相关标签的内容与计数更新迄今为止该标签计算的舔数。

clickcounter

这里是一个可执行样本:

import javafx.application.*; 
import javafx.event.ActionEvent; 
import javafx.event.EventHandler; 
import javafx.geometry.Pos; 
import javafx.scene.Scene; 
import javafx.scene.control.*; 
import javafx.stage.Stage; 

public class TabContext extends Application { 
    @Override public void start(Stage stage) { 
    TabPane tabPane = new TabPane(); 

    tabPane.getTabs().addAll(
     createTab("xyzzy", "aliceblue"), 
     createTab("frobozz", "blanchedalmond") 
    ); 

    stage.setScene(new Scene(tabPane)); 
    stage.show(); 
    } 

    private Tab createTab(String tabName, String webColor) { 
    final Label content = new Label("0"); 
    content.setAlignment(Pos.CENTER); 
    content.setPrefSize(200, 100); 
    content.setStyle("-fx-font-size: 30px; -fx-background-color: " + webColor + ";"); 

    final Tab tab = new Tab(tabName); 
    tab.setContent(content); 

    ContextMenu contextMenu = new ContextMenu(); 

    MenuItem menuItem = new MenuItem("Count Click"); 
    menuItem.setOnAction(new EventHandler<ActionEvent>(){ 
     @Override public void handle(ActionEvent e){ 
     content.setText(
      "" + (Integer.parseInt(content.getText()) + 1) 
     ); 
     } 
    }); 

    contextMenu.getItems().add(menuItem); 

    tab.setContextMenu(contextMenu); 

    return tab; 
    } 

    public static void main(String[] args) { Application.launch(args); } 
} 

交替使用匿名内部类这种方式,你可以创建一个事件处理程序子类与包括标签了解该事件处理是一个构造连接。

class TabContextMenuHandler implements EventHandler<ActionEvent> { 
    private final Tab tab; 

    TabContextMenuHandler(Tab tab) { 
    this.tab = tab; 
    } 

    @Override public void handle(ActionEvent event) { 
    tab.setText("Activated by User"); 
    } 
} 
+0

感谢您的快速反应和很好的解决方案。 – mcdonasm