ListChangeListener.Change:如何正确处理更新和排列的项目
ListChangeListener.Change: how to properly handle updated and permutated items
来自 JavaDoc:
ObservableList theList = ...;
theList.addListener(new ListChangeListener<Item>() {
public void onChanged(Change<tem> 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);
}
}
}
}
});
}
添加和删除项目很简单,但是 //update item
和 // permutate
呢?
我如何知道哪些项目已被哪些其他项目置换?
更新到底是什么意思?只是再次将相同的项目添加到列表中吗?
那么
for (Item remitem : c.getRemoved()) {
remitem.remove(Outer.this);
}
or (Item additem : c.getAddedSubList()) {
additem.add(Outer.this);
}
Outer.this
是什么意思?
How do I know which items have been permutated by which other items?
更改有一个 getPermutation() 方法来描述元素是如何排列的。
What does update mean exactly?
如果属于某个元素的属性发生更改,则会更新列表,尽管相同的元素仍保留在列表中(以相同的顺序)。例如,给定 class
public class Item {
private final IntegerProperty value = new SimpleIntegerProperty();
public final IntegerProperty valueProperty() {
return value ;
}
public final int getValue() {
return valueProperty().get();
}
public final void setValue(int value) {
valueProperty().set(value);
}
public Item(int value) {
setValue(value);
}
}
对列表的元素调用 setValue()
可能会触发更新。请注意 documentation states that updates are "optional" and may not be fired by all lists. Specifically, to obtain a list that fires updates, create it with an extractor:
ObservableList<Item> list = FXCollections.observableArrayList(
item -> new Observable[] {item.valueProperty()});
list.addAll(new Item(1), new Item(2), new Item(3));
list.addListener((Change<? extends Item> c) -> {
while (c.next()) {
if (c.wasUpdated()) {
System.out.println("Items from "+c.getFrom()+" to "+c.getTo()+" changed");
}
}
});
list.get(1).setValue(42);
最后一行代码不会更改列表中的元素或它们的顺序,但会更改其中一个元素的 属性。因此,此更改将触发更新。
What does Outer.this
mean?
它只是对周围class(假设有class名称Outer
)的当前对象的引用;即不是 ListChangeListener
的匿名内部 class 实现的当前对象。请参阅 What is the difference between Class.this and this in Java(以及许多其他)。我认为文档中代码片段的上下文应该是实现 ObservableList
并维护其自己的 ObservableList
实例(装饰器模式)的 class。它观察列表实例并更新自身以与其保持同步。
来自 JavaDoc:
ObservableList theList = ...;
theList.addListener(new ListChangeListener<Item>() {
public void onChanged(Change<tem> 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);
}
}
}
}
});
}
添加和删除项目很简单,但是 //update item
和 // permutate
呢?
我如何知道哪些项目已被哪些其他项目置换?
更新到底是什么意思?只是再次将相同的项目添加到列表中吗?
那么
for (Item remitem : c.getRemoved()) {
remitem.remove(Outer.this);
}
or (Item additem : c.getAddedSubList()) {
additem.add(Outer.this);
}
Outer.this
是什么意思?
How do I know which items have been permutated by which other items?
更改有一个 getPermutation() 方法来描述元素是如何排列的。
What does update mean exactly?
如果属于某个元素的属性发生更改,则会更新列表,尽管相同的元素仍保留在列表中(以相同的顺序)。例如,给定 class
public class Item {
private final IntegerProperty value = new SimpleIntegerProperty();
public final IntegerProperty valueProperty() {
return value ;
}
public final int getValue() {
return valueProperty().get();
}
public final void setValue(int value) {
valueProperty().set(value);
}
public Item(int value) {
setValue(value);
}
}
对列表的元素调用 setValue()
可能会触发更新。请注意 documentation states that updates are "optional" and may not be fired by all lists. Specifically, to obtain a list that fires updates, create it with an extractor:
ObservableList<Item> list = FXCollections.observableArrayList(
item -> new Observable[] {item.valueProperty()});
list.addAll(new Item(1), new Item(2), new Item(3));
list.addListener((Change<? extends Item> c) -> {
while (c.next()) {
if (c.wasUpdated()) {
System.out.println("Items from "+c.getFrom()+" to "+c.getTo()+" changed");
}
}
});
list.get(1).setValue(42);
最后一行代码不会更改列表中的元素或它们的顺序,但会更改其中一个元素的 属性。因此,此更改将触发更新。
What does
Outer.this
mean?
它只是对周围class(假设有class名称Outer
)的当前对象的引用;即不是 ListChangeListener
的匿名内部 class 实现的当前对象。请参阅 What is the difference between Class.this and this in Java(以及许多其他)。我认为文档中代码片段的上下文应该是实现 ObservableList
并维护其自己的 ObservableList
实例(装饰器模式)的 class。它观察列表实例并更新自身以与其保持同步。