提问者:小点点

有没有办法控制JavaFX 8中的菜单弹出位置?


我正在为我的应用程序进行自定义样式。我目前的问题源于设计师为菜单栏和菜单项指定了完全不同的样式。我实现了按钮样式,但是菜单弹出窗口现在稍微覆盖了按钮本身(包括按钮标签),这很难看。

有没有办法控制菜单弹出窗口相对于菜单栏按钮的位置?实际定位这些弹出窗口的代码在哪里?我搜索了JavaFX源代码,但是javafx.scene.control.Menu类不处理任何与上下文菜单相关的东西——似乎菜单逻辑发生在一些完全不同的地方。


共3个答案

匿名用户

我相信菜单中的弹出窗口是通过ContextMenu(与右键菜单相同)完成的。您还可以使用CSS更改位置。您还可以使用ScenicView和SceneBuilder广泛调试您的GUI并找到适当的CSS路径(如果您还没有这样做)。

相关的css类可以在这里找到如何在CSS中设置JavaFX菜单及其项目的样式?并且可以使用填充和边距来移动上下文菜单。

看看默认的CSS风格叫做摩德纳。第1166行是菜单内容的开始。

希望这有帮助。

更新:

事实证明,上下文菜单弹出在菜单按钮的底部。据我所知,没有办法通过CSS移动实际节点。

这意味着,因为它对你来说是重叠的,菜单按钮没有你的菜单栏那么大,如果你让它和你的菜单栏一样大(就像我在图片中所做的那样),它将完美地显示在菜单栏下。

如您所见,我没有在菜单栏上使用填充,而是在菜单按钮上使用它。这将自动调整菜单栏的大小并导致上下文菜单完美弹出。

我还删除了颜色,以向您展示如果您删除颜色,它是完全透明的。

-fx-effect: null;还删除了默认的阴影效果。如果您想对此进行更广泛的控制,您将需要实现自己的菜单按钮和自己的上下文菜单。只有这样,您才能完全控制。

匿名用户

显示弹出窗口的实际代码位于MenuButtonSkinBase中:

private void show() {
    if (!popup.isShowing()) {
        popup.show(getSkinnable(), getSkinnable().getPopupSide(), 0, 0);
    }
}

popup.show的最后两个参数是popup的X和Y偏移量。不幸的是,由于某种原因,方法被标记为私有,因此无法简单地创建MenuButtonSkin的子类并覆盖该方法。

一种可能的解决方案是将MenuButtonSkinBaseMenuButtonSkin中的代码复制粘贴到您自己的文件中(大约300行代码)并在那里调整方法。之后,您将能够执行:

menuButton.setSkin(new TweakedMenuButtonSkin(menuButton));

匿名用户

您不需要复制整个皮肤。如果您扩展皮肤,您可以相当容易地更改它(即使该方法是私有的)。只需复制粘贴以下内容……(在“显示”方法中将位置更改为您想要的任何位置)

@Override
protected void handleControlPropertyChanged(String p) {
    if ("SHOWING".equals(p)) {
        if (getSkinnable().isShowing()) {
            show();
        } else {
            super.handleControlPropertyChanged(p);
        }
    } else {
        super.handleControlPropertyChanged(p);
    }
}


private void show() {
    if (!popup.isShowing()) {
        popup.show(getSkinnable(), getSkinnable().getPopupSide(), 100, 100);
    }
}