import javafx.scene.paint.Color import javafx.stage.Stage import tornadofx.* import kotlin.reflect.KClass class LearnApp : App(ThemeView::class){ val themeController: ThemeController by inject() override fun start(stage: Stage) { super.start(stage) // Make sure we initialize the theme selection system on start themeController.start() } } class ThemeController : Controller() { // List of available themes // val themes = listProperty<KClass<out Stylesheet>>(listOf(LightTheme::class, DarkTheme::class).asObservable()) val themes = listProperty(listOf(LightTheme::class, DarkTheme::class).asObservable()) // Property holding the active theme val activeThemeProperty = objectProperty<KClass<out Stylesheet>>() var activeTheme by activeThemeProperty fun start() { // Remove old theme, add new theme on change activeThemeProperty.addListener { _, oldTheme, newTheme -> oldTheme?.let { removeStylesheet(it) } newTheme?.let { importStylesheet(it) } } // Activate the first theme, triggering the listener above activeTheme = themes.first() } } class ThemeView : View("更換主題顏色樣式") { val settings: ThemeController by inject() override val root = form { fieldset("Theme") { field { vbox(10) { togglegroup { // One radio button for each theme, with their value set as the theme settings.themes.forEach { theme -> radiobutton(theme.simpleName, value=theme) } // The toggle group value is bound to the activeThemeProperty bind(settings.activeThemeProperty) } } } buttonbar { button("Close").action(this@ThemeView::close) } } prefWidth=300.0 prefHeight=300.0 } } // Two themes for completeness class DarkTheme : Stylesheet() { init { root { backgroundColor += Color.DARKGREEN } } } class LightTheme : Stylesheet() { init { root { backgroundColor += Color.LIGHTCYAN } } }