Lets consider two methods of Property
interface:
Property#unbind()
Property#unbindBidirectional(Property<T> other)
As we see, when we want to remove bidirectional binding we can pass the property for which we want to remove this binding.
However, when we remove unidirectional binding we can not pass such property. How to explain it?
The methods involved in unidirectional bindings are bind
, unbind
, and isBound
.
It is important to know that unidirectional bindings are one-to-one1. This is done to maintain consistency. Consider what would happen if multiple unidirectional bindings were allowed at the same time. If we have:
A
→ B
A
→ C
What should A
contain? The value of B
or the value of C
? The contract of bind
requires that the Property
will always contain the value of the ObservableValue
. From javafx.beans.property
:
All properties can be bound to ObservableValues of the same type, which means that the property will always contain the same value as the bound ObservableValue.
The Property
can't maintain this contract if there's more than one ObservableValue
to observe. Thus, a one-to-one1 relationship is enforced.
As a consequence of this one-to-one1 relationship, it is not necessary to pass the ObservableValue
when calling unbind
. The only possible ObservableValue
that could be meant is the one previously given via bind
.
It's worth mentioning that calling bind
on an already bound Property
will implicitly unbind from the previous ObservableValue
. At least, that's how the standard implementations work. I couldn't find documentation defining this behavior so I suppose an implementation could throw an exception instead.
1. Technically, it is a many-to-one relationship. More than one Property
can be bound to the same ObservableValue
, but that one Property
cannot be bound to more than one ObservableValue
. I'm leaving one-to-one in the answer, however, because I think it better illustrates the difference between unidirectional and bidirectional bindings.
The methods involved in bidirectional bindings are bindBidrectional
and unbindBidirectional
.
For bidirectional bindings, the relationship is many-to-many. They are also independent from unidirectional bindings. From bindBidirectional
:
Create a bidirectional binding between this Property and another one. Bidirectional bindings exists independently of unidirectional bindings. So it is possible to add unidirectional binding to a property with bidirectional binding and vice-versa. However, this practice is discouraged.
It is possible to have multiple bidirectional bindings of one Property.
This many-to-many relationship is allowed for bidirectional bindings because they cause each Property
to mirror each other. If one changes, the other updates. From javafx.beans.property
:
It is also possible to define a bidirectional binding between two properties, so that both properties always contain the same value. If one of the properties changes, the other one will be updated.
This means the consistency issue that unidirectional bindings have isn't shared by bidirectional bindings. Consider the following:
A
↔ B
↔ C
If A
changes, then B
will update. Because B
has updated, C
will also update. This means at any given time all properties have the same value. No ambiguity.
As a consequence of this many-to-many relationship, the target Property
is required when unbinding; the bound Property
needs to know which Property
it needs to unbind from.