Summary
-------
Establishes a public API for focus traversal within a JavaFX application.
Problem
-------
While focus traversal is currently implemented in JavaFX, there is no public API to access it.
The lack of public API makes it impossible for a custom skin or custom control to support focus traversal
in the specific direction.
Solution
--------
The focus traversal is provided adding a single method to the **Node** class:
```
public final boolean requestFocusTraversal(TraversalDirection direction)
```
where **TraversalDirection** enumerates the search direction relative to the current node [1].
Typically, controls do not need to handle focus traversal keys explicitly, relying instead on the built-in
traversal logic, unless:
- the traversal is conditional upon the state of the control
- the key used to traverse is used in a non-traversal capacity (one example is the **tab** key in the context of a text editor)
The following example illustrates the use of new API in the context of a text editor conditionally handling
of the **tab** key:
```
Node from = ...
KeyEvent ev = ...
if (!ev.isAltDown() && !ev.isControlDown() && !ev.isMetaDown() && !ev.isShiftDown() && !ev.isShortcutDown()) {
switch (ev.getCode()) {
case TAB:
if (isEditable()) {
insertTab();
} else {
from.requestFocusTraversal(TraversalDirection.NEXT);
}
ev.consume();
break;
}
}
```
Specification
-------------
**modules/javafx.graphics/src/main/java/javafx/scene/Node.java**:
```
+ /**
+ * Requests to move the focus from this {@code Node} in the specified direction.
+ * The {@code Node} serves as a reference point and does not have to be focused or focusable.
+ * A successful traversal results in a new {@code Node} being focused.
+ * <p>
+ * This method is expected to be called in response to a {@code KeyEvent}; therefore the {@code Node}
+ * receiving focus will have the {@link #focusVisibleProperty() focusVisible} property set.
+ *
+ * @param direction the direction of focus traversal, non-null
+ * @return {@code true} if traversal was successful
+ * @since 24
+ */
+ public final boolean requestFocusTraversal(TraversalDirection direction)
```
**modules/javafx.graphics/src/main/java/javafx/scene/TraversalDirection.java**:
```
+/**
+ * Specifies the direction of focus traversal.
+ *
+ * @since 24
+ * @see Node#requestFocusTraversal(TraversalDirection)
+ */
+public enum TraversalDirection {
+ /** Indicates a focus change to the node below the currently focused node. */
+ DOWN,
+ /** Indicates a focus change to the node to the left of the currently focused node. */
+ LEFT,
+ /** Indicates a focus change to the next focusable node. */
+ NEXT,
+ /** Indicates a focus change to the previous focusable node. */
+ PREVIOUS,
+ /** Indicates a focus change to the node to the right of the currently focused node. */
+ RIGHT,
+ /** Indicates a focus change to the node above the currently focused node. */
+ UP;
+}
```
**REFERENCES**
JavaFX JEP: https://github.com/andy-goryachev-oracle/Test/blob/main/doc/FocusTraversal/FocusTraversal-v3.md