Hi Michael,

Did you file a JIRA issue for this one?

I've recently also been doing some rewriting to use the Event system more.  I'm removing custom Scene walking code (and looking at Node.getProperties) to do "event handling", and I've now discovered that it could be done quite a bit nicer by using the provided event mechanism.

I've encountered a few things that annoy me about the event system:

1) I'm making use of Presentation classes (Models) that only associate with things in javafx.base (Event, EventTarget, Properties). These presentations need to register event handlers at some point, but this can only be done on Nodes; having this logic close to the Presentation code makes sense, but it would make them dependent on javafx.graphics; if I could do this via EventTarget, the dependency would not be needed.

2) When you fire an event (via Node.fireEvent for example), there is no feedback you can obtain whether the event was consumed or not as the final event is not returned to check `isConsumed` on (internal calls do have this information, but it is not exposed at the last step).

3) Related to 2), I think EventTarget could also have a method to dispatch events (so you can dispatch an event easily to any target, not just via the convenience method Node#fireEvent).  See this ticket: https://bugs.openjdk.org/browse/JDK-8303209

Perhaps we can work together on this, or if you're not currently working on it I could take a stab at solving all of these issues.

--John
On 07/03/2023 10:24, John Hendrikx wrote:
Hi Michael,

Did you file a JIRA issue for this one?

I've recently also been doing some rewriting to use the Event system more.  I'm removing custom Scene walking code (and looking at Node.getProperties) to do "event handling", and I've now discovered that it could be done quite a bit nicer by using the provided event mechanism.

I've encountered a few things that annoy me about the event system:

1) I'm making use of Presentation classes (Models) that only associate with things in javafx.base (Event, EventTarget, Properties). These presentations need to register event handlers at some point, but this can only be done on Nodes; having this logic close to the Presentation code makes sense, but it would make them dependent on javafx.graphics; if I could do this via EventTarget, the dependency would not be needed.

2) When you fire an event (via Node.fireEvent for example), there is no feedback you can obtain whether the event was consumed or not as the final event is not returned to check `isConsumed` on (internal calls do have this information, but it is not exposed at the last step).

3) Related to 2), I think EventTarget could also have a method to dispatch events (so you can dispatch an event easily to any target, not just via the convenience method Node#fireEvent).  See this ticket: https://bugs.openjdk.org/browse/JDK-8303209

Perhaps we can work together on this, or if you're not currently working on it I could take a stab at solving all of these issues.

--John

On 17/03/2022 21:01, Michael Strauß wrote:
I'm working on an application that uses the JavaFX event system
extensively, and I'm finding it quite hard to use common code for
event handler registrations.

The problem is that the `EventTarget` interface contains no
addEventHandler/removeEventHandler methods, and as a consequence of
that, code that uses `EventTarget` ends up requiring lots of brittle
instanceof tests to call these methods on all the different
implementations of `EventTarget`.

There are three buckets of `EventTarget` implementations:

1) Implementations that declare the following methods:
     <T extends Event> void addEventHandler(EventType<T>,
EventHandler<? super T>);
     <T extends Event> void removeEventHandler(EventType<T>,
EventHandler<? super T>);
     <T extends Event> void addEventFilter(EventType<T>, EventHandler<?
super T>);
     <T extends Event> void removeEventFilter(EventType<T>,
EventHandler<? super T>);
--> Node, Scene, Window, Transform, Task, Service

2) Implementations that declare the following methods:
     <T extends Event> void addEventHandler(EventType<T>, EventHandler<T>);      <T extends Event> void removeEventHandler(EventType<T>, EventHandler<T>);
--> MenuItem, TreeItem, TableColumnBase

(Note that the EventHandler argument ist parameterized as
EventHandler<T>, not EventHandler<? super T> as in the first set of
methods.)

3) Implementations that don't declare any methods to add or remove
event handlers:
--> Dialog, Tab


I think the situation can be improved by promoting the bucket 1
methods to the `EventTarget` interface, so they can be used
consistently across all implementations of `EventTarget`.

This works seamlessly for bucket 1 and bucket 3 implementations.

With bucket 2, there's the problem that, inconsistently, the
EventHandler<T> argument is not a lower-bounded wildcard.
Unfortunately, a method with an EventHandler<T> parameter cannot
implement an interface method that expects EventHandler<? super T>.

However, since the erasure of the method remains the same, changing
the method signature would technically be a binary-compatible change.

Do you think this is a useful improvement?

Reply via email to