On Wed, 21 Oct 2026 11:10:46 GMT, John Hendrikx <[email protected]> wrote:

>>> This is basically a general problem for any program that allows arbitrary 
>>> callbacks (which in JavaFX are often hidden in events/listeners). Calling 
>>> any callback while you're structure isn't in a fully consistent state is 
>>> problematic if your code must continue working no matter what
>> 
>> If I understand this correctly, this is not a problem per se, as long as the 
>> process converges and has no loops.  In other words, a single property 
>> change might trigger a cascade of updates which must eventually settle.
>> 
>> Once settled, the `layoutChildren()` does the layout and updates the scene 
>> graph.
>> 
>> Perhaps what we need is to detect the loops?  Or am I missing something?
>> 
>> --
>> 
>> Another, related, scenario is when the update cascade requires explicit 
>> layout pass (or N passes, as it happened in RichTextArea with N=2).  It is 
>> possible to let the multiple pulses do their job, at the risk of flicker or 
>> perpetual layout going on (I've seen that).  I think it is better to 
>> explicitly acknowledge these cases and design for them.
>
> Layout is already special, it is done once per frame at most, and the 
> deferral system (`requestLayout`) protects somewhat against the things that 
> callbacks can do (and even then there is documentation stating you shouldn't 
> be binding or modifying certain layout specific properties).
> 
> Properties that defer calling their listeners already exist, because 
> callbacks would interfere with whatever they're trying to achieve.
> 
> Most user callbacks won't interfere, but almost any group of two properties 
> that are being manipulated "as part of a whole" can be interfered with with a 
> specially crafted listener on one of them. Loop detection only buys you that 
> you notice that the properties are inconsistent (like the warning in #1081) 
> but there's no route to fix it as any fix attempt can be thwarted by a 
> listener user callback.

> > I do have a solution for this, that I use for my own programs. They're 
> > basically a different kind of property that allows the owner of the 
> > property (ie. the control, table, whatever) to control when listeners fire 
> > (something we see already in some areas of FX where properties are 
> > "customized" to delay firing, but that's usually manual and not coordinated 
> > across multiple properties).
> 
> I'm all ears. A solution to this problem in JavaFX would be great. Yeah 
> JavaFX already uses this mechanism for e.g. `focusProperty` and it makes 
> sense.
> 
> > For example, if I need to change 3 properties, but they're all related 
> > (let's say x,y,z) I can change all three, and only at the end of my changes 
> > have the listeners fire.
> 
> This is exactly what we need.

In my FX Flow library, I have a solution for externally read only properties 
`UpdatableValue`, but general solutions can be built as well. It works like 
this:

    // these are private inside some class (like a ReadOnlyPropertyWrapper)
    private final UpdatableValue<Double> x = UpdatableValue.of();
    private final UpdatableValue<Double> y = UpdatableValue.of();

    // UpdatableValue don't have a normal "set" or "setValue" method at all,
    // instead manipulate using `UpdatableValue.set` method:
    UpdatableValue.set(
        x, 100,  // these are all typed parameters, despite how it looks
        y, 100
    );

    // or using `batch` method:
    UpdatableValue.batch(() -> {
      UpdatableValue.set(x, 100);
      UpdatableValue.set(y, 100);
      // supports nesting, can start another batch here, listeners only
      // fire at the end of the top most level batch
    });

    // exposing as read only:
    public final ObservableValue<Double> x() {
        return x.asObservableValue();
    }

For more arbitrary property manipulation, I've also got a different system, but 
it requires wrapping all properties that should participate in a transaction. 
If we ever add something like this to FX (where we can change the property code 
itself) the wrapping may not be needed. The `UpdatableValue` system is more 
light-weight, and works much more like how read only properties work.

-------------

PR Review Comment: https://git.openjdk.org/jfx/pull/2347#discussion_r4336229330

Reply via email to