是否有可能将工具提示添加到JavaFX(Sub-)菜单?
MenuItems的通常(但很丑陋-为什么菜单不能仅由节点组成?!)解决方案是使用CustomMenuItem并在其中放置标签(即Node)-可以分配标签工具提示。
但是如何为(子)菜单实现此目的?请参见以下示例:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.stage.Stage;
public class CustomSubMenu extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
MenuButton menuButton = new MenuButton("Menu");
Label helloLabel = new Label("Hello...");
helloLabel.tooltipProperty().setValue(new Tooltip("World!"));
menuButton.getItems().add(new CustomMenuItem(helloLabel));
Menu submenu = new Menu("This Submenu needs a ToolTip!");
// new CustomMenuItem(new Menu()); // doesn't work, because Menu is not a Node.
submenu.getItems().add(new MenuItem("Some other Item"));
menuButton.getItems().add(submenu);
primaryStage.setScene(new Scene(menuButton));
primaryStage.show();
}
}
答案 0 :(得分:1)
每个menuItem(当然还有一个菜单)都与一个节点关联。该项目至少显示一次后,即可访问该节点。然后可以通过item.getStyleableNode()
访问该节点(因为fx9,关于fx8,请参见下文),并且可以在该节点上设置工具提示。
因此,基本上,方法是监听该瞬间,然后安装工具提示。下面的示例通过
基本片段:
String tooltipKey = "TOOL_TIP";
MenuItem normalItem = new MenuItem("Good .. ");
normalItem.getProperties().put(tooltipKey, new Tooltip("Morning!"));
menuButton.getItems().add(normalItem);
Menu submenu = new Menu("This Submenu needs a ToolTip!");
submenu.getProperties().put(tooltipKey, new Tooltip("It's meee!"));
menuButton.setOnShown(e -> {
menuButton.getItems().forEach(item -> {
Node node = item.getStyleableNode();
if (node != null && item.getProperties().get(tooltipKey) instanceof Tooltip) {
Tooltip tip = (Tooltip) item.getProperties().get(tooltipKey);
Tooltip.install(node, tip);
}
});
});
对于fx8,基本方法是相同的-但是访问表示menuItem的节点是令人讨厌的(请注意:请勿在生产中!*咳嗽..):
代码段:
// not working - what's wrong?
menuButton.addEventHandler(MenuButton.ON_SHOWN, e -> {
LOG.info("not getting here?");
// install tooltips here
});
ChangeListener<Skin> skinListener = (src, ov, skin) -> {
ContextMenuContent content = (ContextMenuContent) skin.getNode();
VBox menuBox = (VBox) content.getChildrenUnmodifiable().get(0);
menuBox.getChildren().forEach(node -> {
// implementation detail: the menuItem is set in the node's properties
if (node.getProperties().get(MenuItem.class) instanceof MenuItem) {
MenuItem item = (MenuItem) node.getProperties().get(MenuItem.class);
if (node != null && item.getProperties().get(tooltipKey) instanceof Tooltip) {
Tooltip tip = (Tooltip) item.getProperties().get(tooltipKey);
Tooltip.install(node, tip);
}
}
});
};
menuButton.showingProperty().addListener((src, ov, nv) -> {
ContextMenu popup = submenu.getParentPopup();
if (popup != null) {
if (popup.getSkin() == null) {
popup.skinProperty().addListener(skinListener);
} else {
popup.skinProperty().removeListener(skinListener);
}
}
});
答案 1 :(得分:0)
我想出了一种简单的方法来欺骗 MenuItem 作为控件 Label 节点,并使用如下代码:
Label lb=new Label("MenuItem Text");
lb.setStyle("-fx-text-fill:black;");
MenuItem myMenuItem = new MenuItem(null, lb);
Tooltip tips = new Tooltip("Your tip text here");
Tooltip.install(myMenuItem.getGraphic(), tips);
将工具提示设置为标签,这对我来说很好。