I see, you want to avoid the overhead of the intermediate pane(s), mainly 
because the Node class is too heavy.

I wonder if a less invasive solution for that problem would be to put the 
rarely used properties into a hash table instead, something along the lines of 
https://github.com/andy-goryachev-oracle/jfx/pull/20 .

This way we'd eliminate most of the overhead and do it without adding any 
public APIs (apart from exposing the layout classes once they mature).  The 
reason I dislike the idea of Layoutable is because it impacts all the Node's 
descendants, even though conceptually it only belongs to Parent.

-andy




From: John Hendrikx <[email protected]>
Date: Thursday, July 16, 2026 at 03:37
To: Andy Goryachev <[email protected]>; [email protected] 
<[email protected]>
Subject: Re: [External] : Proposal to split off layout and layout metric 
methods from Node to interfaces it implements

This Message Is From an External Sender
This message came from outside your organization.
Report 
Suspicious<https://us-phishalarm-ewt.proofpoint.com/EWT/v1/ACWV5N9M2RV99hQ!NB26dgOv2uIPHxPgvfKeeB8wifO7UNM_qPE-ApXJee7-lnArw9ivFU3vA1OKWzk7SOFWi4LZ-I0apqiGweab_xqLu69yFJ24pTitxw$>


On 15/07/2026 20:10, Andy Goryachev wrote:
Right, static layouts will only work in simple cases, the more complicated ones 
will require an instance.

My point is that if we are laying out Nodes, there is no need to invent another 
abstraction layer because Nodes contain all the required data.  This will 
eliminate the "Bonus" section which some seem to like.

The Bonus section is bonus, all else is still needed.

The problem is: we're not laying out only Nodes.  We're also laying out 
potentially light-weight layout containers (that purposely are not Nodes).  So 
the list of things to lay out can contain a mix of Nodes and Layouts.  A layout 
acts as a Node, but isn't one.

Let's take my example: A TitleSubtileControl that can have a Graphic on the 
left and on the right two lines of text one above the other (title and subtitle)

- The TitleSubtileControl is a normal Node, that wants to avoid having a nested 
HBox and VBox so it creates:
  - A HBoxLayout within it nested a VBoxLayout and a Graphic (a Layout and a 
Node)
  - A VBoxLayout within it nested a Title and a Subtitle Text (two Nodes)
  - It adds only the Nodes to the scenegraph as its children (so: 
titleSubtitleControl.getChildren().addAll(graphic, title, subtitle)

Now the problem is, HBoxLayout needs to accept a VBoxLayout (not a Node) and a 
Graphic (a Node).  The only way to do that is to store them as Objects since 
they don't share a common ancestor; VBoxLayout can't be a Node because that 
would pull in a zillion private fields and properties making it "heavy".

The solution I presented is to create this common ancestor, which I've dubbed 
Layoutable. It contains methods that only layouts need (like VBoxLayout or VBox 
itself).  These methods already exist on Node, they're just not grouped as part 
of an interface it implements.  Doing such a change is source and binary 
compatible.

So the end state is:

- VBoxLayout implements Layoutable (but is not a Node!)
- Node implements Layoutable

When VBoxLayout and a Node are nested in HBoxLayout, the HBoxLayout can treat 
both as Layoutable's making Layouts clean (there would have to be a million 
instanceof checks otherwise, or we'd need to wrap Nodes in a LayoutableWrapper).

Sorry for the confusion with the bonus section, I hope this clarifies why it 
would a good move to have a common ancestor for Nodes and Layouts.

--John


I guess what I am trying to say is that code reuse (and removal of 
hard-to-maintain code replication) should be the primary goal, while adding new 
features (Canvas) should come last, if ever.

-andy


From: John Hendrikx <[email protected]><mailto:[email protected]>
Date: Wednesday, July 15, 2026 at 10:49
To: Andy Goryachev 
<[email protected]><mailto:[email protected]>; 
[email protected]<mailto:[email protected]> 
<[email protected]><mailto:[email protected]>
Subject: Re: [External] : Proposal to split off layout and layout metric 
methods from Node to interfaces it implements

This Message Is From an External Sender
This message came from outside your organization.
Report 
Suspicious<https://us-phishalarm-ewt.proofpoint.com/EWT/v1/ACWV5N9M2RV99hQ!NB26ligkesgE1bPqfVnUuELFLOB1vmX7gUMnmgafz5PcT3tCIOQ6CH3Y_2TlHn6_oY4aATre-aOhU774w6HiWg4mLvHIFUYvM_SnXw$>



On 15/07/2026 19:32, Andy Goryachev wrote:

  *
Yes, they don't need to be public immediately, although they definitely can be 
as they're nothing more than a "copy" of the layout panes we already have, but 
packaged without the Node dependency.  We would need pretty quickly the Node 
implementing the Layoutable interface (which opens the path for people writing 
their own virtual layouts).


One thing I wanted to mention is that these layout classes can probably be 
static (unless they need to keep some internal state like HBox.tempArray).  If 
I understand the logic, there is no need for the Layoutable interface either, 
the owner Node is merely delegates layoutChildren() to the corresponding layout 
class, passing all the necessary information (scale, snap, etc.)

If you want virtual layouts to compose, you need to be able to point at 
something.  Let's say you have a simple layout:

    HorizontalLayout[ Graphic + Text ]

This can be relatively static, agreed.

However, if you want something more complicated:

    HorizontalLayout[ Graphic + VerticalLayout[Title + Subtitle] ]

...then how would the static call look like to HorizontalLayout?

Furthermore, HorizontalLayout would need to accept both Node and Layout somehow 
if they don't implement a common interface (so Object[] ?)

Also, layouts often have a ton of parameters to tweak: padding, alignment, 
spacing, margins, snapToPixel, etc... that's a lot of things to pass in to a 
static layout.  This quickly invites a "parameter" object, at which point you 
can just make the Layout an instance (which gives more flexibility for also 
caching things and other interal bookkeeping).

The best you can do as a "static" solution is to have some helpers, like the 
SpaceDistributor class I once created, but the actual layouts are *far* more 
complicated, and I don't think you can easily get away with having them just be 
a static method call.

In other words, it might be possible to achieve the main goal of code reuse 
without any changes to the public APIs.  The layout classes can be made public 
later, once matured.

Only if you accept the layouts would be extremely limited (no mixing of Layouts 
and Nodes).

Regardless, there wouldn't be any changes to existing public API's by having 
Node implement Layoutable.  At most, there would be one or two methods to offer 
a better abstraction for just plainly exposing "getProperties()" on Layoutable. 
 Implementing an interface that exposes methods that Node already has is a 
source and binary compatible change.

--John

What do you think?

-andy

Reply via email to