[External] : Re: Experiment: Node properties

Andy Goryachev andy.goryachev at oracle.com
Tue Feb 17 19:51:25 UTC 2026


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 <zjx001202 at gmail.com>
Date: Saturday, February 14, 2026 at 09:47
To: Andy Goryachev <andy.goryachev at oracle.com>
Cc: OpenJFX <openjfx-dev at openjdk.org>
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 <zjx001202 at gmail.com<mailto:zjx001202 at gmail.com>> 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 <andy.goryachev at oracle.com<mailto:andy.goryachev at oracle.com>> 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$>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/openjfx-dev/attachments/20260217/9c6e13ab/attachment-0001.htm>


More information about the openjfx-dev mailing list