RFR: 8091673: Public focus traversal API for use in custom controls [v6]

Michael Strauß mstrauss at openjdk.org
Tue Oct 29 18:17:15 UTC 2024


On Mon, 28 Oct 2024 19:20:28 GMT, Andy Goryachev <angorya at openjdk.org> wrote:

>> Public focus traversal API for use in custom controls
>> 
>> https://github.com/andy-goryachev-oracle/Test/blob/main/doc/FocusTraversal/FocusTraversal-v3.md
>> 
>> This work is loosely based on the patch
>> https://cr.openjdk.org/~jgiles/8061673/
>> 
>> And is a scaled down version (with the public traversal policy API removed) of
>> #1555
>
> Andy Goryachev has updated the pull request incrementally with one additional commit since the last revision:
> 
>   visible

Just to complete the picture, I also want to explain why I am strongly against making `focusVisible` writable.

The (much older) `focused` property is an example of bad API design: it is a read-only property that is controlled by the focus subsystem, but in a stroke of complete hackery, also allows subclasses to change its value arbitrarily with the protected `setFocused` method. From this it necessarily follows that the documentation of `focused` is lying:

    /**
     * Indicates whether this {@code Node} currently has the input focus.
     * To have the input focus, a node must be the {@code Scene}'s focus
     * owner, and the scene must be in a {@code Stage} that is visible
     * and active. See {@link #requestFocus()} for more information.
     *
     * @see #requestFocus()
     * @defaultValue false
     */

Since `focused` can be set (and will be set) arbitrarily by subclasses, the presence of this flag does _not_ necessarily indicate that the node has the input focus, it does _not_ necessarily indicate that it is the scene's focus owner, and it does _not_ necessarily indicate that it is in an active scene.

You might think that this is only a small loophole in the implementation, but sadly it is not: Several controls, most notably TableView, abuse the `focused` property for an entirely different purpose. They use it to mark the cell that is currently _selected_, and then hack the `focused` property value to reflect the _selection state_. This selection persists even when the cell doesn't have the input focus (and thus, the `focused` property lies about the input focus).

Not only is this unexpected, it regularly leads users to think that the JavaFX focus system is defective: https://bugs.openjdk.org/browse/JDK-8317426

Repeating the same mistake with `focusVisible` would be crazy.

-------------

PR Comment: https://git.openjdk.org/jfx/pull/1604#issuecomment-2445012994


More information about the openjfx-dev mailing list