我需要一个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
来查看是否为当前项目设置了图形。控制台中的结果:具有相同ImageView
:的两行(MenuItem)
ImageView@79814766[styleClass=image-view]
ImageView@79814766[styleClass=image-view]
我在Swing中做了完全相同的操作(但使用了Icons
和.setIcons()
函数),它运行得非常好。我还寻找了一个"重新绘制"功能来强制显示,但没有办法。
希望你能帮助我!
这是因为同一个Node
不能多次附加到场景图,而且正如您所说,您添加的是同一ImageView
对象。
来自Node的文档:
如果程序将子节点添加到父节点(包括组、区域等),等等),并且该节点已经是不同Parent或场景的根,节点会自动(并且静默地)从其前母公司。
解决方案是修改IconFactory
的getImage
方法,在每次调用时返回一个新的ImageView
实例,或者返回Image
实例而不是ImageView
实例(我认为第二个更适合"IconFactory"这个名称)。
您可以存储Image
实例,而不是存储ImageView
,以避免重新加载Image
本身。您可以将此问题作为参考:在JavaFX 上的同一场景中多次重复使用同一ImageView
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);
}
}
更新后的使用:
subMenuHelp.setGraphic(new ImageView(IconFactory.getImage(ICONS.HLP_BOOK)));