user1406177
user1406177

Reputation: 1369

JavaFX - load FXML into FXML without include

I have a window created with FXML in the corresponding controller, I have a button, which loads a small box when a specific button is clicked. The box is designed using FXML as well.

When I load the box and want to add it into the window, I get this error:

javafx.fxml.LoadException: Root value already specified.
    at javafx.fxml.FXMLLoader.createElement(FXMLLoader.java:2362)
    at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2311)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2131)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2028)
    at com.clientgui.DataPage.openStaticData(DataPage.java:79)
...

And this is my code:

private void openStaticData(int dataObjectId, String titel)
{
    try
    {
        URL location = getClass().getResource("StaticDataBox.fxml");
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(location);
        loader.setBuilderFactory(new JavaFXBuilderFactory());
        loader.load();
        final Region page = (Region) loader.load();  //line 79

        StaticDataBox staticDataBox = (StaticDataBox) loader.getController();
        staticDataBox.setDataObjectId(dataObjectId);
        staticDataBox.setTitel(titel);

        Platform.runLater(new Runnable()
        {
            @Override
            public void run()
            {
                getChildren().add(page);
            }
        });

    } catch (IOException ex)
    {
        Logger.getLogger(DataPage.class.getName()).log(Level.SEVERE, null, ex);
    }
}

The main window FXML:

<fx:root type="javafx.scene.layout.StackPane" xmlns:fx="http://javafx.com/fxml" fx:controller="com.clientgui.ClientGUI" prefHeight="675" prefWidth="1200.0" fx:id="root" styleClass="root">
...
</fx:root>

The FXML of the box I want to create dynamically:

<VBox id="VBox" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml" fx:controller="com.clientgui.StaticDataBox" styleClass="data-box">
...
</VBox>

Upvotes: 1

Views: 5498

Answers (1)

Uluk Biy
Uluk Biy

Reputation: 49215

You are using the instantiated version of FXMLLoader, i.e. non-static load() method of it. This method obligates that the location is set prior calling it, as explained in its javadoc. So by calling loader.load() method, FXMLLoader parses the fxml file at a given location, initializes the controller and constructs the node graph. If the loader.load() method invoked again, FXMLLoader detects that the root has been already set and throws the "Root value already specified." exception.
However invoking the static load() methods of FXMLLoader over and over, will not cause this exception. Because the fxml file parsing and other stuff are performed from the scratch over again independently from each call, on each call.

Upvotes: 3

Related Questions