RFR: 8343956: Focus delegation API
John Hendrikx
jhendrikx at openjdk.org
Sat Aug 2 12:34:05 UTC 2025
On Fri, 1 Aug 2025 21:18:53 GMT, Andy Goryachev <andy.goryachev at oracle.com> wrote:
> There is more: I think the kind of issues we see stem from the sub-optimal event dispatching mechanism in JavaFX, the weirdest part of which is creating multiple event instances for the same event.
You've mentioned this a number of times.
Events are copied because FX uses the **source** field to indicate where the receiving event handled was attached. As it bubbles down, the source field must be updated if you want it to contain the correct value. This is actually a performance optimization for cases where a single listener can be attached to say all table cells, and use the `source` field to distinguish which cell was involved.
It's worth noting that this is actually contrary to how the source field is documented in Event's superclass `EventObject`.
A better solution for this would have been to use a `ThreadLocal` to hold the source (or the soon to be finalized `ScopedValue`). It may be possible to back-implement this still without introducing any incompatibilities. It may safe a few copies (although there won't be any performance wins as even MouseMove events are simply too infrequent to matter). Events would still not be fully immutable though as they still have the consumed flag, and custom implementations could allow for tracking additional information (like "ifNotConsumed" actions).
> The key events should be targeting the keyboard focus owner, in case of the Spinner and similar controls, the TextField inside of it. "Control" and "Skin" are abstractions that have nothing to do with that, and the Spinner itself might conceptually be a part of some other custom control.
I disagree. The Control is intended to function as single encapsulated unit. Its substructure is pure happenstance, and any control (no matter how complex) could choose to not use any sub-controls at all but completely implement them anew. The use of sub-controls is for implementation convenience and reuse, but should not be exposed to users. They reason about a `ComboBox` as a single unit. How such a control handles events is up to it (it could for example choose not to forward events at all, but instead directly alter its sub-controls). The forwarding of events here is again for convenience and re-use, not because we want users to see or directly interact with those events, they are part of the black box that a Control embodies.
What Spinner and related controls currently do is taking a poorly constructed short-cut to do as little work as possible to make the Spinner work (poorly duplicating events, and re-firing them at the top level). They didn't have to do it this way at all.
-------------
PR Comment: https://git.openjdk.org/jfx/pull/1632#issuecomment-3146475509
More information about the openjfx-dev
mailing list