2016-07-26 77 views
1

我需要爲我的MenuItem的圖標。JavaFX setGraphic()不在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

[email protected][styleClass=image-view] 
[email protected][styleClass=image-view] 

我做了完全一樣的Swing中(但Icons.setIcons()功能)和它的工作非常出色。我還尋找「重繪」功能強制顯示,但沒辦法。

希望你能幫助我!

回答

3

這是因爲相同的Node不能附加到場景圖多次,甚至 - 你甚至說 - 你正在添加相同的ImageView對象。

documentation of Node

如果程序增加了一個子節點到父(包括集團,地區, 等),並在該節點已經是一個不同父母的孩子或 根的場景中,該節點自動(並且默默地)從其前母公司 中移除。

解決的辦法是修改IconFactorygetImage方法每次調用返回一個新的ImageView實例或返回Image實例,而不是ImageView實例(第二個適合更好的名字「IconFactory」我認爲)。

您可以存儲Image實例,而不是存儲ImageView以避免重新加載Image本身。更新後

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); 
    } 
} 

使用方法:你可以檢查這個問題作爲參考:Reusing same ImageView multiple times in the same scene on JavaFX

可能的更新上IconFactory

subMenuHelp.setGraphic(new ImageView(IconFactory.getImage(ICONS.HLP_BOOK))); 
+0

哦如此!非常感謝您的快速幫助。 因此,我更新了我的IconFactory,以便在每次調用時返回新的ImageView,並且完美地工作。 –