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

ListView randomly renders outdated information in case items contain null but only empty flag toggles

XMLWordPrintable

      Steps to reproduce:
      * Create ListView having an initial content of one item, which explicitly is of the value null (not the String "null", but really the Java keyword null).
      * Set a custom ListCell factory so it renders empty cells as the String "(empty)" but non-empty cells representing an item of null as the String "(null)".
      * At runtime dynamically add non-null items.

      Expected result:
      * At any time the ListView correctly shows cells either rendered as non-null items, the word "(empty)" for empty space, or the word "(null)" for items that in fact are null (as no further null-items are added, the list will always show one single word instance of "(null)" as the topmost cell).

      Actual result:
      * Initially the list of nulls is correctly rendered a one top cell showing "(null)" plus some empty cells showing "(empty)". But after adding one or two non-null items, there are more "(null)" cells visible on screen than actually exist.

      Cause:
      * Cell#isItemChanged does not take care of the empty flag. As a result ListCell#updateItem (ListCell.java:464) does not update a cell when it changes from "empty = true, item = null" to "empty = false, item = null" or vice versa. As a result, the original outdated status is rendered still, which is wrong.

      Workaround:
      * If application developers need to use null items in ListViews, they should use ListView<Optional<T>> instead of ListView<T>, as the item reference never will be null then.

      Solution:
      * Modify Cell#isItemChanged from...
              return oldItem != null ? !oldItem.equals(newItem) : newItem != null;
      ...to...
              return !(Objects.equals(oldEmpty, newEmpty) && Objects.equals(oldItem, newItem));
      ...to update the cell in case item still is null but empty flag is modified.

      Side effects:
      * Corrects the same failure in all kinds of virtual flows, but all invocations have to pass empty flag then.

            Unassigned Unassigned
            mkarg Markus Karg
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: