简体   繁体   中英

Java alternative to @FXML injection of controllers?

So I have a master controller from the main fxml file and two other controllers from the includes files. Now I inject the child controllers via @FXML ChildController childController . Now it works and everyone who worked with FXML before knows what im talking about. The dependency injection with annotation is all fine but I want to do this myself because I have my own plans on handling all DIs.

(Question below)

This is how I initiate the entire thing:

public void start(Stage primaryStage) throws Exception {    
    FXMLLoader loader = new FXMLLoader();
    loader.setLocation(getClass().getResource("Some resource"));

    MainController mainController = new Controller();
    loader.setController(mainController);

    Scene scene = new Scene(loader.load(), w, h);

    primaryStage.setScene(scene);

    primaryStage.show();
}

Basically I want to do this:

SubController1 A = new SubController1();
SubController2 B = new SubController2();
MainController C = new MainControllerC(A, B);

So how can I do this with FXML (JavaFX)?

You can use a controller factory. If you set a controller factory on the FXMLLoader , the same controller factory will be used when any FXML files included by <fx:include> are loaded.

So:

Callback<Class<?>, Object> controllerFactory = new Callback<Class<?>, Object>() {

    SubController1 a = new SubController1();
    SubController2 b = new SubController2();
    MainController c = new MainController(a, b);

    @Override
    public Object call(Class<?> type) {
        if (type == SubController1.class) {
            return a ;
        }
        if (type == SubController2.class) {
            return b ;
        }
        if (type == MainController.class) {
            return c ;
        }
        return null ;
    }
};

And then

FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource(...));
loader.setControllerFactory(controllerFactory);
Parent root = loader.load();

The FXML files just declare the controller classes in the usual way, using fx:controller="..." .

Controller factories can be pretty powerful: you can use a controller factory to allow a dependency injection framework (such as Spring or Guice) to manage the controllers for you (and inject dependencies into them), for example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM