This blog post fleshes out a previous, much briefer post on adding Spring Framework to the JavaFX and Kotlin mix. I took my original multi-controller application and converted all the JavaFX controllers into Spring Beans. All the beans are initialised in a configuration class, and allowed me to refactor the controllers to use constructor based injection.
Spring Controller Initialisation
All the controllers are created by Spring in a configuration class. Also the EventBus is also a bean and injected into all the controllers.
@Configuration
open class ApplicationConfig {
@Bean
open fun applicationController(fileListController: FileListController,
filePropertiesController: FilePropertiesController,
fileDataController: FileDataController): ApplicationController {
return ApplicationController(fileListController, fileDataController, filePropertiesController)
}
@Bean
open fun eventBus(): EventBus {
return EventBus()
}
@Bean
open fun fileDataController(eventBus: EventBus): FileDataController {
return FileDataController(eventBus)
}
@Bean
open fun fileListController(eventBus: EventBus): FileListController {
return FileListController(eventBus)
}
@Bean
open fun filePropertiesController(eventBus: EventBus): FilePropertiesController {
return FilePropertiesController(eventBus)
}
}
So the Application Controller is now much simpler, taking all the other controllers as constructor arguments.
class ApplicationController(private val fileListController: FileListController, private val fileDataController: FileDataController, private val filePropertiesController: FilePropertiesController) {
...
}
Application Startup
Application startup now needs to create a Spring Application Context and inject the application controller into the FXML Loader.
class Main : Application() {
private val context: AnnotationConfigApplicationContext = AnnotationConfigApplicationContext(ApplicationConfig::class.java)
@Throws(Exception::class)
override fun start(primaryStage: Stage) {
val controller = context.getBean("applicationController") as ApplicationController
val loader = FXMLLoader(javaClass.getResource("/springkotlin.fxml"))
loader.setController(controller)
...
}
}
And that’s it! The full source code is here.
I’m still reading your blog 🙂
You can simplify your code slightly by annotating each controller class directly with @Bean or @Component
LikeLike
Thanks for the tip Eugene. Will take a look at it.
LikeLike