Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8299662

:focus-within is set incorrectly after some TreeTable selection changes

XMLWordPrintable

    • generic
    • generic

      ADDITIONAL SYSTEM INFORMATION :
      N/A (This bug is not specific to the OS or Java Runtime. It is a pure JavaFX bug.)

      A DESCRIPTION OF THE PROBLEM :
      I have a scenegraph where node A contains a TableView, which itself contains TreeTableRow nodes B and C.
      Working case: When I have only B selected, and then switch to selecting C (via either mouse click or down arrow), the focus is first set false on B, and then true on C. Because of that focus update order, the :focus-widtin is updated correctly.
      Broken case: If instead I have only C selected, and then select B (via either mouse click or up arrow), I'm seeing (in the debugger) that the focus updates from B are still happening prior to those from C. During setting B focus to true, all of its ancestors get their focusWithin correctly set to true. But then afterward, while setting C focus to false, all of its ancestors get their focusWithin set to false, which is only correct for ancestors below the nearest common ancestor of B and C. For all common ancestors of B and C, focusWithin is ending up false afterward, but it should still be true.
      There are two possible fixes for this issue: One is to fix the new code for focusWithin to somehow detect and handle this case. Another is to make changes in TreeTable (and probably also TreeTableView, ListView, etc) so that the row selection changes cause the corresponding focus changes to always set the "false" on the previously selected row before setting "true" on the newly selected row.
      I've confirmed this issue using a debugger breakpoint on line 8240 in Node.java (with JavaFX 19). I believe that this while loop in FocusPropertyBase.set(boolean) is where the root cause of this bug lies.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Select a TreeTableRow (which is not the first one in the table). Then select the previous TreeTableRow.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      All common ancestors of the two TreeTableRow end with focusWithin = true.
      ACTUAL -
      All common ancestors of the two TreeTableRow end with focusWithin = false.

      ---------- BEGIN SOURCE ----------
      I hope this is not necessary in this case, but I could provide a minimal reproduction case on GitHub upon request.
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Stop using JavaFX 19's :focus-within pseudo-class entirely. Go back to the old solution, which involves custom scene graph traversal after every scene focus owner change, to set an equivalent custom pseudo-class (on the nodes where it is needed for styling). For programmatic usage of focusWithinProperty().get(), do a similar upward traversal from the scene's focus owner up to the node whose "focus within" value is needed.

      FREQUENCY : always


            mstrauss Michael Strauß
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: