mitso
mitso

Reputation: 15

Spring injection with new Window (FXML)

I use AnnotationConfigApplicationContext to load my spring configuration.

public class Main extends Application {

private AnnotationConfigApplicationContext applicationContext;

@Override
public void init() throws Exception {
    applicationContext = new AnnotationConfigApplicationContext(ApplicationConfig.class);

}

@Override
public void start(Stage primaryStage) throws Exception{
    FXMLLoader loader = new FXMLLoader(getClass().getResource("/org/test/view/main.fxml"));
    loader.setControllerFactory(applicationContext::getBean);
    Parent root = loader.load();
    primaryStage.show();
    primaryStage.setOnHidden(e -> Platform.exit());
}

and this is my ApplicationConfig

@Configuration
@ComponentScan
public class ApplicationConfig {

@Bean
public Executor executor() {
    return Executors.newCachedThreadPool(r -> {
        Thread t = new Thread(r);
        t.setDaemon(true);
        return t ;
    });
}

Now I would like to inject this Executor instance into a new Stage (TestController.fxml) via FXMLLoader. How can I achieve that?

public void showNewWindow()  {
    try {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/org/test/view/TestController.fxml"));
        Parent root1 = fxmlLoader.load();
        Stage stage = new Stage();            
        stage.setScene(new Scene(root1));
        stage.show();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

All help will be greatly appreciated. Thanks!

Upvotes: 0

Views: 435

Answers (1)

James_D
James_D

Reputation: 209330

You can inject "well-known objects" into spring-managed beans. The application context itself is one such object, so in your main controller you can do:

public class MainController {

    @Autowired
    private ApplicationContext applicationContext ;

    public void showNewWindow()  {
        try {
            FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/org/test/view/TestController.fxml"));
            fxmlLoader.setControllerFactory(applicationContext::getBean);
            Parent root1 = fxmlLoader.load();
            Stage stage = new Stage();            
            stage.setScene(new Scene(root1));
            stage.show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // ...

}

Now the TestController will be spring-managed, so you can simply do

public class TestController {

    @Autowired
    private Executor executor ;

    // ...

}

Upvotes: 1

Related Questions