RFR: 8360940: Layout stops updating when using Parent#setNeedsLayout(true) due to incorrect state management [v2]

Andy Goryachev angorya at openjdk.org
Wed Oct 1 17:14:08 UTC 2025


On Wed, 1 Oct 2025 16:55:00 GMT, John Hendrikx <jhendrikx at openjdk.org> wrote:

>>> When a situation like this happens in reality, we might see a momentary flicker due to the layout spanning several pulses, correct?
>> 
>> Well, if layout runs (due to a significant change), you'll see components be re-arranged, and if a 2nd pulse is needed, you would probably not notice as things were moved around a lot anyway.  But on top of that, there is a good chance the 2nd pass is just recalculating everything without actually changing anything because it is often triggered without a good reason.  For example:
>> 
>> Take an HBox for example.  During layoutChildren, it will position its children.  If this involves moving a child to the right or left because an earlier child has shrunk/grown then layout X is changed and triggers the logic in Node (without good reason I might add).  This is in part because HBox does not update or set the "current layout child" at all (none of the containers do this, except Parent's layoutChildren which is almost always overridden).  So this code below in Node will trigger and force another layout pass:
>> 
>>                     if (p != null && !p.isCurrentLayoutChild(Node.this)) {
>>                         if (isManaged()) {
>>                             // Force its parent to fix the layout since it is a managed child.
>>                             p.requestLayout(true);
>>                         } else {
>>                             // Parent size changed, parent's parent might need to re-layout
>>                             p.clearSizeCache();
>>                             p.requestParentLayout();
>>                         }
>>                     }
>>                     
>> All the ingredients match:
>> - LayoutX was modified on a child
>> - Its parent is not `null` (it's the HBox)
>> - It is not the current layout child (HBox doesn't update this before modifying a position on a child)
>> - The child in question is managed (all children in an HBox generally are)
>> 
>> End result: schedule another layout pass
>> 
>> Now, if in the 2nd pass none of the X (or Y) positions change again, then this 2nd pass will end up doing nothing.  Quite wasteful.
>> 
>>> The platform itself can't really do anything, except for the application code to call the layout() explicitly to avoid flicker, right?
>> 
>> Calling `layout` won't do much when the flags are bad, as layout basically operates based on those flags.  So if you call layout at the root, and the flags say that it is `CLEAN` then it stops right there.  
>> 
>> However there are many thi...
>
>> Or maybe even make it more generic: detect when (a small number of) additional layout passes are needed and do them right away instead of waiting for another pulse?
> 
> But also avoid passes that are not needed... I mean HBox almost always triggering a redundant 2nd pass makes the logic in `Node` suspect IMHO.
> 
> I get why the logic is **really** there; a user may modify layoutX randomly on some managed control outside a layout pass; in that case you do want the Parent that is managing those nodes to take control and "fix" what the user broke, but it is triggering much more often than needed.

that was a good, informative discussion, thank you all!

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

PR Review Comment: https://git.openjdk.org/jfx/pull/1879#discussion_r2395291017


More information about the openjfx-dev mailing list