Hi Michael,

Although I really like this proposal, I think it may not go quite far enough to address the concerns I raised about user event handlers.

I've given it a bit more thought, and I think the following should be true for user installed handlers:

1) User event handlers should always take priority over internal handlers, regardless of where they are installed in the scene graph 2) Users should have control over when default handlers are allowed to consume events, without also blocking other user event handlers

Your proposal with prioritized event handlers addresses this only partially, and I think before we agree on going forward with your proposal we should make sure that it either addresses all the problems I raised above or at least wouldn't interfere with a further enhancement that would address these problems.

The problems stem from the fact that JavaFX internals are basically sharing the infrastructure provided to users to provide default actions.  To users this is counterintuitive (it was for me) as they expect when installing event handlers that they are the only ones installing such handlers. I would have expected default behavior to work more like default exception handlers; when an event bubbles up unconsumed, only then is it acted upon by a default handler (or in the case of exception handlers, the thread's default exception handler).

Changing this to be the default at this stage is likely to cause problems (even though I think technically it is not violating any documented behavior), so I like the idea of hiding this behind a flag (like the EventHandlerPriority enum does).

The way I propose to do this is as follows.  All handlers can take two forms, they can either handle an event immediately, or they can register they want to handle this event IF nobody else wants it. All current handlers will be changed (automatically) into the latter form by wrapping them.  Skins and Behaviors need not be changed.

What needs to change?

- Events keep track of an ordered list of default handlers which are called when the event is unconsumed

       void registerDefaultHandler(EventHandler handler);

- If an event bubbles up fully without being consumed, the default handlers that were registered are triggered in order, respecting the consumed flag to stop calling further default handlers

- EventHandlers installed via the standard "addEventHandler" are wrapped to do:

       e -> e.registerDefaultHandler(delegateHandler);

This will delay them being called until bubbling completes, but should not have further consequences.

- EventHandlers installed via the new method `addXYZEventHandler` (or some other mechanism) are not wrapped in any way and work like the current handlers, with the exception that they never compete with handlers that only call `registerDefaultHandler`.

I don't think there is a need to guarantee any ordering here, or to keep SYSTEM handlers separated.  The default mechanism takes care the separation.  Skins should always use this mechanism, either by using the standard `addEventHandler` call which does this automatically, or if they want, by using the new `addXYZEventHandler` but taking care to only use it to call `registerDefaultHandler`.

The above change will make it trivial for users to have their event handlers always called first, and gives them the means to act upon events before default handlers can get at them, no matter at what level they're installed.  The only piece still missing is how to block default processing if the user wishes to do so (ie. the user wants to block SPACE from activating a Button, but does not want to block it from bubbling up as a global hotkey or some parent control might have a use for it) -- this can be provided by allowing event handlers to mark the event as having no default event handling (`setEnableDefaultHandling(false)`) or by clearing the default handlers installed so far (perhaps some ordering is still needed here for that to work predictably).

Thanks for reading, please let me know what you think!

--John


On 28/10/2023 04:41, Michael Strauß wrote:
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.goryac...@oracle.com> wrote:
Would it be possible to create a proposal in the JEP format outlining the 
proposed public API?



Thank you

-andy

Reply via email to