窗格上的上下文菜单正确消失

时间:2016-01-17 21:48:29

标签: java javafx contextmenu

我正在努力让JavaFX PaneVBox在我的情况下,但我认为不重要),ContextMenu行为正确。

我找到了这两个问题:why Panes can't have ContextMenusHow to create ContextMenu within a Pane

我对这两个解决方案(非常相似)的问题是,如果单击窗格,上下文菜单会正确消失,但如果我在该窗格中的控件内单击,它就不会消失。观察此缺陷的最简单方法是使用TextField创建此类窗格。右键单击窗格以显示上下文菜单,然后单击内部到TextField以关注它。虽然适当的上下文菜单会在此时消失,但这个“入侵”的上下文菜单(缺少一个更好的术语)很乐意保留在它的位置,可能会阻止用户查看他们试图填写的文本字段。

现在,我知道我可以在我的窗格上的每个控件的focused属性中添加一个更改侦听器,但这感觉多余。有没有更好的方法可以确保在选择窗格中的控件时隐藏上下文菜单(或者更准确地说 - 当用户在上下文菜单外的拥有窗口中的任意位置单击鼠标时)?

到目前为止我尝试了什么并且不起作用 -

  1. 向窗格的focused属性添加更改侦听器 - 如果其中一个子窗口
  2. ,则显示该窗格不会被视为焦点
  3. 在上下文菜单的focused属性中添加更改侦听器 - 单击外部菜单时,上下文菜单的焦点不会更改。

1 个答案:

答案 0 :(得分:3)

好的,所以在对JavaFX的源代码进行一些挖掘后,我发现了这种解决方法(这就是"解决了#34;正常控件的这个问题)。只需添加以下代码行 -

contextMenu.setImpl_showRelativeToWindow(true);

现在,我知道不鼓励使用内部实现方法,因为它们可能会消失,但这是我找到的唯一解决方案。如果有人有更好的解决方案,我会很高兴听到它,但我怀疑这只是一个应该提交的错误(即 - 应该有一种方法在设置上下文菜单时使用showRelativeToWindow机制在窗格上)。

我想一个更安全的解决方案是设置上下文菜单的一次性控制(不在场景图中),但我不知道这是否会产生任何不必要的副作用:

Label throwaway = new Label(); // No special reason for using Label, could be any Control. 
throwaway.setContextMenu(contextMenu); // note that this is the only place `throwaway` is used, it is never added to the scene graph 
                                       // or referenced again, but just setting the context menu on a control solves the problem.

修改
在挖掘了更多我发现this和讨论的解决方案之后 - 你应该调用show方法重载,它需要一个窗口,而不是一个节点!不是很清楚,但它有效:

myPane.setOnContextMenuRequested(event -> 
    contextMenu.show(myPane.getScene().getWindow(), event.getScreenX(), event.getScreenY())
);