Francesco
Francesco

Reputation: 406

JavaFx optional parameters for controller class in start method when it is loaded into the FXML

with the ScheneBuilder I defined the controller class of my fxml, the code genereted inside my AnchorPane tag is:

fx:controller="demo.SplashController"

now I would like if I had args in the main, to load a new version of the controller, using the appropriate construct. I try this code in the Application.start:

FXMLLoader loader = new FXMLLoader(getClass().getResource("page.fxml"));
PageController controller;
if(!dir.equals("")){ //attribute coming from args
  controller = new PageController(dir);
}else{
  controller = new PageController();  
}
loader.setController(controller);
AnchorPane root = loader.load();
Scene scene = new Scene(root,480,414);
primaryStage.setScene(scene);
primaryStage.show();

but using this code a conflict appears because I have already defined the controller in my project with FXML code, to solve it would be enough to remove the segment in the FXML code but I would not do it because leaving the code in the fxml allows me to access some good features of the SceneBuilder.

Upvotes: 0

Views: 311

Answers (1)

fabian
fabian

Reputation: 82461

The only way pass parameters to the controller's constructor and specify the controller's class in the fxml is to use a controller factory:

FXMLLoader loader = new FXMLLoader(getClass().getResource("page.fxml"));
loader.setControllerFactory(cl -> dir.isEmpty() ? new PageController() : new PageController(dir));
AnchorPane root = loader.load();

Another option would be to create a method in the controller class that allows you to pass the info after loading and does the initialisation:

FXMLLoader loader = new FXMLLoader(getClass().getResource("page.fxml"));
AnchorPane root = loader.load();
PageController controller = loader.getController();
controller.setDir(dir);

Note that the method call happens after the initialize method is run assuming there is one.

Upvotes: 1

Related Questions