In the documentation you can read for Parent's requestLayout:
> If this parent is either a layout root or unmanaged, then it will be added directly to the scene's dirty layout list, otherwise requestParentLayout will be invoked.
And for the managed property you can read:
> If a managed node's layoutBounds changes, it will automatically trigger relayout up the scene-graph to the nearest layout root
And:
> If an unmanaged node is of type {@link javafx.scene.Parent Parent}, it will act as a "layout root"
So, from this I derive the following:
- A layout root is either a scene root or a Parent (or subclass) which is unmanaged
- If a managed node changes, it will automatically trigger relayout up to the nearest **layout** root
- If requestLayout is called on an unmanaged node (which will almost always be a Parent) then it will be added to the Scene's dirty layout list
In reality however, this doesn't work. Given a StackPane that is unmanaged (and which has been positioned with resizeRelocate). When I add a child to this StackPane (which will be managed by default) then it will quickly encounter the unmanaged parent StackPane, which is considered a layout root.
However, nothing in the code will trigger anything for this layout root. It is not added to a "dirty" list; it doesn't request a pulse, nothing. And it shows; the child does not show up in the UI, nor is layoutChildren called on the StackPane. Inspecting the StackPane shows its "needsLayout" flag is `true` and remains `true`. Only manually calling `layout` or `layoutChildren` on the StackPane will make the child show up.
This IMHO clearly is not according to how it is specified in the docs.
> If this parent is either a layout root or unmanaged, then it will be added directly to the scene's dirty layout list, otherwise requestParentLayout will be invoked.
And for the managed property you can read:
> If a managed node's layoutBounds changes, it will automatically trigger relayout up the scene-graph to the nearest layout root
And:
> If an unmanaged node is of type {@link javafx.scene.Parent Parent}, it will act as a "layout root"
So, from this I derive the following:
- A layout root is either a scene root or a Parent (or subclass) which is unmanaged
- If a managed node changes, it will automatically trigger relayout up to the nearest **layout** root
- If requestLayout is called on an unmanaged node (which will almost always be a Parent) then it will be added to the Scene's dirty layout list
In reality however, this doesn't work. Given a StackPane that is unmanaged (and which has been positioned with resizeRelocate). When I add a child to this StackPane (which will be managed by default) then it will quickly encounter the unmanaged parent StackPane, which is considered a layout root.
However, nothing in the code will trigger anything for this layout root. It is not added to a "dirty" list; it doesn't request a pulse, nothing. And it shows; the child does not show up in the UI, nor is layoutChildren called on the StackPane. Inspecting the StackPane shows its "needsLayout" flag is `true` and remains `true`. Only manually calling `layout` or `layoutChildren` on the StackPane will make the child show up.
This IMHO clearly is not according to how it is specified in the docs.
- relates to
-
JDK-8360940 Layout stops updating when using Parent#setNeedsLayout(true) due to incorrect state management
-
- Open
-
- links to
-
Review(master) openjdk/jfx/1874