On Sun, 9 Aug 2026 01:58:23 GMT, Nir Lisker <[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/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. The caller has some control here based on its own content bias. For example, an `HBox` containing both horizontal and vertically biased controls has to pick one or the other (it will favor horizontal). For the children that were vertically biased, that means they should do a normal calculation -- if such children would internally decide that because they have a bias they should first calculate the other axis, then the layout wouldn't be correctly horizontally biased overall. Also, callers may not have the information of the size of the other axis (or deliberately omitted it due to their own bias), or may want to make adjustments to the value queried of a child (ensuring it is within min/max range, or filling it out with a larger value if filling is allowed). A biased control on its own just doesn't have enough context to decide what the other axis value should be for a biased calculation. This is also a pretty fundamental part of any `Node` that implements the `computeMin/Pref/Max/Width/Height` methods -- it can't be changed now to work differently even if we wanted to. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/2241#discussion_r3743332000
