<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@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;}
/* Style Definitions */
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.EmailStyle19
        {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;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style>
</head>
<body lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed SS16"">Thank you.<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"">I completely disagree with the idea of adding a single method to Node and introducing 6 way enum, for the reasons provided earlier.<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"">Having said that, I am more interested in moving forward.  If everyone feels more comfortable with Node + enum combo, I'll make the change.<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"">Thank you for a lively discussion.<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">openjfx-dev <openjfx-dev-retn@openjdk.org> on behalf of John Hendrikx <john.hendrikx@gmail.com><br>
<b>Date: </b>Monday, October 21, 2024 at 23:46<br>
<b>To: </b>openjfx-dev@openjdk.org <openjfx-dev@openjdk.org><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">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>
> <andy.goryachev@oracle.com> 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">
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">https://github.com/openjdk/jfx/pull/1604</a><o:p></o:p></span></p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>