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
