在JavaFX8中是否有控制菜单弹出位置的方法?

在JavaFX8中是否有控制菜单弹出位置的方法?,java,javafx-8,Java,Javafx 8,我正在为我的应用程序定制样式。我目前的问题源于设计师为菜单栏和菜单项指定了完全不同的样式。我实现了按钮样式,但是菜单弹出现在稍微覆盖了按钮本身(包括按钮标签),这很难看 是否有一些方法可以控制相对于菜单栏按钮的菜单弹出位置?实际定位这些弹出窗口的代码在哪里?我搜索了JavaFX源代码,但是JavaFX.scene.control.Menu类没有处理任何与上下文菜单相关的内容-似乎菜单逻辑发生在完全不同的地方。我相信菜单中的弹出窗口已经完成(与右键单击菜单相同)。您还可以使用CSS更改位置。您还可

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


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

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

相关的css类可以在这里找到,填充和边距可以用来移动上下文菜单

查看名为Modena的应用程序。第1166行是菜单开始的地方

希望这有帮助

更新:

这是我的测试:

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

这意味着,由于菜单按钮与菜单栏重叠,因此菜单按钮没有菜单栏大,如果将其设置为菜单栏大(如图中所示),它将完全显示在菜单栏下

正如您所看到的,我在菜单按钮上使用填充,而不是在菜单栏上使用填充。这将自动调整菜单栏的大小,并使contextmenu弹出到位

我还删除了颜色,以显示如果删除颜色,它是完全透明的

正如你在这里看到的:


-fx效果:空还删除默认的阴影效果。如果您想更广泛地控制它,您需要实现自己的菜单按钮和上下文菜单。只有这样,您才能拥有完全的控制权。

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

private void show() {
    if (!popup.isShowing()) {
        popup.show(getSkinnable(), getSkinnable().getPopupSide(), 0, 0);
    }
}
弹出窗口的最后两个参数是弹出窗口的X和Y偏移量。不幸的是,由于某种原因,该方法被标记为private,因此不可能简单地创建
MenuButtonSkin
的子类并重写该方法

一种可能的解决方案是将粘贴代码从
MenuButtonSkinBase
MenuButtonSkin
复制到您自己的文件(大约300行代码)中,并调整其中的方法。之后,您将能够执行以下操作:

menuButton.setSkin(new TweakedMenuButtonSkin(menuButton));

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


是的,使用CSS将是理想的。但是怎么做呢?我知道-fx填充,但我在文档中的任何地方都找不到-fx保证金。-fx保证金实际上是插入的。例如,-fx背景插入。我相信这就是你想要使用的。我尝试了-fx背景插入,但没有帮助-弹出窗口仍然固定在原来的位置。通常当我找不到东西时,我会查看默认的CSS样式Modena。查看我的帖子,我已经添加了一个链接到你想要的东西。但是,应用-fx背景插图和-fx边框插图并没有帮助-我仍然在弹出窗口周围有白色边框。
@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);
    }
}