[External] : Re: Proposal: Focus Traversal API

John Hendrikx john.hendrikx at gmail.com
Wed Sep 18 06:05:15 UTC 2024


Andy,

As you're not responding to any of the suggestions or any of my 
questions, but are only re-iterating points that I believe are not going 
to be a benefit to the long term viability of FX, I see no point in 
continuing the discussion further.

--John

On 18/09/2024 01:09, Andy Goryachev wrote:
>
> Dear John:
>
> You do bring a lot of good points, no doubt.  And I do agree with a 
> lot of the suggestion, but I still want to emphasize two points:
>
> 1. The backward compatibility should not be dismissed that easily.  
> There is a number of existing applications out there and we do not 
> want to break them.  Whether the behavior is specified or not is 
> irrelevant, we do not want to cause mayhem from the customers and 
> developers alike whose keyboard navigation suddenly changed.
>
> 2. I question the cost benefit analysis of the redesign idea. While I 
> agree with you that it might help with some unusual cases, the overall 
> benefit is rather limited.  The benefit of the proposed solution is, 
> in my opinion, far greater: it allows for custom traversal policies (a 
> feature that has been requested multiple times) and enables focus 
> traversal from custom components, something of a lesser value, but 
> still important.  Exposing the existing APIs is a relatively cheap 
> solution that will give us two features at nearly zero cost.  On the 
> other hand, I doubt that our team, or yourself, are willing commit 
> substantial development effort to redesign the thing to use events.  
> Which brings me to the choice I mentioned earlier: realistically, we 
> have a choice of providing two requested features soon, or never.
>
> I would also encourage other members of the development community to 
> voice their opinion on the subject, perhaps there is something else we 
> can do to move forward.
>
> Thank you
>
> -andy
>
> *From: *John Hendrikx <john.hendrikx at gmail.com>
> *Date: *Saturday, September 14, 2024 at 09:41
> *To: *Andy Goryachev <andy.goryachev at oracle.com>, 
> openjfx-dev at openjdk.org <openjfx-dev at openjdk.org>
> *Subject: *[External] : Re: Proposal: Focus Traversal API
>
> Hi Andy,
>
> First let me say that when it comes to designing an API, you really 
> need to take the time to think the solution through.  The current 
> internal solution was probably kept internal for exactly that reason, 
> insufficient time to work out the kinks and look into alternatives.
>
> An API is almost impossible to change later, so the general rule is 
> that if you're not sure about an API, then its better to have no API.  
> This is why I think it is important that we first look for what the 
> API should look like, then worry about how this can be fitted onto 
> JavaFX.  Making concessions related to the current implementation 
> before having a clear idea of how the API should preferably work is 
> not part of that.  You start making concessions only when it turns out 
> the preferred design would encounter unresolvable problems in the 
> current implementation.
>
> Since I think there is very little public API related to focus 
> traversal, nor is there any specification of how it currently works, I 
> think we have a lot of room to maneuver.  This is why I think we 
> should first reach a consensus on the API, then look how it can be 
> fitted on top of FX.  Sometimes a well thought out API also is a 
> natural fit, and may be easier to migrate to than you think.
>
> On 14/09/2024 00:17, Andy Goryachev wrote:
>
>     Dear John, Everyone:
>
>     Thank you for a thoughtful response!  Some of the ideas you
>     described definitely deserve further consideration.  If I were to
>     summarize:
>
>     1. move the focus traversal logic away from the components and
>     into the Scene
>
>     2. re-implement focus traversal through TraversalEvents rather
>     than responding directly to KeyEvents
>
>     3. (more) standard policies
>
>     4. using CSS
>
>     (there is of course more topics in your response, but let me start
>     with the 4 above)
>
>     #1
>
>     I generally like this idea.  In some sense it is already how
>     things work internally, but without the ability to customize that
>     (i.e. by introducing custom traversal keys, or removing existing
>     ones).  The downside is substantial: not only we'd need to
>     re-design the whole of the focus traversal, but also rework the
>     existing control's behaviors.  Did I mention the risk of
>     regression, given the absence of comprehensive behavioral tests?
>
> There's two things here.
>
> 1. There is no need to re-design the whole focus traversal.  The old 
> internal system can be gradually replaced (it works by directly 
> consuming KeyEvents after all).
>
> 2. Regression.  When nothing is specified, and the fact that controls 
> **ought** to work like other common controls in different UI toolkits, 
> is it a regression when focus traversal works the same as those other 
> platforms, even if it may be a regression from the point of view of 
> FX?  For example, a Spinner will currently react to any mouse key, 
> where as other common toolkits only react to the left mouse button.  
> Is it a regression if FX is adjusted to also only react to the left 
> mouse button?  It's not specified anywhere.
>
> I think we have sufficient space to maneuver here as long as we are 
> not making focus traversal completely different from how it commonly 
> works in UI's.
>
> Can there be regressions versus the current (unspecified) 
> implementation?  Sure, there can be.  Is that necessarily bad?  That 
> depends.  If the new focus traversal works like it does on all other 
> toolkits, then no, it is more of a bug fix.  Did we break something 
> with the new implementation?  That's always possible, but will then be 
> fixed as soon as it is reported.
>
>     #2
>
>     This may or may not be an integral part of #1. Potentially, it
>     allows for injection of events by the application code, as well as
>     simplifies creation of complex custom controls.  The latter
>     becomes possible with the original proposal, so net benefit is
>     limited to the first part, I think.
>
> I think TraversalEvents are quite central to making this an API that 
> will really stand the test of time.  It leverages the existing event 
> system, giving you all the power that comes with it.  You did not 
> answer my question about the TraversalEvents in your design.  Why are 
> the Events when they can't be triggered, filtered or consumed?
>
>     #3
>
>     One obvious possibility is to enable creation of a simple policy
>     based on a list of Nodes.  I must mention one use case that is
>     impossible to cover with pre-defined policy is one where
>     navigation depends on some state.  Such a policy must be
>     implemented programmatically.  I think one property should be
>     sufficient - I am strongly against adding two properties here.
>
> Programmatic escapes can always be achieved by responding directly to 
> a TraversalEvent.  I think however this should be a rare case, and 
> standard policies should really cover almost all use cases.  It may be 
> a gap that should be investigated, and the API adjusted for (usually 
> the "exceptions" are well worth looking into to see if with a tweak 
> they can't become "standard").  As for being "strongly against" having 
> two properties -- that's an odd stance to take without motivating it.  
> It could also be rolled into "one" where the Policy is a record with 
> the two values, but I think we're getting ahead of ourselves here.  
> First the API, then the implementation.
>
> I do think however there is great value in having the Logical and 
> Directional navigation split.  Often you'll only want to replace one 
> of these with a custom policy (or a different standard policy), so 
> that the other navigation method can be used to escape the control. 
> For example, a Toolbar could be tabbed in an out of (using Logical 
> navigation) while the Directional navigation is cyclic (and thus can't 
> be used to escape the control's context).
>
>     #4
>
>     The idea of using CSS to specify traversal policy seems wrong to
>     me: the CSS defines the presentation aspects (styles) rather than
>     behavioral ones.  I know it is possible to set custom skins and
>     the corresponding behavior via CSS, and we know why (skins define
>     the appearance), but we should not go beyond that, in my opinion.
>
> I see no problem styling such properties.  They're FX properties, and 
> it would be very convenient to style them to globally alter how focus 
> works, instead of having to rely on, say, Builders or Factories for 
> controls where traversal policies can be applied.  There are also 
> already properties that don't only influence the look of controls.  
> "-fx-skin" being the most obvious one, but there is also 
> "-fx-focus-traversable", "-fx-context-menu-enabled", 
> "-fx-block-increment", "-fx-unit-increment", "-fx-pannable", 
> "-fx-initial-delay", "-fx-repeat-delay", "-fx-collapsible", 
> "-fx-show-delay", "-fx-show-duration", "-fx-hide-delay", and probably 
> more.  Aside from "-fx-skin" none of these properties have a visual 
> impact, but instead alter behavior.
>
> Note: I'm not saying this needs to be there immediately.  I just want 
> to make sure we're not closing off this direction, as again, it would 
> be a huge hassle to do this programmatically.  In "code" the only 
> things I usually do on my controls are the following:
>
> - I define the container hierarchy (VBox, HBox, which children go where)
> - I set a style name
> - I set anything that unfortunately cannot be CSS styled (things like 
> ALWAYS, SOMETIMES, NEVER grow policies, Grid sizes, etc, things that 
> are clearly "visual" but still can't be styled).
>
> All the rest I don't touch, or want to touch.  Having to select a 
> traversal policy for every control of type X I create is just 
> cumbersome and unnecessary.  There will be a call then to set this 
> "globally", and then there will be the question, do we make something 
> custom with many limitations because it doesn't fit our conceptions of 
> what (FX) CSS is for (ie, not style, but only *visual* style) or do we 
> just expose these properties as Styleable leveraging an existing 
> powerful system with almost zero effort?
>
>     -- 
>
>     There is one more aspect of the problem that I think we should
>     consider.  The current proposal does not change the implementation
>     in any material way, nor does it change the behavior, thus can be
>     done quickly.  The benefit everyone gets from it is ability to
>     trigger focus traversal and to control it via custom policies. 
>     Any other solution will require resources and the bandwidth we
>     currently don't have, which means the /probability/ of it being
>     added to FX is virtually zero.  Let me emphasize, I am not against
>     attempting to discuss or implement the best possible solution, but
>     we should be aware of the limitations of the reality we live in.
>
> "Quickly" and API's are incompatible with each other. There is nothing 
> worse than exposing an API quickly, which then becomes a burden on the 
> system -- I think the current CSS API is a prime example of where 
> "quickly" has gone wrong, costing us tremendous amounts of effort to 
> make even minor changes to it.
>
> I urge you to ignore the current implementation, think thoroughly how 
> (in an ideal world) you would want such an API to work (from a user 
> perspective, not from an implementor's perspective) and only then see 
> how this could be made to fit into JavaFX.
>
> This is exactly what I did.  I did not look at the implementation, 
> although I'm aware of some of it.  I looked at how I as a user of FX 
> am building applications, the struggles I have with it currently, 
> (with controls for example "eating" KeyEvents), and how I would like 
> to be able to adjust focus traversal.  Do I want to respond to 
> "KeyCode.LEFT" or do I want to respond to "TraversalEvent.LEFT"?  Do I 
> also need to respond to "KeyCode.NUM_PAD_LEFT"?  These things should 
> be abstracted, and preferably I should just be able to choose from 
> common navigation standards.  And when I do want to change such a 
> standard, in 99% of the cases that will be the case for all similar 
> controls in my application.  How do I do such things currently if I 
> want to change something for all controls in my application?  I use CSS.
>
> Also I think this can be implemented gradually.  Here's a potential plan:
>
> 1. Have Scene listen to unused KeyEvents and translate them to 
> TraversalEvents
>
> Benefit: gives custom controls a way to respond to keyboard based 
> navigation in a platform agnostic way; this probably already removes 
> the biggest roadblock for custom controls...
>
> Public API: Limited to a new Event
>
> 2. Start converting existing controls to listen to TraversalEvent 
> instead of KeyEvent
>
> This hits a lot of controls, but should be relatively easy to do, and 
> it can be all kept internal for now.  It can be done in a few batches.
>
> Benefit: for each control converted, user can now programmatically 
> trigger focus changes, and by overriding things at Scene level can 
> completely change navigation keys
>
> Public API: none
>
> 3. Implement a number of standard policies internally (OPEN, CONFINED, 
> CYCLIC, IGNORED)
>
> Convert any controls that could use these as their default, removing 
> any custom logic if it happens to match one of the defaults.
>
> Benefit: less code to maintain and debug, gives us experience with 
> which policies make sense and where the gaps are
>
> Public API: none
>
> Order: It is possible to do this before 2, and so some of the control 
> conversions could just consist of removing their custom logic, and 
> selecting a standard policy.
>
> 4. Expose policy property/properties on Parent
>
> Any controls that are not using a custom policy anymore (of type 
> IGNORED) can now be user adjusted.  We don't have to guarantee that 
> each policy makes sense for each control. Changing a default IGNORED 
> policy to a standard one will change the behavior (as intended) but it 
> need not be a "complete" behavior that users like.  This is not FX's 
> problem, and can be improved upon later.
>
> Benefit: users can now change policies on any existing control, even 
> ones with a custom policy; many of the controls may support a switch 
> between OPEN, CONFINED and CYCLIC out of the box.
>
> Public API: new properties on Parent
>
> 5. Perhaps expose some helpful tools to calculate the "next" Node for 
> a given traversal option.
>
> This can be done at any stage, and can be considered completely 
> separate.  It is IMHO a relatively low priority need.
>
> Benefit: less work for control implementors (although they could just 
> "copy" said code)
>
> Public API: Maybe some methods in Node, or some kind of static helper.
>
> 6. CSS styleable properties
>
> If we really want to give power to our users, and impress them with a 
> flexible focus traversal API, then make these properties styleable.
>
> Benefit: allow users to pick any control, and set is policy globally 
> or within a subset of controls (ie. dialogs, popups, etc).
>
> Public API: Nothing in Java, but document as CSS properties
>
> --John
>
>     Thank you,
>
>     -andy
>
>     *From: *openjfx-dev <openjfx-dev-retn at openjdk.org>
>     <mailto:openjfx-dev-retn at openjdk.org> on behalf of John Hendrikx
>     <john.hendrikx at gmail.com> <mailto:john.hendrikx at gmail.com>
>     *Date: *Wednesday, September 11, 2024 at 19:05
>     *To: *openjfx-dev at openjdk.org <openjfx-dev at openjdk.org>
>     <mailto:openjfx-dev at openjdk.org>
>     *Subject: *Re: Proposal: Focus Traversal API
>
>     Hi Andy / List,
>
>     I've given this some thought first, without looking too much at
>     the proposal.
>
>     In my view, focus traversal should be implemented using events,
>     and FX should provide standard handling of these events controlled
>     with properties (potentially even CSS stylable for easy mass
>     changing of the default navigation policy).
>
>     ## KeyEvent and TraversalEvent separation
>
>     I think the cleanest implementation would be to implement a
>     KeyEvent listener on Scene that takes any unused KeyEvents, checks
>     if they're considered navigation keys, and converts these keys to
>     a new type of event, the TraversalEvent. The TraversalEvent is
>     then fired at the original target. The TraversalEvent is
>     structured into Directional and Logical sub types, and has leaf
>     types UP/DOWN/LEFT/RIGHT and NEXT/PREVIOUS.  Scene is the logical
>     place to handle this as without a Scene there is no focus owner,
>     and so there is no point in doing focus traversal.
>
>     This separation of KeyEvents into TraversalEvents achieves the
>     following:
>
>     - User can decide to act on **any** key, even navigation keys,
>     without the system interfering by consuming keys early,
>     unexpectedly or even consuming these keys without doing anything
>     (sometimes keys get consumed that don't actually change
>     focus...).  The navigation keys have many possible dual purposes,
>     and robbing the user of the opportunity to use them due to an
>     overzealous component interpreting them as traversal keys is very
>     annoying.  Dual purposes include for example cursor control in
>     TextField/TextArea, Scrollbars, etc.  The user should have the
>     same control here as these FX controls have.
>
>     - Scene is interpreting the KeyEvents, and this interpretation is
>     now controllable.  If I want a Toolbar (or the whole application)
>     to react to WASD navigation keys, then installing a KeyEvent
>     handler at Scene level or at any intermediate Parent level that
>     converts WASD to UP/LEFT/DOWN/RIGHT Traversal events would affect
>     this change easily.
>
>     - The separation also allows to block Focus Traversal only,
>     without blocking the actual Keys involved.  If I want to stop a
>     Toolbar from reacting to LEFT/RIGHT, but I need those keys higher
>     up in the hierarchy, then I'm screwed.  With the separation, the
>     key events are unaffected, and I can block Toolbars from reacting
>     specifically to traversal events only.
>
>     ## Traversal Policy Properties on Parent
>
>     I think FX should provide several policies out of the box, based
>     on common navigation patterns.  The goal here is to have policies
>     in place that cover all use cases in current FX provided
>     controls.  This will provide a good base that will cover probably
>     all realistic work loads that custom controls may have. The goal
>     is not to support every esoteric form of navigation, instead an
>     escape hatch will be provided in the form of disabling the
>     standard navigation.
>
>     In order to achieve this, I think Parent should get two new
>     properties, which control how it will react to Directional and
>     Logical navigation.  These will have default values that allow
>     navigation to flow from Node to Node within a Parent and from
>     Parent to its Parent when navigation options in a chosen direction
>     are exhausted within a Parent. Custom controls like Combo boxes,
>     Toolbars, Button groups, etc, can change the default provided by a
>     Parent (similar to how some controls change the mouse transparent
>     flag default).
>
>     These two properties should cover all realistic needs, and IMHO
>     should be considered to be CSS stylable in the future to allow
>     easy changing of default policies of controls (ie. want all
>     Toolbars to react differently to navigation keys, then just style
>     the appropriate property for all toolbars in one go).
>
>     Parent will use these properties to install an event handler that
>     reacts to TraversalEvents (not KeyEvents).  This handler can be
>     fully disabled, or overridden (using setOnTraversalEvent).
>
>     - logicalTraversalPolicy
>     - directionalTraversalPolicy
>
>     The properties can be set with a value from a TraversalPolicy
>     enum.  I would suggest the following options:
>
>     - OPEN
>
>     This policy should be the default policy for all Parents.  It will
>     act and consume a given TraversalEvent only when there is a
>     suitable target within its hierarchy.  If there is no suitable
>     target, or the target would remain unchanged, the event is NOT
>     consumed and left to bubble up, allowing its parent(s) to act on
>     it instead.
>
>     - CONFINED
>
>     This policy consumes all TraversalEvents, regardless of whether
>     there is something to navigate to or not.  This policy is suitable
>     for controls that have some kind of substructure that we don't
>     want to accidentally exit with either Directional or Logical
>     navigation.  In most cases, you only want to set one of the
>     properties to CONFINED as otherwise there would be no keyboard
>     supported way to exit your control.  This is a suitable policy for
>     say button groups, toolbars, comboboxes, etc.
>
>     - CYCLIC
>
>     Similar to CONFINED but instead of stopping navigation at the
>     controls logical boundaries, the navigation wraps around to the
>     logical start.  For example, when were positioned on the right
>     most button in a button group, pressing RIGHT again would navigate
>     to the left most button.
>
>     - IGNORED
>
>     This is similar to the mouseTransparent property, and basically
>     leaves the TraversalEvent to bubble up.  This policy allows you to
>     completely disable directional and/or logical navigation for a
>     control. Useful if you want to install your own handler (the
>     escape hatch) but still want to keep either the default
>     directional or logical navigation.
>
>     Possible other options for this enum could include a version that
>     consumes all TraversalEvents (BLOCK) but I don't see a use for it
>     at the moment.  There may also be variants of CONFINED and CYCLIC
>     that make an exception for cases where there is only a single
>     choice available.  A ButtonGroup for example may want to react
>     differently depending on whether it has 0, 1 or more buttons. 
>     Whether these should be enshrined with a custom enum value, or
>     perhaps a flag, or just left up to a custom implementation is
>     something we'd need to decide still.
>
>     ## Use Cases
>
>     1) User wants to change the behavior of a control from its default
>     to something else (ie. a Control that is CYCLIC can be changed to
>     OPEN or CONFINED)
>
>     Just call the setters with the appropriate preferred policy.  This
>     could be done in CSS for maximum convenience to enable a global
>     change of all similar controls.
>
>     2) User wants to act on Traversal events that the standard policy
>     leaves to bubble up
>
>     Just install a Traversal event handler either on the control or on
>     its parent (depending on their needs).  A potential action to an
>     unused Traversal event could be to close a Dialog/Toast popup, or
>     a custom behavior like selecting the first/last item or
>     next/previous row (ie. if I press "RIGHT" and there is no further
>     right item, a user could decide to have this select the first item
>     again in the current Row or the first item in the **next** Row).
>
>     3) User wants to do crazy custom navigation
>
>     Set both policies to IGNORED, then install your own event handler
>     (or use the setOnTraversalHandler to completely override the
>     handler).  Now react on the Traversal events, consuming them at
>     will and changing focus to whatever control you desire.
>
>     4) User wants to change what keys are considered navigation keys
>
>     Install event handler on Scene (or any intermediate Parent) for
>     KeyEvents, interpret WASD keys as UP/LEFT/DOWN/RIGHT and sent out
>     a corresponding Traversal event
>
>     5) User wants to use keys that are considered navigation keys for
>     their own purposes
>
>     Just install a KeyEvent handler as usual, without having to worry
>     that Skins/Controls eat these events before you can get to them
>
>     6) User wants to stop a control from reacting to traversal events,
>     without filtering navigation keys completely
>
>     With the separation of unconsumed KeyEvents into TraversalEvents,
>     a user can now block only the latter to achieve this goal without
>     having to blanket block certain KeyEvents.
>
>     -----
>
>     About the Proposal:
>
>     I think the Goals are fine as stated, although I think we differ
>     on what the Traversal events signify.
>
>     I think CSS support should be considered a possible future goal. 
>     The proposal should therefore take into account that we may want
>     to offer this in the future.
>
>     Motivation looks okay.
>
>     > The focus traversal is provided by the FocusTraversal class
>     which offers static methods for traversing focus in various
>     directions, determined by the TraversalDirection enum.
>
>     I think these methods don't need to be exposed with a good
>     selection of standard TraversalPolicy options.  After all, there
>     are only so many ways that you can do a sensible navigation action
>     without confusing the user, and therefore I think these policy
>     options will cover 99% of the use cases already.  For the left
>     over 1% we could **consider** providing these focus traversal
>     functions as a separate public API, but I would have them return
>     the Node they would suggest, and leave the final decision to call
>     requestFocus up to the caller.  Initially however I think there is
>     already more than enough power for custom implementations to
>     listen to Traversal events and do their own custom navigation.  If
>     it is not similar to one of the standard navigation options, the
>     traverseUp/Down functions won't be of much use then anyway.
>
>     About your typical example:
>
>         Node from = ...
>         switch (((KeyEvent)event).getCode()) {
>         case UP:
>             FocusTraversal.traverse(from, TraversalDirection.UP,
>     TraversalMethod.KEY);
>             event.consume();
>             break;
>         case DOWN:
>             // or use the convenience method
>             FocusTraversal.traverseDown(from);
>             event.consume();
>             break;
>         }
>
>     I think this is not a good way to deal with events.
>
>     1) The event is consumed regardless of the outcome of traverse. 
>     What if focus did not change?  Should the event be consumed?
>
>     2) This is consuming KeyEvents directly, robbing the user of the
>     opportunity to act on keys considered "special" by FX.
>
>     3) This code is not only consuming KeyEvents directly, but also
>     deciding what keys are navigation keys.
>
>     So I think this example code should be different. However, first I
>     expect that in most cases, configuring a different traversal
>     policy on your Parent subclass will already be sufficient in
>     almost all cases (especially if we look at FX current controls and
>     see if the suggested policies would cover those use cases).  So
>     this code will almost never be needed.  However, in the event that
>     you need something even more specific, you may consider handling
>     Traversal events directly.  In which case the code should IMHO
>     look something like this:
>
>         Node from = ...
>
>         Node result = switch(traversalEvent.getEventType()) {
>           case TraversalEvent.UP -> FocusTraversals.findUp(from);
>           case TraversalEvent.DOWN -> FocusTraversals.findDown(from);
>           // etc
>        }
>
>         if (result != null) {
>              result.requestFocus();
>              traversalEvent.consume();
>         }
>
>     Note that the above code leaves the final decision to call
>     requestFocus up to the caller.  It also allows the caller to
>     distinguish between the case where there is no suitable Node in
>     the indicated direction and act accordingly.
>
>     This allows it to NOT consume the event if it prefers its Parent
>     to handle it (if the control doesn't want CYCLIC or CONFINED style
>     navigation).  It also allows it to further scrutinize the
>     suggested Node, and if it decides it does not like it (due to some
>     property or CSS style or whatever) it may follow up with another
>     findXXX call or some other option to pick the Node it wants.  It
>     also allows (in the case of no Node being found) to pick its own
>     preferred Node in those cases.  In other words, it is just far
>     more flexible.
>
>     I'm not sure yet where to place these static helper methods (if we
>     decide to expose them at all initially), or even if they should be
>     static.  Given that its first parameter is always a Node, a
>     non-static location for them could simply be on Node itself, in
>     which case the calling convention would become "Node result  =
>     from.findTraversableUp()" (suggested name only)
>
>     > Focus traversals generate a new type of event, encapsulated by
>     the class TraversalEvent which extends javafx.event.Event, using
>     the event type TraversalEvent.NODE_TRAVERSED.
>
>     What is the point of this event?  If you want to know that focus
>     changed, you can add a listener to Scene.focusOwnerProperty.  What
>     does it mean if I filter this event?  What if I consume it?  I
>     don't think this should be an event at all, unless implemented as
>     I suggested above, where consuming/filtering/bubbling can be used
>     to control how controls will react to navigation events.
>
>     --John
>
>     On 03/09/2024 21:33, Andy Goryachev wrote:
>
>         Dear fellow developers:
>
>         I'd like to propose the public focus traversal API:
>
>         https://github.com/andy-goryachev-oracle/Test/blob/main/doc/FocusTraversal/FocusTraversal.md
>         <https://urldefense.com/v3/__https:/github.com/andy-goryachev-oracle/Test/blob/main/doc/FocusTraversal/FocusTraversal.md__;!!ACWV5N9M2RV99hQ!LnjDXwUbbEymf9b1gkZFia8vuewsVJy6_49It-IKw66U9mS78PjdIPotBpc7AXlSfY7N5xcRXsmcPQhOzavk4z9VkPv-$>
>
>         Draft PR:
>
>         https://github.com/openjdk/jfx/pull/1555
>         <https://urldefense.com/v3/__https:/github.com/openjdk/jfx/pull/1555__;!!ACWV5N9M2RV99hQ!LnjDXwUbbEymf9b1gkZFia8vuewsVJy6_49It-IKw66U9mS78PjdIPotBpc7AXlSfY7N5xcRXsmcPQhOzavk49fH_P2p$>
>
>         Your comments and suggestions will be warmly accepted and
>         appreciated.
>
>         Thank you
>
>         -andy
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/openjfx-dev/attachments/20240918/30a02357/attachment-0001.htm>


More information about the openjfx-dev mailing list