On Mon, 3 Aug 2026 16:34:14 GMT, John Hendrikx <[email protected]> wrote:

> This PR shows how virtual layouts could be implemented, as discussed on the 
> mailinglist: 
> https://mail.openjdk.org/archives/list/[email protected]/thread/PLNSQ3ZI63AVKEFKNT5GT6WHAD2GYMPC/
> 
> It would work by making new non-Node containers called Layouts which can 
> contain a mix of either Nodes or other Layouts. Allowing Layouts to nest 
> makes it possible to create a substructure similar to how nesting 
> StackPane/HBox/VBox etc works today. An example is a simple control that has 
> a graphic with a title and subtitle stacked vertically next to it:
> 
> 
> +-------------+-----------------------------------------+
> |             |                                         |
> |             |                 Title                   |
> |             |                                         |
> |   Graphic   +-----------------------------------------+
> |             |                                         |
> |             |                Subtitle                 |
> |             |                                         |
> +-------------+-----------------------------------------+
> 
> For a control to model this, it would need a VBox containing the Title and 
> Subtitle, and an HBox containing the Graphic and the VBox.  The two 
> containers are heavy-weight Nodes and this incurs sufficiently large memory 
> and performance penalties that most standard JavaFX controls will opt to 
> instead roll their own layout code to avoid paying the cost for these.
> 
> With virtual layouts, the control could make use of non-Node containers. The 
> control would add its three children (Graphic, Title and Subtitle) as direct 
> children for display in the scene graph, but would offload their positioning 
> to a virtual layout.  This roughly looks like this:
> 
> 
>   public class TitledGraphic extends Region {
>       private final HBoxLayout root;
> 
>       public TitledGraphic(Node graphic, String titleText, String 
> subtitleText) {
>           // Flat scene graph:
>           getChildren().addAll(graphic, title, subtitle);
> 
>           // Create virtual layout:
>           root = HBoxLayout.of(graphic, VBoxLayout.of(title, subtitle));
>       }
> 
>       @Override
>       protected void layoutChildren() {
>           root.resizeRelocate(0, 0, getWidth(), getHeight());
>       }
> 
>       @Override protected double computeMinWidth(double height)   { return 
> root.minWidth(height); }
>       @Override protected double computeMinHeight(double width)   { return 
> root.minHeight(width); }
>       @Override protected double computePrefWidth(double height)  { return ...

I took a quick look. I assume some of my comments are on code that was left 
as-is, so you can ignore them.

modules/javafx.graphics/src/main/java/javafx/scene/layout/Layoutable.java line 
104:

> 102: 
> 103:     /**
> 104:      * If this element is resizable, sets its layout bounds to the 
> specified

What is an element? A `Node`? A `Layoutable`?

modules/javafx.graphics/src/main/java/javafx/scene/layout/Layoutable.java line 
125:

> 123:         resize(width, height);
> 124:         relocate(x,y);
> 125:     }

Is there a reason to override this? This looks more like a convenience method 
that would have otherwise be `final`.

modules/javafx.graphics/src/main/java/javafx/scene/layout/Measurable.java line 
2:

> 1: /*
> 2:  * Copyright (c) 2010, 2026, Oracle and/or its affiliates. All rights 
> reserved.

Copyright year should be only 2026 If this is a new file.

modules/javafx.graphics/src/main/java/javafx/scene/layout/Measurable.java line 
67:

> 65:      * Indicates that the height of this element should be used as its 
> baseline.
> 66:      */
> 67:     static final double BASELINE_OFFSET_SAME_AS_HEIGHT = 
> Double.NEGATIVE_INFINITY;

Minor: `static final` isn't required.

The docs don't need "This is", can start from "A...".

modules/javafx.graphics/src/main/java/javafx/scene/layout/Measurable.java line 
75:

> 73:      * For a vertical content-bias callers should pass in a height value 
> that
> 74:      * the minimum width should be based on. For a horizontal or null 
> content-bias
> 75:      * the caller should pass in -1.

I haven't looked much at the original code, but us there a way to not give the 
caller a chance to pass the wrong value?
For example, if this method checks itself the content bias, and if it's 
horizontal it treats the input as -1.
Usually when you want the user to use a method in some way, it's best to force 
it. So, if a method says "the super method must be called first", one way of 
doing it would be:

void calc() {
    super.calc();
    finish();
}

abstract void finish();

and the user doesn't need tp implement `calc()` themselves.

modules/javafx.graphics/src/main/java/javafx/scene/layout/Measurable.java line 
82:

> 80:      * <p>
> 81:      * If {@link #maxWidth(double)} is lower than this number, {@code 
> minWidth} takes
> 82:      * precedence.

Is this guaranteed or a requirement?

modules/javafx.graphics/src/main/java/javafx/scene/layout/Measurable.java line 
225:

> 223:      */
> 224:     Orientation getContentBias();
> 225: }

EOF newline.

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

PR Review: https://git.openjdk.org/jfx/pull/2241#pullrequestreview-4890281812
PR Review Comment: https://git.openjdk.org/jfx/pull/2241#discussion_r3742349513
PR Review Comment: https://git.openjdk.org/jfx/pull/2241#discussion_r3742353173
PR Review Comment: https://git.openjdk.org/jfx/pull/2241#discussion_r3742256288
PR Review Comment: https://git.openjdk.org/jfx/pull/2241#discussion_r3742273137
PR Review Comment: https://git.openjdk.org/jfx/pull/2241#discussion_r3742292281
PR Review Comment: https://git.openjdk.org/jfx/pull/2241#discussion_r3742294041
PR Review Comment: https://git.openjdk.org/jfx/pull/2241#discussion_r3742267358

Reply via email to