WLTY
WLTY

Reputation: 89

ListChangeListener - correct change order

What is the correct change order?

In the documentation here - click, we can see the following example:

 ObservableList<Item> theList = ...;

 theList.addListener(new ListChangeListener<Item>() {
     public void onChanged(Change<Item> c) {
         while (c.next()) {
             if (c.wasPermutated()) {
                 for (int i = c.getFrom(); i < c.getTo(); ++i) {
                      //permutate
                 }
             } else if (c.wasUpdated()) {
                      //update item
             } else {
                 for (Item remitem : c.getRemoved()) {
                     remitem.remove(Outer.this);
                 }
                 for (Item additem : c.getAddedSubList()) {
                     additem.add(Outer.this);
                 }
             }
         }
     });

 }

BUT below the sample code there is:

Note: in case the change contains multiple changes of different type, these changes must be in the following order: permutation change(s), add or remove changes, update changes. This is because permutation changes cannot go after add/remove changes as they would change the position of added elements. And on the other hand, update changes must go after add/remove changes because they refer with their indexes to the current state of the list, which means with all add/remove changes applied.

Is the example wrong then? Or maybe I'm missing something?

Upvotes: 1

Views: 187

Answers (1)

Slaw
Slaw

Reputation: 45806

There are three types of changes that can be fired by an ObservableList:

  1. Permutation (a change in order)
  2. Addition/removal (or replacement, which is just a simultaneous addition and removal)
  3. An update (a change in an element's property, requires an "extractor")

A single change can be only one of those types. However, a single Change instance can carry multiple changes. That's why you have to iterate over the Change instance by calling next() in a while loop.

The documentation you quote:

Note: in case the change contains multiple changes of different type, these changes must be in the following order: permutation change(s), add or remove changes, update changes.

Is regarding the order of changes returned by said next() method. Here the order is important because the Change must report the list as it currently exists.

That documentation does not dictate the order you query the type of change. If the change was not a permutation then c.wasPermutated() simply returns false and the code moves on. Same with the other types of changes. Note that, because of how the API is designed, if a change is neither a permutation nor an update then it must be an addition or removal (or replacement).

So the example is not wrong. If you wanted you could write it as:

while (c.next()) {
  if (c.wasPermutated()) {
    // process perumutation
  } else if (c.wasRemoved() || c.wasAdded()) {
    // process removal, addition, or replacement
  } else {
    // process update
  }
}

But that does not change the behavior of the code.

Upvotes: 2

Related Questions