Promote addEventHandler/removeEventHandler to EventTarget interface

Kevin Rushforth kevin.rushforth at oracle.com
Tue Mar 7 14:34:51 UTC 2023


An incompatible change in a fundamental interface such as EventTarget is 
not something we would want to do, so any proposed changes will need to 
retain compatibility (both binary and source). At a minimum, this means 
that any newly added methods would need to have a default 
implementation, and we would need to look closely at other aspects of 
compatibility.

-- Kevin


On 3/7/2023 1:24 AM, 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?



More information about the openjfx-dev mailing list