我需要MenuItem
的图标。
这就像获得图标ImageView
的“工人阶级”:
public class IconFactory {
private static ImageView HLP_BOOK_JFX;
public enum ICONS {
BASCET_REMOVE, BASCET_PUT, SAVE, OPEN, ARROW_RIGHT, ARROW_LEFT, ARROW_UP, ARROW_DOWN, CLOCK, ANALOG_SIGNAL, DIGITAL_SIGNAL, REFRESH, GREEN_PLUS, NETWORK, OK, CANCEL, RIGHT_NAV2, LEFT_NAV2, PLAY, PAUSE, LIST_ADD, PAGE_FIND, SET_PARAM, DOWNLOAD, UPLOAD, LOG_FILE, WARNING, INFO, LOG_DIAG, DATA_TRANS, TREE, FILTER, SEARCH, PARAM, ERASE, RESETDEF, RESETDEF2, DEBUG_BUG, INTERNATIONAL, CLOSE, HLP_BOOK
}
public static ImageView getImage(ICONS en) {
switch (en) {
case HLP_BOOK:
if (HLP_BOOK_JFX == null)
HLP_BOOK_JFX = new ImageView(new Image(IconFactory.class.getResourceAsStream("help_book.png")));
return HLP_BOOK_JFX;
}
return null;
}
当我使用myMenuItem.setGraphic(IconFactory.getImage(ICONS.HLP_BOOK))
作为单一菜单项时,效果非常好。
但是,当我想在循环中生成两个菜单并设置相同的图形时,一个MenuItem
没有显示图标。(下面代码中的第一个循环) )。
我的代码:
while (keys.hasMoreElements()) {
// that will do 2 loops, do not care about how
MenuItem subMenuHelp = new MenuItem("MenuItem");
subMenuHelp.setGraphic(IconFactory.getImage(ICONS.HLP_BOOK));
subMenuHelp.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
// do not care
openHelpFile(link);
}
});
System.out.println(((ImageView) subMenuHelp.getGraphic()).toString());
myMenu.getItems().add(subMenuHelp);
}
如您所见,我添加了System.out.println
以查看是否为当前项目设置了图形。
控制台中的结果:两行(MenuItem)具有相同的ImageView
:
ImageView@79814766[styleClass=image-view]
ImageView@79814766[styleClass=image-view]
我在Swing中完成了相同的操作(但使用Icons
和.setIcons()
功能)并且效果非常好。我也寻找一个“重绘”功能来强制显示,但没办法。
答案 0 :(得分:3)
这是因为同一个Node
无法多次附加到场景图上,而且 - 正如您所说的那样 - 您正在添加相同的ImageView
对象。
如果程序将子节点添加到父节点(包括组,区域, 等)并且该节点已经是不同父节点或子节点的子节点 在场景的根,自动(并静默)删除节点 它的前任父母。
解决方案是修改getImage
的{{1}}方法,以便在每次调用时返回新的IconFactory
实例,或返回ImageView
个实例而不是Image
个实例(第二个更适合我想的“IconFactory”这个名字。)
您可以存储ImageView
实例,而不是存储Image
,以避免重新加载ImageView
本身。您可以将此问题视为参考:Reusing same ImageView multiple times in the same scene on JavaFX
Image
的可能更新:
IconFactory
更新后的用法:
public class IconFactory {
private static HashMap<ICON, Image> images = new HashMap<ICON, Image>();
public enum ICON {
BASCET_REMOVE, BASCET_PUT, SAVE, OPEN, ARROW_RIGHT, ARROW_LEFT, ARROW_UP, ARROW_DOWN, CLOCK, ANALOG_SIGNAL, DIGITAL_SIGNAL, REFRESH, GREEN_PLUS, NETWORK, OK, CANCEL, RIGHT_NAV2, LEFT_NAV2, PLAY, PAUSE, LIST_ADD, PAGE_FIND, SET_PARAM, DOWNLOAD, UPLOAD, LOG_FILE, WARNING, INFO, LOG_DIAG, DATA_TRANS, TREE, FILTER, SEARCH, PARAM, ERASE, RESETDEF, RESETDEF2, DEBUG_BUG, INTERNATIONAL, CLOSE, HLP_BOOK
}
public static Image getImage(ICON en) {
if (!images.containsKey(en)) {
switch (en) {
case HLP_BOOK:
images.put(en, new Image(IconFactory.class.getResourceAsStream("help_book.png"))); break;
default:
return null;
}
}
return images.get(en);
}
}