4

可以将上下文菜单添加到滚动窗格,但不能添加到其他类型的窗格。为什么?

4

2 回答 2

5

FXML 的工作原理

FXML 通过使用反射(或使用专门的构建器类)对 Java API 进行内省来工作。有关 FXML 作品的更多信息,请参阅 FXML简介文档。

为什么不能使用 FXML 标记在 JavaFX 的窗格上定义 ContextMenus

控件有一个contextMenu 属性ScrollPane是一个控件。其他窗格类型(例如StackPane)不是控件。由于在这些其他窗格类型中没有相应的属性可以设置为包含对 contextMenu 的引用,因此您无法使用 FXML 在这些窗格类型上定义 contextMenu。

出于类似的原因,您也不能在窗格上定义工具提示。

如何为 FXML 控制器中的窗格定义 ContextMenu

您仍然可以使用 contextMenu show API 通过代码在窗格(以及任何其他非控件的任意节点)上设置上下文菜单,例如通过将以下代码放置在 FXML 控制器中。

@FXML StackPane stack;

// . . .

public void initialize() {
    final ContextMenu contextMenu = new ContextMenu(new MenuItem("xyzzy"));
    stack.setOnMouseClicked(new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent mouseEvent) {
            contextMenu.show(
                    stack,
                    mouseEvent.getScreenX(), 
                    mouseEvent.getScreenY()
            );
        }
    });
}

为什么不添加 ContextMenu 属性

节点可以有一个 contextMenu 属性,这将允许通过 FXML 标记在窗格上定义 ContextMenus。

Node没有 contextMenu 属性而 Control 有的原因是因为 ContextMenu 本身就是一个 Control 。将 ContextMenu 属性添加到节点意味着 JavaFX 实现的核心场景图模型代码将依赖于控制模块(它将依赖于场景图模块),因此是循环依赖。这将阻止发布包含核心 JavaFX 场景图和渲染引擎但不包含控件的非常轻量级的 Java 运行时系统(不是今天有人发布这样的系统)。

如何提交功能请求

如果您认为应该更改系统以允许使用 SceneBuilder 在任意窗格上定义上下文菜单,那么您可以针对 JavaFX 问题跟踪器提交功能请求(如果这样做,请在功能请求中包含返回此问题的链接) .

于 2013-10-22T23:33:43.763 回答
1

如果场景图中的每个节点都想打开上下文菜单,则所描述的打开弹出窗口的方法会导致打开多个弹出窗口。绝对需要消费事件。

另请参阅Using FXML to Create ContextMenu within a Pane 中的讨论它为这个问题提供了有效的答案。

顺便说一句,应该改用 Node.onContextMenuRequested(...) ,是吗?

于 2013-11-13T13:25:56.953 回答