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.
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"
}