I’m about to finish a simple program with JavaFX as GUI and there’s only one more thing left to do: getting the graphical user interface to update some labels with the correspondent data fetch from a suspendable function. I have built the GUI with Scenebuilder and I load the FXML file into the Main Class (the one which inherits from Application(). I would like to do this using coroutines, but as you might have guessed, I don’t have enough knowledge yet. I’ve seen quite a few tutorials and read some others as well, but there aren’t many coroutines + JavaFx tutorials out there. I will post the code of a demo app so that is simpler to read:
Basically, this is what I’m doing (Now. But I’ve tried other approaches):
HelloApplication.kt
package com.alberto.demo2
import javafx.application.Application
import javafx.fxml.FXMLLoader
import javafx.scene.Scene
import javafx.stage.Stage
import kotlinx.coroutines.*
import kotlinx.coroutines.javafx.JavaFx
import kotlin.coroutines.CoroutineContextvar controlador:HelloController = HelloController()
var contador:Int = 0class HelloApplication : Application() {
override fun start(stage: Stage) { val fxmlLoader = FXMLLoader(HelloApplication::class.java.getResource("hello-view.fxml")) val scene = Scene(fxmlLoader.load(), 320.0, 240.0) stage.title = "Hello!" stage.scene = scene stage.show() GlobalScope.launch(Dispatchers.Default){ while(true) { updateLabel() delay(1000) } } }
}
fun updateLabel(){
contador++ controlador.welcomeText.text = "$contador"
}
fun main() {
Application.launch(HelloApplication::class.java)
}
HelloController.kt
package com.alberto.demo2
import javafx.fxml.FXML
import javafx.scene.control.Label
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
class HelloController {
@FXML
var welcomeText: Label = Label()
@FXML
private fun onHelloButtonClick() {
welcomeText.text = "Welcome to JavaFX Application!"
}
}
At this moment, I’m getting this output:
Exception in thread “main” java.lang.ExceptionInInitializerError
at com.alberto.demo2.HelloController.(HelloController.kt:11)
at com.alberto.demo2.HelloApplicationKt.(HelloApplication.kt:11)
Caused by: java.lang.IllegalStateException: Toolkit not initialized
at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:410)
at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:405)
at com.sun.javafx.application.PlatformImpl.setPlatformUserAgentStylesheet(PlatformImpl.java:695)
at com.sun.javafx.application.PlatformImpl.setDefaultPlatformUserAgentStylesheet(PlatformImpl.java:657)
at javafx.scene.control.Control.(Control.java:99)
… 2 more
I’ve tried other approach that didn’t throw any exceptions but neither did update the label with the increment of “contador” (counter).
If you have any suggestions for me to try or know about any good article that can make things clearer than other articles out there, about coroutines, please let me know.
Thank you very much in advance!
Alberto.