Search code examples
csskotlintornadofx

How to bind Node style (or styleClass) to a property?


Consider the following example:

class MainView : View("Example") {
    val someBooleanProperty: SimpleBooleanProperty = SimpleBooleanProperty(true)
    override val root = borderpane {
        paddingAll = 20.0
        center = button("Change bg color") {
            action {
                // let's assume that new someBooleanProperty value is updated
                // from some API after button clicked
                // so changing style of the borderpane in action block
                // of the button is not the solution
                someBooleanProperty.value = !someBooleanProperty.value
            }
        }
    }
}

class Styles : Stylesheet() {
    companion object {
        val red by cssclass()
        val green by cssclass()
    }

    init {
        red { backgroundColor += Color.RED }
        green { backgroundColor += Color.GREEN }
    }
}

How can I dynamically change the background color of borderpane depending on someBooleanProperty (e.g RED when true and GREEN when false)? Is there possibility to bind CSS class to a property? Is there any solution to do that without using CSS (meaning inside style block etc)


Solution

  • If you want to toggle a class (add or remove a class based on a boolean property), you can use the Node.toggleClass(CssRule, ObservableValue<Boolean>) function.

    val someBooleanProperty = SimpleBooleanProperty(true)
    ...
    borderpane {
        toggleClass(Styles.red, someBooleanProperty)
        toggleClass(Styles.green, someBooleanProperty.not())
    }
    

    If, on the other hand, you want to bind to a changing class value, you can use the Node.bindClass(ObservableValue<CssRule>) function.

    val someClassyProperty = SimpleObjectProperty(Styles.red)
    ...
    borderpane {
        bindClass(someClassyProperty)
    }
    

    You can then set the class to whatever you want.