The MenuWidget class and its associated FXML file are entirely self-contained. You aren't including anything there and you are not adding any children to the StackPane. In other words, this:
public class MenuWidget extends VBox implements Initializable { @FXML StackPane menus; public MenuWidget() { FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/resources/MenuWidget.fxml")); fxmlLoader.setRoot(this); fxmlLoader.setController(this); try { fxmlLoader.load(); } catch (IOException exception) { throw new RuntimeException(exception); } } @Override public void initialize(URL location, ResourceBundle resources) { System.out.println(menus.getChildren().size()); } }
Loads this:
<fx:root type="javafx.scene.layout.VBox" prefWidth="300.0" xmlns:fx="http://javafx.com/fxml/1"> <StackPane fx:id="menus"> <padding> <Insets top="5" left="5" bottom="5" right="5"></Insets> </padding> </StackPane> </fx:root>
And once it's finished with that, the initialize method is invoked. Nothing there added anything to menus so the result of calling menus.getChildren().size() is of course 0.
Somewhere else you are loading this:
<MenuWidget> <menus> <fx:include source="FirstMenu.fxml" /> <fx:include source="SecondMenu.fxml" /> </menus> </MenuWidget>
Which causes a MenuWidget to be instantiated, which involves calling the MenuWidget#initialize method, and then attempts to add children to menus. To put it another way, if this was valid and working FXML, then the children would be added after the MenuWidget instance was created and initialized.
However, the <menus> element should be causing your application to throw an exception. The MenuWidget class does not define a read-only list property named menus. If you want to uses <menus>, and you want elements of that list to be added to the children of the menus stack pane, then modify your MenuWidget class to be:
public class MenuWidget extends VBox implements Initializable { @FXML StackPane menus; public MenuWidget() { FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/resources/MenuWidget.fxml")); fxmlLoader.setRoot(this); fxmlLoader.setController(this); try { fxmlLoader.load(); } catch (IOException exception) { throw new RuntimeException(exception); } } @Override public void initialize(URL location, ResourceBundle resources) { System.out.println(menus.getChildren().size()); } // add read-only list property (the "property" is read-only, not // the list itself) named "menus" public final ObservableList<Node> getMenus() { return menus.getChildren(); } }
But that seems conceptually wrong (at least to me). I'm not exactly sure what you're trying to do, but maybe you should be fx:include-ing the other FXML files directly into the MenuWidget FXML file, rather than what you're currently doing. That way you could inject the controllers and/or views (see nested controllers) into the MenuWidget class. I'm also not sure if the use of fx:root is entirely warranted in this case, based on what you've shown us. Inheriting from VBox does not seem to be adding any benefit to your code (i.e. you're not adding any functionality)—especially since you're only adding a single child to it (then adding children to that child). Perhaps a standard FXML file + controller would be more appropriate.
initialize, and after that's done, do your println again and see what happensMenuWidgetclass does not define any list property namedmenus, so the<menus>element in the FXML file should be causing errors.MenuWidget.initialize()is invoked during the process of loadingMenuWidget.fxml, which happens during theMenuWidgetconstructor call (which is before items are added to the menu list). Yourinitializemethod could add a listener tomenus.getChildren()and update whatever it is you need to update as items are added (note, though, that you can't modify the samemenus.getChildren()list in such a listener). This just might not be the right solution at all; it's difficult to know without more details of what you're trying to achieve.