<div dir="ltr">Sounds good. Have you tried a prototype implementation for a built-in JavaFX control/Pane, just to see how well it works?</div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Wed, Apr 16, 2025 at 5:50 PM Andy Goryachev <<a href="mailto:andy.goryachev@oracle.com">andy.goryachev@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="msg-1880730255040356136">





<div lang="EN-US" style="overflow-wrap: break-word;">
<div class="m_-1880730255040356136WordSection1">
<p class="MsoNormal"><span style="font-size:11pt;font-family:"Iosevka Fixed SS16"">This might be a good idea from an API perspective, but please be careful - this optimization might break the behavior. For instance, the scroll bar might change as a result
 of a key event in the TextArea, so the text layout is still needed, however expensive.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"Iosevka Fixed SS16""><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"Iosevka Fixed SS16"">(and I like Michael's suggestion of naming the method requestLayoutChildren())<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"Iosevka Fixed SS16""><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"Iosevka Fixed SS16"">-andy<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"Iosevka Fixed SS16""><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"Iosevka Fixed SS16""><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"Iosevka Fixed SS16""><u></u> <u></u></span></p>
<div id="m_-1880730255040356136mail-editor-reference-message-container">
<div>
<div>
<div style="border-right:none;border-bottom:none;border-left:none;border-top:1pt solid rgb(181,196,223);padding:3pt 0in 0in">
<p class="MsoNormal" style="margin-bottom:12pt"><b><span style="font-size:12pt;color:black">From:
</span></b><span style="font-size:12pt;color:black">openjfx-dev <<a href="mailto:openjfx-dev-retn@openjdk.org" target="_blank">openjfx-dev-retn@openjdk.org</a>> on behalf of John Hendrikx <<a href="mailto:john.hendrikx@gmail.com" target="_blank">john.hendrikx@gmail.com</a>><br>
<b>Date: </b>Monday, April 14, 2025 at 08:56<br>
<b>To: </b><a href="mailto:openjfx-dev@openjdk.org" target="_blank">openjfx-dev@openjdk.org</a> <<a href="mailto:openjfx-dev@openjdk.org" target="_blank">openjfx-dev@openjdk.org</a>><br>
<b>Subject: </b>Unnecessary layouts; TLDR; new method "requestLocalLayout"<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:12pt"><span style="font-size:11pt">I've been writing a container that does layout, and I've been using it<br>
extensively in my latest project.<br>
<br>
I noticed that many skins and controls will call requestLayout(), not<br>
realizing that this will mark the current node + all parent nodes with<br>
`NEEDS_LAYOUT`.  This causes all those containers to call `compute`<br>
methods and execute their `layoutChildren`, even though your control may<br>
only have changed something that does NOT change its layout bounds (like<br>
a color, background, alignment or even things like a cursor shape or<br>
position).  These computations are expensive, involving querying of all<br>
children of each container to find out their min/pref/max sizes, do<br>
content bias calculations, splitting space over each control and many<br>
many snapXYZ calls -- all leading to no visual layout change...<br>
<br>
For example, a TextArea or TextField will call requestLayout on every<br>
character typed, every cursor movement, and every text content change. <br>
None of those affects their bounds (at least, in my experience, these<br>
controls are not continuously resizing themselves when I scroll or type<br>
things...).  TextField will even change its cursor shape every time its<br>
value is updated, even if that value is simply bound to a Slider and the<br>
field doesn't have focus at all -- this field will then trigger layout<br>
on itself and all its ancestors even if it is in a completely unrelated<br>
area of the UI (not close to the slider).<br>
<br>
It seems that in many cases these controls and skins just want their<br>
layoutChildren method to be called, as their main layout logic is<br>
located there -- duplicating this logic partially for every minor<br>
property change that doesn't affect its bounds is error prone, so I can<br>
completely follow this reasoning.  However, using requestLayout to get<br>
layoutChildren called is very expensive.<br>
<br>
There is a better way: call setNeedsLayout(true) -- this is a protected<br>
method that any Node has access to, and basically will only call<br>
layoutChildren on your own Node.  It marks all the parent nodes as<br>
`DIRTY_BRANCH`, which means that on a layout pass it will traverse down<br>
to see which nodes actually needs layout (it won't call layoutChildren<br>
for each ancestor, which is a big win).<br>
<br>
Because of its protected nature (and its required parameter which must<br>
be true), it is a bit hard to use.  I'm thinking it might be a good idea<br>
to introduce a new method here, a request layout call that schedules a<br>
Node for layout without forcing all ancestors to do the same. This way<br>
Skin and Control designers can clearly see the two options and choose<br>
what is required:<br>
<br>
     requestLayout -- my bounds likely have changed (font change,<br>
border/padding change, spacing change), so please call compute methods<br>
and redo the entire layout<br>
<br>
     requestLocalLayout -- my bounds have not changed (color changes,<br>
background changes, content changes within a ScrollPane, cursor changes,<br>
cursor position changes, alignment changes)<br>
<br>
What do you think?<br>
<br>
--John<br>
<br>
<br>
<u></u><u></u></span></p>
</div>
</div>
</div>
</div>
</div>
</div>

</div></blockquote></div>