2016-05-16 65 views
0

我正在写一个带有TreeView的桌面应用程序,根据这里的Oracle示例:https://docs.oracle.com/javafx/2/ui_controls/tree-view.htmJavaFX MenuItem对MouseEvent.CLICKED没有反应

从ContextMenu的MenuItem动作中,我想触发一个事件,该事件将在打开ContextMenu的项目下创建一个新的TreeItem。

对于MenuItem,可以使用setOnAction(EventHandler<ActionEvent> event)方法,但我只想通过鼠标左键点击该操作。

首先,尽管它为方法addEventHandler(EventType type, EventHandler<EventType> handler)提供了事件类型MouseEvent.ANY(或其他),但不能将EventHandler添加到MenuItem。不调用事件处理程序的句柄方法。

其次,我可以通过在菜单项上添加一个标签0123'并添加一个EventHandler到标签来使用workarround。虽然MouseEvent.MOUSE_CLICKED不是由EventHandler的标签上的句柄方法调用的,但它可以工作。

这是“正常的”行为吗?我知道标签不会对点击事件做出反应,但我不明白为什么无法在MenuItem上注册单独的EventHandler或EventFilter。

回答

1

ContextMenu使用MenuItemContainer,这是一个

容器负责在菜单布局单行 - 在其他 的话,这包含并制定出一个菜单项,无论它是 亚型特异。

皮草这一目的似乎创造新Nodes代表MenuItem。因此,将不会调用添加到MenuItem的任何EventHandlers

为了让你预期它的工作,你可以使用一个CustomMenuItem,并添加按照EventHandlercontent

public class ContextMenuCell extends TreeCell<String> { 

     private ContextMenu menu; 

     public ContextMenuCell() { 
      Label lbl = new Label("Add item"); 
      MenuItem menuItem = new CustomMenuItem(lbl); 

      lbl.setOnMouseClicked(evt -> { 
       if (evt.getButton() != MouseButton.PRIMARY) { 
        return; 
       } 

       TreeItem treeItem = 
         new TreeItem<String>("New item"); 

       if (getTreeItem().isLeaf()) { 
        getTreeItem().getParent().getChildren().add(getIndex(), treeItem); 
       } else { 
        getTreeItem().getChildren().add(0, treeItem); 
       } 

      }); 

      menu = new ContextMenu(menuItem); 
     } 

     @Override 
     public void updateItem(String item, boolean empty) { 
      super.updateItem(item, empty); 

      if (empty) { 
       setText(null); 
       setGraphic(null); 
      } else { 
       setText(item); 
       setGraphic(getTreeItem().getGraphic()); 
       setContextMenu(menu); 
      } 
     } 
    } 
+0

您的解决方案也适用于我,谢谢。看起来这个API并不是100%清晰的,因为packackge javafx.scene.control中的许多控件都可以处理单独的EventHandler和EventFilter。 – Supahupe