Yes, you went a step beyond - by including the subclasses and, as a necessity, 
adding a public API (a protected method).  I think you also went further by 
avoiding the property instantiation in the setter if it's not needed, if I read 
the code correctly.

I would advocate against creating public APIs (by using Accessor pattern) for 
subclasses.  The trick of avoiding instantiation is probably not needed for 
event handler properties (it's unlikely the application would set the handler 
to null), but it makes sense for other properties that take a Boolean or a 
simple value.  In these cases, the setter might avoid creating the property if 
the value being set equals to the default value.

In other words, we can probably save even more memory once we go beyond the 
Node class and smarter setters.

-andy




From: Glavo <[email protected]>
Date: Saturday, February 14, 2026 at 09:47
To: Andy Goryachev <[email protected]>
Cc: OpenJFX <[email protected]>
Subject: [External] : Re: Experiment: Node properties

This is the prototype implementation of my idea: 
https://github.com/Glavo/jfx/tree/event-handler-properties<https://urldefense.com/v3/__https://github.com/Glavo/jfx/tree/event-handler-properties__;!!ACWV5N9M2RV99hQ!JYrjeh4cs83mjhiReeU80iO4mWqRgsGzePVdGcbVvtB2kkfolK6Gs2vC2ankqr0Ebmw-9bANAvHp4l2BzZ83Bm8$>

For all event handler properties, it will eliminate the need to construct these 
properties if the user only uses the set methods 
(`setOnAction`/`setOnMousePressed`/...)
and does not directly call the property getter methods 
(`onActionProperty`/`onMousePressedProperty`/...).

Currently, I use HashMap to store the properties in Node, but it can also be 
easily replaced with Andy's FastMap.

I'm not sure if this idea is worth investing more effort in, so I'd like to ask 
for everyone's opinion.

Glavo

On Sat, Feb 14, 2026 at 1:46 PM Glavo 
<[email protected]<mailto:[email protected]>> wrote:
I have another idea: event handle properties (like 
`ButtonBase#onActionProperty()`) are frequently set, but rarely have listeners 
added.
I think we can initialize these properties more lazily.

We can add the following method to `Node`:

protected final <T extends Event> EventHandler<? super T> getEventHandler(final 
EventType<T> eventType) {
    
getInternalEventDispatcher().getEventHandlerManager().getEventHandler(eventType);
}

Then we can implement `onActionProperty()` like this:

private ObjectProperty<EventHandler<ActionEvent>> onAction;

public EventHandler<ActionEvent> getOnAction() {
    return onAction != null ? onAction.get() : (EventHandler<ActionEvent>) 
getEventHandler(ActionEvent.ACTION);
}

public void setOnAction(EventHandler<ActionEvent> value) {
    if (onAction != null)
        onAction.set(value);
    else
        setEventHandler(ActionEvent.ACTION, value);
}

public ObjectProperty<EventHandler<ActionEvent>> onActionProperty() {
    if (onAction == null) {
        onAction = new ObjectPropertyBase<>((EventHandler<ActionEvent>) 
getEventHandler(ActionEvent.ACTION)) {
            @Override
            public Object getBean() {
                return ButtonBase.this;
            }
            @Override
            public String getName() {
                return "onAction";
            }
            @Override
            protected void invalidated() {
                setEventHandler(ActionEvent.ACTION, get());
            }
        };
    }
    return onAction;
}

This allows us to eliminate the allocation of many properties.
Although there is a slight risk (the behavior will change slightly if the user 
updates the handler value with `setEventHandler(ActionEvent.ACTION, ...)` 
before calling `onActionProperty()`/`getOnAction()`), I think it is worthwhile.

Glavo

On Thu, Feb 5, 2026 at 5:17 AM Andy Goryachev 
<[email protected]<mailto:[email protected]>> wrote:
I would like to share the results of a little experiment involving optimization 
of storage of Node properties.  The basic idea is to create a compact fast 
map-like container to hold the rarely instantiated properties in order to 
reduce the application memory footprint.

The savings are not overwhelming, but not exactly zero.  I would imagine this 
optimization might be more interesting in any resource constrained environment 
such as Android / iOS / RaspberryPi.  Please refer to [0] for the details.

I encourage you to try it with your application, to see whether you notice any 
change in memory consumption and/or performance.  Let me know what you think!

Cheers,
-andy


References

[0] 
https://github.com/andy-goryachev-oracle/Test/blob/main/doc/Experiments/NodeProperties.md<https://urldefense.com/v3/__https://github.com/andy-goryachev-oracle/Test/blob/main/doc/Experiments/NodeProperties.md__;!!ACWV5N9M2RV99hQ!JYrjeh4cs83mjhiReeU80iO4mWqRgsGzePVdGcbVvtB2kkfolK6Gs2vC2ankqr0Ebmw-9bANAvHp4l2BRfQIOQs$>

Reply via email to