我正在为我的应用程序进行自定义样式。我目前的问题源于设计师为菜单栏和菜单项指定了完全不同的样式。我实现了按钮样式,但是菜单弹出窗口现在稍微覆盖了按钮本身(包括按钮标签),这很难看。
有没有办法控制菜单弹出窗口相对于菜单栏按钮的位置?实际定位这些弹出窗口的代码在哪里?我搜索了JavaFX源代码,但是javafx.scene.control.Menu
类不处理任何与上下文菜单相关的东西——似乎菜单逻辑发生在一些完全不同的地方。
我相信菜单中的弹出窗口是通过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
的子类并覆盖该方法。
一种可能的解决方案是将MenuButtonSkinBase
和MenuButtonSkin
中的代码复制粘贴到您自己的文件中(大约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);
}
}