4

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.

Xaser
  • 2,066
  • 2
  • 22
  • 45

2 Answers2

3

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"
}
Edvin Syse
  • 7,267
  • 18
  • 24
1

In JavaFX you could use a StringConverter:

    TextField field = new TextField();
    Label label = new Label();

    label.textProperty().bindBidirectional(field.textProperty(), new StringConverter<String>() {

        @Override
        public String toString(String fieldValue) {

            // Here you can compute the hash
            return "hash(" + fieldValue+ ")";
        }

        @Override
        public String fromString(String string) {

            return null;
        }

    });
wallek876
  • 3,219
  • 2
  • 19
  • 29