I'm trying to understand why data binding works in the way it works in JavaFX. It lets you bind ObservableValues to other ObservableValues like this:
val prop0 = SimpleStringProperty("xul")
val prop1 = SimpleStringProperty("baz")
prop0.bind(prop1)
When I do this both properties will have the value baz.
I can also chain bindings:
val prop0 = SimpleStringProperty("xul")
val prop1 = SimpleStringProperty("baz")
val prop2 = SimpleStringProperty("qux")
prop0.bind(prop1)
prop1.bind(prop2)
// all will have the value "qux"
The docs says that I can't set the value of a property which is bound:
prop0.value = "foo" // exception
although I can have cyclic bindings:
val prop0 = SimpleStringProperty("xul")
val prop1 = SimpleStringProperty("baz")
val prop2 = SimpleStringProperty("wom")
prop0.bindBidirectional(prop1)
prop1.bindBidirectional(prop2)
prop2.bindBidirectional(prop0)
but a simple bidirectional binding will result in a StackOverflowError:
prop0.bindBidirectional(prop1)
prop1.bindBidirectional(prop0)
That's why (I guess) there is an explicit way of doing bidirectional binding:
val prop0 = SimpleStringProperty("xul")
val prop1 = SimpleStringProperty("baz")
val prop2 = SimpleStringProperty("wom")
prop0.bindBidirectional(prop1)
prop0.bindBidirectional(prop2)
What I don't understand is why JavaFX restricts unidirectional binding a value to multiple other values:
val prop0 = SimpleStringProperty("xul")
val prop1 = SimpleStringProperty("baz")
val prop2 = SimpleStringProperty("qux")
prop0.bind(prop1)
// this will unbind prop0 from prop1
prop0.bind(prop2)
but lets me create any number of BidirectionalBindings? Why is there a difference between these concepts when a bidirectional binding should have been two unidirectional bindings?
What's also weird is that there is the Binding interface which creates a new entity which will depend on the source ObservableValues:
val num1 = SimpleIntegerProperty(1)
val num2 = SimpleIntegerProperty(2)
// creates a new binding, which will change its value
// whenever num1 or num2 changes
val sum = num1.add(num2)
which can be disposed:
sum.dispose()
but when I call bind or bindBidirectional it does not return a disposable Binding.
I read the docs but these things are not explained in them. Did I miss something? What is the internal logic which makes this behavior necessary?