Javafx - Load FXML file inside controller but also use NetBeans "Make Controller"

When trying to load an FXML file, it usually does something like this:

FXMLLoader loader = FXMLLoader.load(getClass().getResource("File.fxml"));
Region root = loader.load();
Stage stage = new Stage();
stage.setScene(new Scene(root));
stage.show();

      

However, when I tried to put the download code in the controller for "caller convenience", I did the following:

public Controller()
{
   FXMLLoader loader = new FXMLLoader(getClass().getResource(fxml));
   loader.setController(this);
   Parent root = loader.load();
   Stage stage = new Stage();
   stage.setScene(new Scene(root));
   stage.show();
}

      

It worked well because now I just needed to call the constructor to create a new window.

But I had to delete

fx:controller="package.Class"

      

in the FXML file because otherwise an Exception ("javafx.fxml.LoadException: controller is already set") was thrown when I called

fxmlloader.setController(this);

      

in the constructor. Since I am using NetBeans and its "Make Controller" function (right click on the FXML file), the controller class cannot be created due to a missing attribute.

Summary:

I want to ensure that the "fx: controller" attribute is still set to FXML (for NetBeans) and can also easily load the FXML inside the Controller class.

Is this possible, or do I need some sort of wrapper class that creates the FXML window (s)?

Thanks in advance.

+3


source to share


1 answer


You can do it:

public Controller()
{
   FXMLLoader loader = new FXMLLoader(getClass().getResource(fxml));
   loader.setControllerFactory(type -> {
       if (type == Controller.class) {
           return this ;
       } else {
           try {
               return type.newInstance();
           } catch (RuntimeException e) {
               throw e ;
           } catch (Exception e) {
               throw new RuntimeException(e);
           }
       }
   });
   Parent root = loader.load();
   Stage stage = new Stage();
   stage.setScene(new Scene(root));
   stage.show();
}

      



which will allow you (essentially you will need) to have the attribute fx:controller

in the FXML file. This basically means that a function FXMLLoader

can use to get an instance of a controller from a specified class. In this case, if the FXML Loader searches for an object of a class Controller

, it returns the current object, otherwise it simply creates a new object of the specified class.

+3


source







All Articles