4

Everywhere I see explanations on the use o FXMLLoader#setController() it's associated with using fx:root and also setting a root node programmatically (both Oracle Docs and SO answers have this pattern). Is it a requirement? Or can I create a regular FXML (probably using SceneBuilder) with some good old container and set only the controller programmatically later?

In FXML:

<BorderPane fx:id="root" prefHeight="500.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml" > </Borderpane>

In some code (probably a controller):

FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("fxml_example2.fxml"));
fxmlLoader.setController(this);
try {
    fxmlLoader.load();            
} catch (IOException exception) {
    throw new RuntimeException(exception);
}
Community
  • 1
  • 1
Rodrigo Coacci
  • 193
  • 1
  • 7

1 Answers1

7

I don't think it is a requirement. I've got this working by tweaking the Oracle tutorial code to look like this in my Application class:

@Override
public void start(Stage stage) throws Exception {

    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("fxml_example.fxml"));
    fxmlLoader.setController(new ExampleController());
    Parent root = (Parent)fxmlLoader.load();

    stage.setTitle("FXML Welcome");
    stage.setScene(new Scene(root, 300, 275));
    stage.show();
}

As you can see I've set my ExampleController programatically rather than using the fx:controller="ExampleController" in the FXML and I didn't have to set id:root anywhere to do it.

As an aside, I quite like this approach as it mimics more closely setting the data context in MVVM with WPF and further decouples the view from the controller.

Paolo
  • 22,188
  • 6
  • 42
  • 49