This is a kind of follow-up of seeing thread-rule violations when mixing Swing/FX and bind both parts to the same model.
Meanwhile I experimented a bit: use a custo
A partial answer (why the misbehaviour of the bidi-bound textfield and what to do against it):
Techically, the behaviour is due to internal flags which get confused when the "back-notification" of a bidi-bound property happens outside of the expected code blocks.
isUpdating
to not update the originating property again doNotAdjustCaret
is used by TextInputControl to mark changes triggered by itself. The control has a custom TextProperty which uses that flag to either set the selection to the start (for external changes) or not (for internal changes) Now the thread-changing property falls outside the first block, triggers a re-set of the textProperty which in turn isn't recognized as self-triggered, thus resetting the selectin/caret. A work-around is to update the value and "back-fire" directly:
/**
* Implemented to set the value of this property, immediately
* fire a value change if needed and then update the delegate.
*
* The sequence may be crucial if the value is changed by a bidirectionally
* bound property (like f.i. a TextProperty): that property reacts to
* change notifications triggered by its own change in a different
* way as by those from the outside, detected by a flag (sigh ...)
* set while firing.
*/
@Override
public void set(T value) {
T oldValue = this.value;
this.value = value;
if (!areEqual(oldValue, value)) {
fireValueChangedEvent();
}
updateToDelegate(value);
// PENDING: think about uni-directional binding
}
/**
* Updates the internal value and notifies its listeners, if needed.
* Does nothing if the newValue equals the current value.<p>
*
* It runs on the thread it is called from.
*
* @param newValue the new value.
*/
protected void doUpdateFromDelegate(T newValue) {
if (areEqual(newValue, value)) return;
value = newValue;
fireValueChangedEvent();
}