-
Enhancement
-
Resolution: Fixed
-
P4
-
None
-
None
-------
Add the "javafx.scene.Node.focusVisible" and "javafx.scene.Node.focusWithin" properties, as well as the corresponding "focus-visible" and "focus-within" CSS pseudo-classes.
Motivation
----------
The W3C CSS Selectors Level 4 specification defines three focus-related pseudo-classes:
"focus", which applies to a node that currently accepts keyboard or mouse input;
"focus-visible", which applies to a focused node that visibly indicates focus, and
"focus-within", which applies to a focused node and any of its parents.
JavaFX currently implements the "focused" property only, which corresponds to the "focus" CSS pseudoclass.
However, many contemporary UI designs do not always indicate focus in the same way that the built-in JavaFX themes do. For example, the Windows 10 theme or modern "Fluent" design implementations generally only indicate the focused element as a consequence of keyboard input. There are also "Material" design implementations with the same behavior.
Adding a "focusVisible" property and the corresponding "focus-visible" pseudoclass to JavaFX will enable application developers to create modern themes that differentiate between logical input focus and visual focus indication.
Adding a "focusWithin" property and the corresponding "focus-within" pseudoclass to JavaFX will enable application developers to more easily achieve nested focus visuals.
Description
-----------
A new property will be added to javafx.scene.Node:
public final boolean isFocusVisible()
public final ReadOnlyBooleanProperty focusVisibleProperty()
This new property will also toggle the "focus-visible" pseudo-class on its scene graph node.
Another new property will be added to javafx.scene.Node:
public final boolean isFocusWithin()
public final ReadOnlyBooleanProperty focusWithinProperty()
The property values are set in conjunction with the value of "Node.focused" as an atomic operation, so it will not be possible for listeners to observe inconsistent states. The value of "Node.focusVisible" will be determined by tracking the input modality that caused a node to acquire focus.
The W3C CSS specification includes some suggestions for the heuristics used to determine whether or not focus should be indicated:
https://drafts.csswg.org/selectors-4/#focus-visible-pseudo
For JavaFX, "Node.focusVisible" would be set in addition to "Node.focused" if a scene graph node gained focus as a consequence of keyboard input. In all other cases, "Node.focusVisible" would not be set on a node.
Additionally, if "Node.focusVisible" is set, it will be cleared when the focused node receives interaction with mouse or touch.
One of the W3C suggestions should not be implemented for JavaFX:
> If the previously-focused element indicated focus, and a script causes focus to move elsewhere, the newly focused element should indicate focus.
> Conversely, if the previously-focused element did not indicate focus, and a script causes focus to move elsewhere, the newly focused element should also not indicate focus.
This behavior is difficult to implement in JavaFX, because there is no way for a node to know whether or not it gained focus programmatically, or as a result of a control skin invoking Node.requestFocus(). Supporting this scenario would require adding new public API and potentially changing lots of skins to account for the distinction between programmatic and mouse-based focus traversal. The impact on existing code would most likely be too large for a very marginal benefit.
The new "focusVisible" and "focusWithin" properties do not change the semantics of the existing "focused" property. Existing JavaFX themes will not be impacted by this change.
Alternatives
------------
As an alternative to implementing this feature, modality-aware focus indication might be implemented in a JavaFX application by installing event handlers on individual controls or on the Scene (in order to intercept the TAB key) and monitoring the "focused" property (or "focusOwner", respectively).
As another alternative to using built-in rules to determine the value of the "focusVisible" property, there could be an API that allows application developers to change these rules. However, it appears that the benefit of doing to is very marginal, while the effort could be very significant.
- csr for
-
JDK-8274798 Support :focus-visible and :focus-within CSS pseudoclasses
- Closed
- duplicates
-
JDK-8090588 Need way to determine if the focused Node is a child of a Parent
- Closed
-
JDK-8092385 Methods for checking focus "inside" a node
- Closed
- relates to
-
JDK-8291502 Mouse or touch presses on a non-focusable region don't clear the focusVisible flag of the current focus owner
- Resolved
-
JDK-8297554 Remove Scene.KeyHandler
- Resolved
-
JDK-8087926 TableView (or ListView, TreeView) should keep the focus ring when a cell in it is editing and has focus
- Open
-
JDK-8297130 ComboBox popup doesn't close after selecting value that was added with 'runLater'
- Resolved
-
JDK-8313956 focusWithin on parents of a newly-added focused node is not updated
- Resolved
-
JDK-8299662 :focus-within is set incorrectly after some TreeTable selection changes
- Closed
-
JDK-8089514 [TableView, TreeView, ListView, TreeTableView] Clicking outside of the edited cell, node, or entry should commit the value
- Open