In some contexts it's necessary to detect - in a ListChangeListener, without control about the list itself - a "all data swapped out", f.i. when we need to clear some state like selection - on completely new data the old state is meaningless.
Completely new data can be reached by
Thinking about which type of changes could be fired on setAll (c is the change, items is the observed list, "subChangeCount" pseudo-code for counting the subchanges):
// initially empty
assertEquals(0, items.size());
items.setAll(1, 2, 4);
assertEquals(1, c.subChangeCount());
assertTrue(c.wasAdded() && !c.wasReplaced());
assertEquals(0, c.getFrom());
assertEquals(c.getList().size(), c.getAddedSize());
// initially not empty
assertTrue(items.size() > 0);
items.setAll(1, 2, 4);
assertEquals(1, c.subChangeCount());
assertTrue(c.wasReplaced());
assertEquals(0, c.getFrom());
assertEquals(c.getList().size(), c.getAddedSize());
This seems to allow a utility check like:
boolean wasSetOrClearedAll(Change c) {
if (c.getList().isEmpty()) return true;
c.next();
if (c.getAddedSize() == c.getList().size()) return true;
return false;
}
In contrast, internal fx code, f.i. in listening to ComboBox' items:
while (c.next()) {
comboBox.wasSetAllCalled = comboBox.previousItemCount == c.getRemovedSize();
...
}
comboBox.previousItemCount = getItemCount();
stores the old itemCount and compare that against the current removedSize (which I'm uncomfortable with, old state gets stale far too often for my taste), nevertheless there's a good probability that I'm missing something with my approach.
Question is:
in which context would my utility method fail (and core approach would detect the setAll correctly)?
Unfortunately there is no reliable way of detecting this on the Listener side.
The struggle starts with the default implemention, which mostly looks like this:
@Override
public boolean setAll(Collection<? extends E> col) {
beginChange();
try {
clear();
addAll(col);
} finally {
endChange();
}
return true;
}
If you pass an empty Collection to setAll
the result and the event that is fired are both exactly the same as when you would have called clear
.
So your method wasSetOrClearedAll
returns true
when clear
has been called, too (as would the core implementation).
So in the end there is no generic detection of setAll
, it all depends on your use-case. If you can narrow down what you are trying to detect you may write a filter for that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With