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

Firing SimpleUpdateChange does not get propagated properly on SortedList

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • P3
    • 8u60
    • 8u25
    • javafx
    • None
    • Win 8, j8u40-b15

    Description

      Pls look at the following test code:

      you will notice actually two issues, therefore i've created two test rounds.
      I am using an ObservableListWrapper to "simulate" updateChange-Events and to see how they get propagated through a chain of an ObservableList ("UpdateFiringList"), SortedList and FilteredList. This is a constallation commonly used in Controls such as TableViews, ListViews, etc.
      However, as noted in several places that UpdateChangeEvents are "optional" so we implemented our own List (a dummy "UpdateFiringList" for demo purposes).

      So when you run the code you will notice two issues:
      1st: when firing an update, the sorted list will not reflect it (since calling the change on the ListChangeListener is somehow hard-coded to return false, though the toString reflects that it is actually an update)

      2nd: here i am not sure why I get an AIOOBE, i don't think i should. the difference here is that i switched the sequence of sorted/filtered list.

      And one last thing...also when using a real UpdateFiringList using a tableView the selection there seem to be some issues whith the table keeping the currently selected row after receving an update event...especially when in editing mode. however, this might be caused by the above mentioned issues. In fact the TableView does not handle wasUpdated() in its updateSelection() method at all. And since it currently receives an update-event masked as an "add" event (but with the index positions propagated in the change) its selection will shift one row down. In "unsorted" mode though. (If sorting is enabled it does not happen, since the now "add" event will trigger a resort i suppose...)


      package updatetest;

      import java.util.ArrayList;
      import java.util.List;

      import javafx.collections.ListChangeListener;
      import javafx.collections.transformation.FilteredList;
      import javafx.collections.transformation.SortedList;

      import com.sun.javafx.collections.NonIterableChange.SimpleUpdateChange;
      import com.sun.javafx.collections.ObservableListWrapper;

      public class UpdateTests {
      public static void main(String[] args) throws Exception {
      ListChangeListener<Object> listener = change -> {
      while (change.next()) {
      System.err.println("==============================");
      System.err.println("List: " + change.getList().getClass().getCanonicalName());
      System.err.println("change: " + change);
      System.err.println();
      System.err.println(String.format("%-15s %s", "wasAdded", change.wasAdded()));
      System.err.println(String.format("%-15s %s", "wasPermutated", change.wasPermutated()));
      System.err.println(String.format("%-15s %s", "wasRemoved", change.wasRemoved()));
      System.err.println(String.format("%-15s %s", "wasReplaced", change.wasReplaced()));
      System.err.println(String.format("%-15s %s", "wasUpdated", change.wasUpdated()));
      System.err.println();
      System.err.println();
      }
      };

      // setting up 1st sequence of lists (where we expected a wasUpdated=true for the sortedlist too)...
      System.err.println("========================================================");
      System.err.println("1st Test Round...");
      UpdatingFiringListWrapper<Object> updateFiringList = new UpdatingFiringListWrapper<>(new ArrayList<>());
      FilteredList<Object> filterWrap = updateFiringList.filtered(item -> true);
      SortedList<Object> sortWrap = filterWrap.sorted();

      updateFiringList.addListener(listener);
      filterWrap.addListener(listener);
      sortWrap.addListener(listener);

      updateFiringList.add(new Object());
      updateFiringList.fireUpdateForIndex(0);
      System.err.println("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");

      // setting up 2nd sequence of lists (where we get AIOOBE)...
      System.err.println("========================================================");
      System.err.println("2nd Test Round...");
      updateFiringList = new UpdatingFiringListWrapper<>(new ArrayList<>());
      sortWrap = updateFiringList.sorted();
      filterWrap = sortWrap.filtered(item -> true);

      updateFiringList.addListener(listener);
      filterWrap.addListener(listener);
      sortWrap.addListener(listener);

      updateFiringList.add(new Object());
      updateFiringList.fireUpdateForIndex(0);
      System.err.println("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
      }

      private static class UpdatingFiringListWrapper<E> extends ObservableListWrapper<E> {
      public UpdatingFiringListWrapper(List<E> backingList) {
      super(backingList);
      }

      public void fireUpdateForIndex(int index) {
      super.fireChange(new SimpleUpdateChange<E>(index, this));
      }
      }
      }

      Attachments

        Activity

          People

            vadim Vadim Pakhnushev
            smorandijfx Stefano Morandi (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:
              Imported: