Hi Andy, I’m trying to understand the use case you’ve outlined here since it doesn’t correspond to anything currently in JavaFX.
> On Dec 10, 2024, at 8:32 AM, Andy Goryachev <andy.goryac...@oracle.com> wrote: > How does the idea of focus delegation works with multiple inner nodes that > are supposed to handle different aspects of a complex control? For example, > a custom combo box-like control may contain an editor (possibly created > dynamically), may be a couple of buttons, may be even two editors. How would > that work? > > In this example, the buttons need focus to respond to ENTER or SPACE key > presses, the editors should respond to key typed and maybe LEFT/RIGHT arrow > keys to switch between the two, and so on. Will the proposed design still > work? Are you proposing a control which delegates events to one inner node that changes over time OR a control which delegates a single key event to multiple inner nodes at once? If the latter, would all of those inner nodes have the focused flag set? Neither of these correspond to a control design I’m familiar with. Can you point to an example? I can’t picture how such a control would appear to the user. In either case would the delegate nodes be accessible via an API like a Spinner’s editor or hidden like a Spinner’s buttons? In the unlikely event that we wanted to deliver key events to a Spinner’s buttons I could imagine using an internal mechanism but that doesn’t make much sense for the publicly accessible editor. Perhaps in your use-case we need two separate mechanisms for delivering key events, this PR and a different one for delegate nodes that aren’t advertised via the control’s API. Martin > > From: openjfx-dev <openjfx-dev-r...@openjdk.org > <mailto:openjfx-dev-r...@openjdk.org>> on behalf of Michael Strauß > <michaelstr...@gmail.com <mailto:michaelstr...@gmail.com>> > Date: Monday, December 9, 2024 at 18:17 > To: > Cc: openjfx-dev <openjfx-dev@openjdk.org> > Subject: Re: [External] : Re: Focus delegation API > > > Yep, this seems unnecessary and counterproductive to me. All we need is to > > drop the target field from the event. > > I can't image that we would ever do this, considering that events have > been there almost from the beginning. We'd break half of the JavaFX > world if we changed the API of events. > In addition to that, this would remove functionality. As of now, you > can add a listener to Scene, and inspect which node is being targeted > by an event. > > > > > 2. ComboBox's skin has installed an event filter on ComboBox > > > > So we have another scenario where different priorities are needed: adding > > event filters. > > Maybe, but that's a different problem than what's being solved by > focus delegation. Focus delegation is all about removing defective > ad-hoc implementations, and offering a pre-made building block for > composite controls. > > > > > 3. However, it must forward the event to the TextField (as otherwise > > the TextField doesn't work), so it fires off a copy of the event > > targeted at TextField. > > > > Maybe instead, there should be a way to send the event to a Node directly, > > without bubbling up. These internal events should never propagate outside > > of the skin's internals. > > Sure, that would be an option. But it's not my preferred solution for > the following reasons: > 1. It's gratuitously different. Instead of using events like they > normally work, control skins would punch a hole through the scene > graph, and deliver the event directly to the delegation target. That > means that the skin's scene graph works differently as the outside > scene graph, as you can't observe events traveling through it. > 2. It requires the skin to implement a complex protocol (register an > event handler, copy the event, punch a hole through to the delegation > target, send off the event), whereas the focus delegation proposal > requires no additional implementation inside of the skin (aside from > selecting the delegation target). > > The advantage of focus delegation is that it just works, even > recursively, across arbitrary levels of abstractions (a skin might > contain another control, which itself has a skin, and so on). No > matter where you listen to events, you will always see exactly what > you'd expect to see: an event that is targeted at the next focused > node. This is another aspect of focus delegation, unrelated to events: > it formalizes the notion of multi-level focus without resorting to > hacks (like FakeFocusTextField). You'll need to solve this no matter > what, as users can click on the TextField. As we discussed, the > ComboBox must be the focus owner even when a user clicks on the > TextField. > > > > > Well, we don't need to add a bunch of weird properties for that (the first > > part). Just send the events to the skin's components directly, preventing > > the bubbling up part. There is no need for Event.target because there is > > no extraneous events being bubbled up, and both CB and TF can process the > > events as they come in. > > First of all, it's only one property (Node.hoistFocus), not a bunch. > And this is not related to events at all, it is a way for skins to > indicate that clicking on an internal node will focus the outside > control. > > The part of focus delegation that fixes the delivery of events in a > scene graph with potentially nested abstractions is done without any > new properties.