On Sat, 8 Aug 2026 19:57:30 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/com/sun/javafx/scene/layout/Snapper.java > line 37: > >> 35: * operations used by layout math. >> 36: */ >> 37: public interface Snapper { > > Really like the idea of the `Snapper`. > > What I would really like to see documented is what values developers should > snap. > Maybe we could add all the information we gathered over the years here. > So the conclusion of the mailing list entries, > https://github.com/openjdk/jfx/pull/1948, > https://github.com/openjdk/jfx/pull/1111 (maybe even revive this one after) > and there are probably more. > > Especially: Snap only final values once (before they are returned or used as > x/y/w/h (If I understood that right). Yeah, we can add documentation here, just like how `Measurable` explains the bias system a bit. > Snap only final values once (before they are returned or used as x/y/w/h (If > I understood that right). That's probably best indeed; it depends on what's using those values again whether or not the snapping proved important or not (often the value gets resnapped again, depending on the container, but you shouldn't rely on that). I also discovered a slight bug in how `ceil` works. We shouldn't subtract 1 ulp from the values, as 1 ulp (at Double.MAX_VALUE) can be a huge number. I was wrong when I implemented that (although it works for most "normal" values). Instead I propose that we subtract 1 millionth of a pixel. At `Double.MAX_VALUE` that rounds to 0, while at more reasonable values it will remove any slight floating point errors that could cause a small 1 pixel misalignment. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/2241#discussion_r3741807089
