On Sat, 8 Aug 2026 19:59:00 GMT, Marius Hanl <[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); }... > > modules/javafx.graphics/src/main/java/javafx/scene/layout/LayoutSupport.java > line 62: > >> 60: alt = computedBoundedHeight(snapper, child, fillHeight, >> contentHeight); >> 61: } >> 62: return left + snapper.snapSizeX(child.minWidth(alt)) + right; > > What I was always wondering here (since this is the same as in `Region`: Why > do we not snap the final value? We especially would also save some cycles if > we do not snap intermediate values and snap them again later. Same on the > other methods - maybe something to improve later? You are right that the final value should be snapped, although in this case the error will be tiny (I think it snaps `left` and `right` so at least we're not summing snapped and unsnapped values here). However, in the interest of proving that this PR doesn't have any functional changes, I didn't do this (slight errors do make some tests fail and they'd need adjusment). For similar reasons I haven't switched `Math.round` to `Math.rint` in this PR, even though we really should do that soon (`Math.round` will mess up large double values, and does a conversion to `long` that we really don't need). ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/2241#discussion_r3741812450
