Prioritized event handlers

John Hendrikx john.hendrikx at gmail.com
Tue Oct 31 22:40:56 UTC 2023


On 31/10/2023 18:12, Martin Fox wrote:
> I understand John’s point: you want all the user installed filters and 
> handlers across all levels to be processed before switching to system 
> level processing. I also understand this prioritization proposal is 
> designed to push our existing set of system handlers to a separate 
> phase. But is that all we’re talking about here? I need some 
> clarification.

The goal is to give the user (not a control author) a way to handle 
events before the system handles them, no matter where the handler (or 
filter) is installed in the scene graph.  This makes sense as users 
should be the only real "users" of JavaFX nodes and controls, or at 
least it should feel that way.  The sharing of the event infrastructure 
(for memory or performance reasons) by Behaviors and Skins is unexpected 
by users, and unpredictable as it depends on what order handlers are 
installed.  Sharing of this infrastructure is fine, but the user should 
not have to deal with the unpredictability, and preferably wouldn't need 
to be aware of the fact that FX is installing handlers of its own at all 
(but that is a little late).

There are two proposals here to solve this.

1. Using waves, where events are first dispatched to handlers with the 
highest priority, then if unconsumed, dispatched to the next lower 
priority, and so on.

2. Using registation of default handlers per event; events are 
dispatched as normal, but system handlers play nice by only registering 
their interest in the event (ie. they receive the event as normal, but 
don't consume it). When an event fully bubbles up and is unconsumed, the 
default handlers get their turn to consume the event without a new 
dispatch cycle.

>
> Within a given control the order of event processing gets involved. If 
> a Control is subclassed the subclass should get first shot at the 
> event. The same is true for Behaviors and Skins. Beyond that I’m still 
> not clear if the behavior or skin should get the event first or if the 
> skin should get it via the behavior or the other way around. In any 
> case, you’ve got the control, the behavior, the skin, and all of their 
> subclasses trying to sort out the execution order.

I don't think we need to get involved here; there are only two actors, 
the user and the control authorl (and its default behavior).  The 
execution order for default behavior is fixed by the order the handlers 
were installed. If you subclass a control you can be first if you want 
to (in the constructor).  As you are implementing a control, you should 
be using the same priority level as other system handlers would do (like 
Behaviors and Skins) so that a user of your control can override it 
still with a higher priority.

Also, I think if you design controls/behaviors and skins correctly, with 
good separation, the only part that is installing event handlers should 
be the Behaviors. Controls probably shouldn't install handlers, and 
neither should Skins (although some do).

>
> Based on this discussion (and I might be mistaken on this) it sounds 
> like you're trying to handle all this using this proposal, namely 
> registering event handlers with a prioritization scheme. Wouldn’t it 
> be easier to just grab the event and pass it around using Java method 
> calls? Perhaps the call is handleEvent(). A control implements 
> handleEvent() by passing the event off to the behavior’s handleEvent() 
> which passes it off to the skin’s handleEvent(). The skin sends it up 
> the superclass chain by calling super.handleEvent(), etc. so on.

This is not really possible, and is basically describing an alternative 
dispatching mechanism (Node could also pass events to their children); 
events are typed and you can create new event types.  Having a 
`handleEvent` method would require instanceof checks to determine the 
event type.  Having a handle method for each type is impossible as you 
can create new event types that can be sent to existing controls.

It's also not needed; event handlers are already called in order, and 
the order is fixed by how the control gets constructed.  A subclass 
should have sufficient opportunity to be "first" if they want to.  The 
rest of the events should be handled by the behavior, which should be 
aware in which order it wants things installed.  Skins and Controls 
shouldn't be installing event handlers at all.

All this happens on the "system" side.  When you write your own control 
you should install the handlers as system handlers (using scheme 1 or 2 
described above).  The user of the control should however not have to 
care how many handlers are installed by the system, or in what order; 
they should be able to override anything by having a higher priority 
(using scheme 1 or 2 above).

>
> This would make for an easy sell to outside developers. We can tell 
> them that if they subclass a Control and implement handleEvent() they 
> will get events first during the system phase. The same is true if 
> they subclass a behavior or skin. They don’t need to buy into or even 
> see a complicated event prioritization scheme to get exactly what they 
> expect, namely first access to events.

I don't think Control authors have any such problems currently. Skins 
get installed after the first CSS pass, so if you install handlers in 
your subclass constructor you'll always be first.

The proposal is all about allowing users to get to events first when 
using standard controls directly.

--John

>
> But, again, maybe I’m off base here. Let me know.
>
> Martin
>
>> On Oct 30, 2023, at 12:53 PM, Andy Goryachev 
>> <andy.goryachev at oracle.com> wrote:
>>
>> Dear Michael:
>> Thank you, this is very helpful.
>> Questions/Comments:
>> 1. Does this proposal changes the way events are dispatched with 
>> respect to priority?  In other words, does it first go through the 
>> list of all handlers registred on the leaf Node (high priority first, 
>> then lower, then lowest), then bubble up?  Or do they propagate 
>> upwards looking for high priority handlers first, then the process 
>> restarts for lower priorities, as I saw in some previous emails?  (I 
>> could be mistaken)
>> 2. Do you propose to abort event dispatching immediately after the 
>> event is consumed?  This probably should be mentioned earlier in the 
>> Motivation (the problem statement) section.
>> 3. I wonder if three priority levels are sufficient.  Let me 
>> explain.  We have two possible actors who can register an event 
>> listener: the application code and the FX (or, rather more 
>> specifically, the skin and its behavior, whatever that might be).
>> Application code might want to add handlers at three possible priorities:
>>
>>   * App handler must always be called before any fx handler
>>   * App hander does not care
>>   * App handler must always be called after any fx handlers
>>
>> For fx/skin handlers we might have fewer levels:
>>
>>   * Skin handler does not care
>>   * Skin handler must be called after all other skin handlers
>>
>> This situation maps to 5 priorities and 4 effective levels (or 5).
>> We should also mention the fact that when any actor adds two or more 
>> handlers for the same event with the same priority, they get invoked 
>> in the order added.
>> Would you agree, or am I missing some critical aspect of the proposed 
>> solution?
>> Thank you
>> -andy
>>
>> *From:*openjfx-dev <openjfx-dev-retn at openjdk.org> on behalf of 
>> Michael Strauß <michaelstrau2 at gmail.com>
>> *Date:*Friday, October 27, 2023 at 19:41
>> *To:*openjfx-dev <openjfx-dev at openjdk.org>
>> *Subject:*Re: Prioritized event handlers
>>
>> Here is the proposal:
>> https://gist.github.com/mstr2/4bde9c97dcf608a0501030ade1ae7dc1
>>
>> Comments are welcome.
>>
>>
>> On Fri, Oct 27, 2023 at 8:21 PM Andy Goryachev
>> <andy.goryachev at oracle.com> wrote:
>> >
>> > Would it be possible to create a proposal in the JEP format 
>> outlining the proposed public API?
>> >
>> >
>> >
>> > Thank you
>> >
>> > -andy
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/openjfx-dev/attachments/20231031/c655a64c/attachment-0001.htm>


More information about the openjfx-dev mailing list