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

ListChangeListener next() and/or getAddedSubList() returns items from previous change


    • Type: Bug
    • Status: Closed
    • Priority: P4
    • Resolution: Duplicate
    • Affects Version/s: 8u25, 8u31
    • Fix Version/s: None
    • Component/s: javafx
    • Labels:
    • Environment:

      Windows 8, 64 bit platform

    • Subcomponent:


      Between Java 7_71 and Java 8_31, the behaviour of getAddedSubList() has changed such that if there are 2 changes, the second call to change.next() returns items that are a part of the first change. This seems to happen in recursive scenarios where onChanged() has not yet returned, and a new change is triggered from with onChanged(). Please see attached test program, executing the main method. Run in version 7_71 to see the expected behaviour and in 8_31 to see the problematic behaviour. This also occurs in 8_25

      The program has an observable list. Two items are added to the observable list at once using addAll(). Then from within the onChanged() method, another item is added using the add(). An if statement has been added to limit the recursive nature of this program to one recursive call. Upon adding the final element, onChanged() is called a second time, next() is called to obtain the changed elements using getAddedSubList() however, the sublist contains elements from the first change. The program writes to standard output, the item, along with the index of the change obtained from getFrom() and getTo()

      In Java 7_71, the program returns as expected:
      Change Detected: First One 0 2
      Change Detected: Second One 0 2
      Change Detected: One more 2 3

      Here we see "First One" and "Second One" added as one batch, with the change ranging from index 0 to index 2. "One More", the final one, is added with the change going from index 2 to index 3

      However, in Java 8_31:
      Change Detected: First One 0 2
      Change Detected: Second One 0 2
      Change Detected: First One 0 3
      Change Detected: Second One 0 3
      Change Detected: One more 0 3

      Here we see "First One" and "Second One" as expected, however in the recursive case, the change reports "First One". "Second One" again, along with "One More", with the changed indexed from 0 to 3.

      This test program was distilled down from a more complex program which uses the ListChangeListener as a queue for dealing changes atomically, each item within the change has the potential to trigger other changes in recursive manner. By calling next(), the "change" should be fully represented and should not rely on the method returning in order for the state of the following change to be accurate.

      --------test program------------

      package com.test;

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

      import javafx.application.Application;
      import javafx.application.Platform;
      import javafx.collections.FXCollections;
      import javafx.collections.ListChangeListener;
      import javafx.collections.ObservableList;
      import javafx.stage.Stage;

      public class ListChangeListenerBug extends Application {

      private ObservableList<String> list = FXCollections.observableArrayList();
      private boolean limitRecursion = true;//limit the recursion to one

      public void start(Stage stage) {
      list.addListener(new ListChangeListener<String>() {

      public void onChanged(javafx.collections.ListChangeListener.Change<? extends String> c) {
      List<String> copiedList = new ArrayList<String>();
      for (String string : c.getAddedSubList()) {//grab the items in the change and store them in a new collection as to not cause a concurrent list modification exception.
      System.out.println("Change Detected: " + string + " " + c.getFrom() + " " + c.getTo());//write the change to console.

      for (String string : copiedList) {
      if(limitRecursion) {//make sure we only do the recursion step once.
      limitRecursion = false;
      list.add("One more");//cause another change for the list change handler to handle



      List<String> original = new ArrayList<String>();
      original.add("First One");
      original.add("Second One");
      list.addAll(original);//add two items at once


      public static void main(String[] args) {



          Issue Links



              • Assignee:
                vadim Vadim Pakhnushev
                duke J. Duke (Inactive)
              • Votes:
                0 Vote for this issue
                1 Start watching this issue


                • Created: