Just to expand on the use case in ScalaFX, the scalafx.application.JFXApp
trait primarily does two things:
- Firstly, it initializes JavaFX and starts the JavaFX Application Thread (JFXAT), using any supplied command line arguments.
- It then uses
scala.DelayedInit
to queue up all sub-class constructors (in the exact same manner as withscala.App
) but then passes them for execution to the JFXAT.
This is extremely convenient, because interaction with the JavaFX API must typically take place only on the JFXAT. This allows ScalaFX users to write trivial GUI applications in their application constructors, safe in the knowledge that the JFXAT will have been created and initialized, and that those constructors execute on that thread too.
For example:
import scalafx.Includes._
import scalafx.application.JFXApp
import scalafx.scene.Scene
import scalafx.scene.paint.Color._
import scalafx.scene.shape.Rectangle
object HelloStageDemo
extends JFXApp {
stage = new JFXApp.PrimaryStage {
title.value = "Hello World!"
width = 600
height = 450
scene = new Scene {
fill = LightGreen
content = new Rectangle {
x = 25
y = 40
width = 100
height = 100
fill <== when(hover) choose Green otherwise Red
}
}
}
}
Without DelayedInit
, all bets are off. Even onCreate
doesn’t appear to address how this can be resolved. The only solution appears to be to put what used to be in the constructor into a virtual function, and hope that no-one attempts to interact with JavaFX from an application constructor. This a far less elegant, and would break all existing user code too.