RFR: 8343956: Focus delegation API [v3]

Andy Goryachev andy.goryachev at oracle.com
Wed Jul 30 22:00:05 UTC 2025


I think I narrowed down my objection to this proposal.  My main problem with it is that it tries to add properties to the wrong entity (Node).

In a typical application, the focus traversal requirements usually come in the context of a higher level aggregate such as a form, or a panel, or a window, and not the individual nodes.  An example from Swing and AWT is the FocusTraversalPolicy class.  This is no accident - the focus traversal might be dynamically dependent on other aspects of the UI state, for example the kind of information already present in a form.

Trying to implement it at the Node level would be extremely difficult, and one will inevitably resolve to creating a kind of controller that determines the traversal order at the higher level.

A better approach, in my opinion, would be to revive the FocusTraversalPolicy API [0], [1] (after some modernization).  The most important feature that would be added is enabling ability to plug in a custom traversal policy that can address any application-level requirements with relative ease.

What do you think?

-andy


References

[0] https://github.com/andy-goryachev-oracle/Test/blob/main/doc/FocusTraversal/FocusTraversal.md

[1] https://github.com/openjdk/jfx/pull/1555



From: openjfx-dev <openjfx-dev-retn at openjdk.org> on behalf of Michael Strauß <mstrauss at openjdk.org>
Date: Wednesday, July 16, 2025 at 23:33
To: openjfx-dev at openjdk.org <openjfx-dev at openjdk.org>
Subject: Re: RFR: 8343956: Focus delegation API [v3]
On Mon, 14 Jul 2025 18:36:48 GMT, Martin Fox <mfox at openjdk.org> wrote:

> In this PR setting hoistFocus on a control only updates the flag in the control itself. What if the control’s skin introduces sub-nodes? I would assume that setting hoistFocus on a control would automatically set that flag on the control’s entire skin. Is that correct? If so what are the mechanics of making that happen?

The `hoistFocus` flag only applies to the node on which it is set, and not to its descendants. Consider a control that uses a sub-control in its skin. If the sub-control also delegates focus to one of its own descendants, then those descendants individually get to decide whether to hoist focus to the sub-control; and if so, the sub-control will further hoist focus to the outer control.

Automatically setting this flag precludes the option to have sub-nodes that _don't_ hoist focus. Consider a Button: it has an optional sub-node (`graphic`) that is independently focusable and doesn't hoist focus. A custom button could conceivably have both: a delegate (maybe a text field), as well as an independently focusable sub-node.

> It seems hoistFocus is serving two roles. One is an optimization so that requestFocus knows whether it should walk the scene graph looking for a focus-scope node. For that use the flag should be propagated through descendants in the graph. But it’s also being proposed as a hoisting barrier e.g. when it’s _not_ set it prevents focus from hoisting upward even if there's a focus-scope node higher up in the graph. But a barrier applies just to a single node and should not be propagated. So I’m having a difficult time figuring out when and how this flag should be propagated through the tree. But I’m no expert on skins so maybe I’m assuming this is more complicated than it actually is.

`hoistFocus` is not an optimization, it's semantically relevant in the way I described.

-------------

PR Review Comment: https://git.openjdk.org/jfx/pull/1632#discussion_r2212398078
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/openjfx-dev/attachments/20250730/f6a82bab/attachment.htm>


More information about the openjfx-dev mailing list