Proper way to bind a Property to a Value derived from a control in JavaFx / TornadoFX

Xaser :

Consider the (kotlin/tornadofx) example below, which aims to connect the contents of a textfield with the text of a label through binding. The label should reflect a derived value of the textfield, in this case the hash. How do I properly achieve this binding (I feel that using a changelistener is not the proper way to go).

class HashView : View("My View") {
    val hashProperty = SimpleStringProperty("EMPTY")

    override val root = vbox {
        textfield {
            hashProperty.bind(stringBinding(text) { computeHash(text)}) // This does not work
        }
        label(hashProperty)
    }
}

PS: answers in java / JavaFX are also welcome as long as I can somehow apply the idea in tornadofx as well.

UPDATE 1: I have discovered that there was only a minor change necessary to make my example work, namely it should be

hashProperty.bind(stringBinding(textProperty() { computeHash(this.value) })

I am however still not certain whether this is the conventional way to do it. So I'm going to leave this question open.

Edvin Syse :

I recommend not to involve the properties of the actual input elements in the calculations. You should define the input property first and bind that to the textfield. Then create a derived StringBinding and bind that to the label. Also note that a property has a built in stringBinding function which automatically operates on that property. This makes your code look a lot cleaner, can be made reusable if needed and is easier to maintain:

class HashView : View("My View") {
    val inputProperty = SimpleStringProperty()
    val hashProperty = inputProperty.stringBinding { computeHash(it ?: "EMPTY") }

    override val root = vbox {
        textfield(inputProperty)
        label(hashProperty)
    }

    fun computeHash(t: String) = "Computed: $t"
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=97688&siteId=1