Search code examples
javamultithreadingjavafxthread-safetyvolatile

Changing member value from start() in Application and save reference to ui components


I have the following custom Application class implementation. However, I do not understand why the value of isVisible does not change. I tried to change the field type to SimpleBooleanProperty. However, it does not help. Also, I should access the ui later, so I wanted to save the reference to them, however, the value does not set as well. I tried initializing my ui components in start() method, however, after that if I see my field, it is null.

import javafx.stage.Stage
import java.util.concurrent.atomic.AtomicBoolean

class TestApplication : Application() {

    @Volatile
    private var isVisible = AtomicBoolean(false)

    override fun start(stage: Stage) {
        stage.show()
        println("Stage shown ${Thread.currentThread().name}")
        isVisible.set(true)
    }

    fun showUI() {
        Thread { launch(TestApplication::class.java) }.start()

        println("Waiting until getting visible")
        while (isVisible.get().not());
        println("isVisible=${isVisible}")
    }
}

Solution

  • The problem is creating the instance of the TestApplication class twice. Application.launch() creates new instance, does not get the existing one.

    The solution can be to use singleton pattern on TestApplication class.