Richard, 

Is there a sequence diagram (or similar) where the layout process is described 
in detail?
It’s hard to in text get a clear and precise view on how the layout process in 
the Node hierarchy is happening.

The sequence diagram would be good to have as a constraint for building layout 
panes. Otherwise its easy to time things incorrectly with strange layout 
artefacts as a result.
It’s especially important for devs to know which methods are called for the 
pre-layout (size measuring) phase and them for the actual layout phase.

Cheers,
Mikael

On 28 Jul 2014, at 07:38, Martin Sladecek <martin.slade...@oracle.com> wrote:

> The super.layoutChildren should size every child of the control (which is 
> VBox), but not child's children. The control must finish the layout before 
> children can do theirs. If you need to do layout on some child before that, 
> you can call .layout() on it. It will do it's layout using it's current size. 
> You should have all the bounds correct after that call.
> 
> But that would not work in your case anyway. You have both childs in a HBox, 
> which takes care of resizing the children. This means you need to layout the 
> HBox to get children size and in order to do that, you need HBox to be at 
> it's final size, which will happen during the VBox layout. So your steps 
> would be:
> 1) super.layoutChildren() - VBox is resized to Controls content size
> 2) now the VBox is resized, you can call vbox.layout()
> 3) now HBox is resized, so call hbox.layout()
> 4) children are resized. They have correct layout bounds now. But in order to 
> get correct boundsInParent (but maybe you really need layout bounds?), you 
> need to call .layout() on children too.
> 
> Even if you do all these steps, calling setPrefWidth() on child2 marks the 
> whole tree dirty again. Because HBox needs to resize child2 using it's new 
> PrefWidth. This also means, HBox prefwidth will be different, so it's parent 
> (VBox) must do the same. Ditto with the control. Also, the HBox (VBox, 
> control) may not have enough size to resize child2 to it's pref width, so 
> child1 might be shrinked as a result, which breaks your invariant. You are 
> basically changing the input for HBox's layout (child2.pref size) based on 
> it's output (child1 size), which makes this a loop.
> 
> So in order to really make this work, you need to manage the child nodes 
> directly and compute your layout by yourself. This can be done either by 
> using your own subclass of Pane and overriding it's layoutChildren. Or if you 
> want to do everything in Skin's layoutChildren, you can make the children 
> unmanaged, but then it doesn't really matter where they are in the 
> scenegraph, HBox won't be managing them.
> 
> Hope this helps!
> 
> -Martin
> 
> 
> On 25.7.2014 18:56, Richard Bair wrote:
>> Hmmm. The first question I have is whether boundsInParent is really what you 
>> want to use, vs. layout bounds. But assuming it is what you want, why are 
>> the bounds zero? This is during the layout pass, which is the right place to 
>> be doing what you’re doing. The super layoutChildren call will size 
>> everything based on the contentX, contentY, contentWidth, contentHeight 
>> (http://hg.openjdk.java.net/openjfx/8u-dev/rt/file/4b8d06211312/modules/controls/src/main/java/javafx/scene/control/SkinBase.java).
>>  Is it possible that the parent itself is size 0? boundsInParent should 
>> always be invalidated automatically whenever the width/height/transforms/etc 
>> changes. If not that is definitely a bug (that you can write a simple test 
>> case for to prove).
>> 
>> But my first guess is maybe the parent is size 0 as well, due to something 
>> else (maybe the pref size of the control is 0 to start with or something…)
>> 
>> Richard
>> 
>> On Jul 24, 2014, at 3:34 AM, Werner Lehmann <lehm...@media-interactive.de> 
>> wrote:
>> 
>>> Hi,
>>> 
>>> inside a control skin I have the following code pattern:
>>> 
>>>  protected void layoutChildren(...)
>>>  {
>>>    super.layoutChildren(...);
>>> 
>>>    Node child1 = ...
>>>    Bounds bip = child1.getBoundsInParent();
>>> 
>>>    if (!animating) {
>>>      Node child2 = ...
>>>      child2.setTranslateX(bip.getMinX();
>>>      child2.setPrefWidth(bip.getWidth());
>>>    }
>>>  }
>>> 
>>> The skin scene graph looks roughly like this:
>>> 
>>> VBox
>>>  HBox { ..., child1, ...}
>>>  child2
>>>  ...
>>> 
>>> Everything is layouted just fine but I want to adjust child2.translateX and 
>>> prefWidth based child1 bounds. This does not work initially because 
>>> boundsInParent returns zero components leading to incorrect initial display 
>>> of the control.
>>> 
>>> Seems as if boundsInParent is not yet updated. I guess I could use a 
>>> binding for that but it would conflict with an animation I also have on 
>>> translateX and prefWidth.
>>> 
>>> Maybe there is a better time to make those adjustments on child2?
>>> 
>>> Rgds
>>> Werner
> 

Reply via email to