<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
Hi Andy,<br>
<br>
I think this updated proposal is a good one. It provides the minimum
API to allow applications to do what they cannot do today, without
locking us into the API needed to directly support traversal
policies or defining new traversal events. Those could be added in a
future release, if there is sufficient demand once this is done.<br>
<br>
Minor typos:<br>
<br>
In the list of goals:<br>
<br>
> to introduc a public API for a focus traversal policy<br>
<br>
"introduce"<br>
<br>
In your example:<br>
<br>
> from.traverse(from, TraversalDirection.NEXT);<br>
<br>
remove the "from" argument.<br>
<br>
-- Kevin<br>
<br>
<br>
<div class="moz-cite-prefix">On 10/22/2024 3:25 PM, Andy Goryachev
wrote:<br>
</div>
<blockquote type="cite" cite="mid:DS0PR10MB62008793BA084CDD074CD4EDE54C2@DS0PR10MB6200.namprd10.prod.outlook.com">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style>@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}@font-face
{font-family:"Yu Gothic";
panose-1:2 11 4 0 0 0 0 0 0 0;}@font-face
{font-family:Aptos;
panose-1:2 11 0 4 2 2 2 2 2 4;}@font-face
{font-family:"Iosevka Fixed SS16";
panose-1:2 0 5 9 3 0 0 0 0 4;}@font-face
{font-family:"Times New Roman \(Body CS\)";
panose-1:2 11 6 4 2 2 2 2 2 4;}@font-face
{font-family:"\@Yu Gothic";
panose-1:2 11 4 0 0 0 0 0 0 0;}p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
font-size:10.0pt;
font-family:"Aptos",sans-serif;}a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}span.EmailStyle20
{mso-style-type:personal-reply;
font-family:"Iosevka Fixed SS16";
color:windowtext;}.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;
mso-ligatures:none;}div.WordSection1
{page:WordSection1;}</style>
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">Updated
the API and the JEP per feedback comments:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><a href="https://github.com/andy-goryachev-oracle/Test/blob/main/doc/FocusTraversal/FocusTraversal-v3.md" moz-do-not-send="true" class="moz-txt-link-freetext">https://github.com/andy-goryachev-oracle/Test/blob/main/doc/FocusTraversal/FocusTraversal-v3.md</a><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><a href="https://github.com/openjdk/jfx/pull/1604" moz-do-not-send="true" class="moz-txt-link-freetext">https://github.com/openjdk/jfx/pull/1604</a><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">Thanks,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">-andy<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""><o:p> </o:p></span></p>
<div id="mail-editor-reference-message-container">
<div>
<div>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal" style="margin-bottom:12.0pt"><b><span style="font-size:12.0pt;color:black">From:
</span></b><span style="font-size:12.0pt;color:black">Andy Goryachev
<a class="moz-txt-link-rfc2396E" href="mailto:andy.goryachev@oracle.com"><andy.goryachev@oracle.com></a><br>
<b>Date: </b>Tuesday, October 22, 2024 at 12:22<br>
<b>To: </b>John Hendrikx
<a class="moz-txt-link-rfc2396E" href="mailto:john.hendrikx@gmail.com"><john.hendrikx@gmail.com></a>,
<a class="moz-txt-link-abbreviated" href="mailto:openjfx-dev@openjdk.org">openjfx-dev@openjdk.org</a>
<a class="moz-txt-link-rfc2396E" href="mailto:openjfx-dev@openjdk.org"><openjfx-dev@openjdk.org></a><br>
<b>Subject: </b>Re: Proposal: Focus Traversal API<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">Thank
you.</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">I
completely disagree with the idea of adding a single
method to Node and introducing 6 way enum, for the
reasons provided earlier.</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">Having
said that, I am more interested in moving forward.
If everyone feels more comfortable with Node + enum
combo, I'll make the change.</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">Thank
you for a lively discussion.</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">-andy</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16""> </span><o:p></o:p></p>
<div id="mail-editor-reference-message-container">
<div>
<div>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal" style="margin-bottom:12.0pt"><b><span style="font-size:12.0pt;color:black">From:
</span></b><span style="font-size:12.0pt;color:black">openjfx-dev
<a class="moz-txt-link-rfc2396E" href="mailto:openjfx-dev-retn@openjdk.org"><openjfx-dev-retn@openjdk.org></a> on
behalf of John Hendrikx
<a class="moz-txt-link-rfc2396E" href="mailto:john.hendrikx@gmail.com"><john.hendrikx@gmail.com></a><br>
<b>Date: </b>Monday, October 21, 2024 at
23:46<br>
<b>To: </b><a class="moz-txt-link-abbreviated" href="mailto:openjfx-dev@openjdk.org">openjfx-dev@openjdk.org</a>
<a class="moz-txt-link-rfc2396E" href="mailto:openjfx-dev@openjdk.org"><openjfx-dev@openjdk.org></a><br>
<b>Subject: </b>Re: Proposal: Focus
Traversal API</span><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">I already like this
suggestion very much, as it is simple,
concise and
<br>
located exactly where you'd expect it (near
`requestFocus`). It offers <br>
the navigation options that FX offers in a
programmatic way and doesn't <br>
need to cater to other methods, only what FX
offers.<br>
<br>
I also have an alternative approach that
could be considered. The user <br>
model would be something like this:<br>
<br>
LogicalNavigation.NEXT.find(currentNode).ifPresent(Node::requestFocus);<br>
<br>
This is more wieldy, but does offer a
natural API that allows extension <br>
as `LogicalNavigation.NEXT` is an
implementation of an interface <br>
(provisional name Navigator):<br>
<br>
interface Navigator {<br>
Optional<Node> find(Node
node); // finds a next node given <br>
a starting point<br>
}<br>
<br>
Then implementations of these can be made
available as constants or <br>
enums, for example:<br>
<br>
enum LogicalNavigation implements
Navigator {<br>
NEXT(InternalImplementation::next),<br>
PREVIOUS( ... );<br>
<br>
...<br>
}<br>
<br>
The above API offers a natural way to only
"predict" the focus, and only <br>
act on it if you want.<br>
<br>
--John<br>
<br>
On 21/10/2024 19:13, Michael Strauß wrote:<br>
> I think it is a good idea to do the
non-controversial part of this<br>
> feature first.<br>
><br>
> With regards to the API, I would prefer
a single instance method on Node:<br>
><br>
> Node
moveFocus(FocusTraversalKind);<br>
><br>
> Where FocusTraversalKind is an enum
with values UP, DOWN, LEFT, RIGHT,<br>
> NEXT, and PREVIOUS.<br>
> Note that it is not called
"TraversalDirection", because NEXT and<br>
> PREVIOUS are logical types of
navigation, not directional ones.<br>
> The return value is the node that will
receive focus as a result of<br>
> this method call.<br>
><br>
> The name "moveFocus" pairs with
"requestFocus" (and we could also<br>
> potentially add "predictFocus" to get
the node that would receive<br>
> focus, without actully changing focus).<br>
><br>
> Having a single instance method allows
for easier composition, as I<br>
> can now pass the FocusTraversalKind to
methods, which is a bit awkward<br>
> to do with method references.<br>
><br>
> For example, I could write a method:<br>
><br>
> /*<br>
> * Moves the focus if allowed.<br>
> * Returns true if the focus
changed, false otherwise<br>
> */<br>
> boolean
moveFocusIfAllowedByBusinessLogic(Node node,<br>
> FocusTraversalKind kind) {<br>
> return switch (kind) {<br>
> case UP, DOWN -> false;<br>
> default -> isAllowed()
&& node.moveFocus(kind) != node;<br>
> };<br>
> }<br>
><br>
> If I would instead pass a method
reference to<br>
> FocusTraversal::traverseNext into my
custom method, I'm very limited<br>
> in what I can do with it.<br>
> For example, I can't switch() on the
method reference, I can't change<br>
> it with custom logic, etc.<br>
><br>
><br>
> On Fri, Oct 18, 2024 at 10:25</span><span style="font-size:11.0pt;font-family:"Arial",sans-serif"> </span><span style="font-size:11.0pt">PM Andy Goryachev<br>
> <a class="moz-txt-link-rfc2396E" href="mailto:andy.goryachev@oracle.com"><andy.goryachev@oracle.com></a>
wrote:<br>
>> Dear fellow developers:<br>
>><br>
>><br>
>><br>
>> Thank you for providing a lively
discussion here in the mailing list, and in
the PR.<br>
>><br>
>><br>
>><br>
>> A surprisingly large number of
objection was voiced, among them in no
particular order (please correct me if I
missed anything):<br>
>><br>
>><br>
>><br>
>> - no need for the traversal policy
API, developers have all the tools they need<br>
>><br>
>> - rather than providing
Parent.traversalPolicy, the whole thing
should be delegated to Scene<br>
>><br>
>> - no need for custom traversal
policies, provide a number of standard
policies (e.g. cyclic/logical; or via enum
if possible)<br>
>><br>
>> - introducing a new category of
traversal events (later deemed unnecessary)<br>
>><br>
>> - adding two properties to Parent
for directional and logical traversal<br>
>><br>
>> - desire to be able to configure
traversal policy via CSS<br>
>><br>
>> - focus traversal methods should be
instance methods in the Node class<br>
>><br>
>><br>
>><br>
>> Also, the discussion reiterated
some of the design problems we have in
JavaFX, namely<br>
>><br>
>><br>
>><br>
>> - controls consuming key events
that effect no change in the control's state<br>
>><br>
>> - interference between controls'
key handling and Scene's accelerators<br>
>><br>
>> - undetermined priority of event
handlers registered by the skin and the
application<br>
>><br>
>><br>
>><br>
>> I still believe there is a value in
providing the traversal policy APIs, but
given the general sentiment in the feedback,
I think the right approach would be to scale
down the proposal to leave only the focus
traversal API [0], addressing a single use
case of the custom components [1].<br>
>><br>
>><br>
>><br>
>> I am sad to think that there will
be no support for custom traversal policies
in JavaFX in the foreseeable future, as it
seems highly unlikely that my company will
sponsor a major redesign of the focus
subsystem. I hope there is a non-zero
chance of the open source community coming
together and designing an alternative that
satisfies everyone, so maybe not all is
lost.<br>
>><br>
>><br>
>><br>
>> Please let me know what you think
of the new proposal.<br>
>><br>
>><br>
>><br>
>> Thanks,<br>
>><br>
>> -andy<br>
>><br>
>><br>
>><br>
>><br>
>><br>
>> [0] <a href="https://github.com/andy-goryachev-oracle/Test/blob/main/doc/FocusTraversal/FocusTraversal-v2.md" moz-do-not-send="true" class="moz-txt-link-freetext">
https://github.com/andy-goryachev-oracle/Test/blob/main/doc/FocusTraversal/FocusTraversal-v2.md</a><br>
>><br>
>> [1] JDK-8091673 Public focus
traversal API for use in custom controls<br>
>><br>
>> [2] Draft PR <a href="https://github.com/openjdk/jfx/pull/1604" moz-do-not-send="true" class="moz-txt-link-freetext">https://github.com/openjdk/jfx/pull/1604</a></span><o:p></o:p></p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<br>
</body>
</html>