[External] : Re: Proposal: Focus Traversal API

John Hendrikx john.hendrikx at gmail.com
Thu Sep 19 14:17:18 UTC 2024


My apologies then, I was a bit impatient.  Good luck with the test 
sprint then!

--John

On 18/09/2024 17:13, Andy Goryachev wrote:
>
> Oh, sorry, I did not mean to ignore your comments.  I should have 
> mentioned we are having a bi-annual "test sprint" and work exclusively 
> on the test suite.  You made a lot of good comments that require some 
> thought and careful consideration, for which I simply had no spare CPU 
> cycles last week or this week.  Sorry, will definitely respond in 
> detail early next week.
>
> -andy
>
> *From: *John Hendrikx <john.hendrikx at gmail.com>
> *Date: *Tuesday, September 17, 2024 at 23:05
> *To: *Andy Goryachev <andy.goryachev at oracle.com>, 
> openjfx-dev at openjdk.org <openjfx-dev at openjdk.org>
> *Subject: *Re: [External] : Re: Proposal: Focus Traversal API
>
> 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>
>     <mailto:john.hendrikx at gmail.com>
>     *Date: *Saturday, September 14, 2024 at 09:41
>     *To: *Andy Goryachev <andy.goryachev at oracle.com>
>     <mailto:andy.goryachev at oracle.com>, openjfx-dev at openjdk.org
>     <openjfx-dev at openjdk.org> <mailto: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/20240919/017541d6/attachment-0001.htm>


More information about the openjfx-dev mailing list