bugfix> kotlin > 投稿

ユーザーが設定と呼ばれるビューでアプリの背景テーマ(ライト/ダーク)を変更できるように、アプリに機能を追加しようとしています。スタイルシートクラスの2つの異なるスタイルシートを使用してテーマを変更する場合、実行中にアプリが使用するスタイルシートを変更するにはどうすればよいですか?これを行う簡単な方法はありますか?

これらの設定のコードは以下にあります。コードの改善も役立ちます:

class Settings(){
    var BackGroundTheme: BackGroundThemeState = BackGroundThemeState.Light
}
enum class BackGroundThemeState{Light, Dark}
class SettingsController: Controller(){
    private var settings = Settings()
    fun changeTheme(state: BackGroundThemeState){
        when(state){
            Light -> settings.BackGroundTheme = Light
            Dark  -> settings.BackGroundTheme = Dark
        }
        when(settings.BackGroundTheme){
//            Light -> do nothing for now
            Dark  -> importStylesheet(app.DarkThemeStyleSheet)
        }
        reloadStylesheetsOnFocus()
    }
} 
class SettingsView: View("Settings"){
    val settings: SettingsController by inject()
    private val toggleGroup = ToggleGroup()
    override val root = vbox(){
        alignment = Pos.BOTTOM_CENTER
        setPrefSize(300.0, 200.0)
        hbox(){
            alignment = Pos.BASELINE_LEFT
            vbox {
                paddingTop = 10.0
                paddingLeft = 30.0
                paddingBottom = 90.0
                label("Theme")
                radiobutton("Light", toggleGroup){
                    isSelected = true
                    action {
                      settings.changeTheme(Light)
                    }
                }
                radiobutton("Dark", toggleGroup) {
                    action {
                        settings.changeTheme(Dark)
                    }
                }
            }
        }
        hbox {
            alignment = Pos.BOTTOM_RIGHT
            paddingRight = 15.0
            paddingBottom = 10.0
            button("OK"){
                setPrefSize(70.0, 30.0)
                action{
                    find(SettingsView::class).close()
                }
            }
        }
    }
}

回答 1 件
  • これは、監視可能なプロパティに依存している場合、はるかにスムーズに実行できます。現在のテーマを保持するプロパティを作成し、古いプロパティを削除して、このプロパティが変更されたときに新しいテーマを追加します。

    トグルグループの組み込み機能を使用して、アクティブなテーマプロパティにバインドできます。

    これを示す完全なアプリケーションを次に示します。

    class MyThemeApp : App(SettingsView::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 = SimpleListProperty<KClass<out Stylesheet>>(listOf(LightTheme::class, DarkTheme::class).observable())
        // Property holding the active theme
        val activeThemeProperty = SimpleObjectProperty<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 SettingsView : View("Settings") {
        val settings: ThemeController by inject()
        override val root = form {
            fieldset("Theme") {
                field {
                    vbox {
                        togglegroup {
                            // One radio button for each theme, with their value set as the theme
                            settings.themes.forEach { theme ->
                                radiobutton(theme.simpleName, getToggleGroup(), theme)
                            }
                            // The toggle group value is bound to the activeThemeProperty
                            bind(settings.activeThemeProperty)
                        }
                    }
                }
                buttonbar {
                    button("OK").action(this@SettingsView::close)
                }
            }
        }
    }
    // Two themes for completeness
    class DarkTheme : Stylesheet() {
        init {
            root {
                backgroundColor += Color.DARKGREEN
            }
        }
    }
    class LightTheme : Stylesheet() {
        init {
            root {
                backgroundColor += Color.LIGHTCYAN
            }
        }
    }
    
    

あなたの答え