ListChangeListener の JavaDoc は、変更を処理するためのテンプレートを提供します。ただし、順列の処理方法がわかりません。すべてのインデックスについて、アイテムの新しいインデックスがどこにあるかを見つけることができますが、それをどうすればよいかわかりません。これは、プログラミング言語に依存しないちょっとしたパズルです。ObservableList は、add()、remove()、set() のみを実行でき、反復子も持ちます。
元のリスト [1,2,3] があり、リスト [] をそれにバインドする場合、バインドされたリスト [1,2,3] はそれに一致する必要があります。元のリストのコンパレータが交換され、元のリストが [3,2,1] になるようになった場合、バインドされたリストを追従させるにはどうすればよいですか?
/**
* Binds a source list's elements to a destination list. Any changes made in
* the source list will reflect in the destination list.
*
* @param <SRC> The source list's object type.
* @param <DEST> The destination list's object type.
* @param dest The destination list that will be bound to the src list.
* @param src The source list to watch for changes, and propagate up to the
* destination list.
* @param transformer A function that will transform a source list data
* type, A, into a destination list data type, B.
*/
public static <SRC, DEST> void bindLists(
ObservableList<DEST> dest, ObservableList<SRC> src, Function<? super SRC, ? extends DEST> transformer) {
/*Add the initial data into the destination list.*/
for (SRC a : src) {
dest.add(transformer.apply(a));
}
/*Watch for future data to add to the destination list. Also watch for removal
of data form the source list to remove its respective item in the destination
list.*/
src.addListener((ListChangeListener.Change<? extends SRC> c) -> {
while (c.next()) {
if (c.wasPermutated()) {
/*How do you handle permutations? Do you remove and then add,
or add and then remove, or use set, or use a copy arraylist
and set the right indices? Removing/adding causes concurrent modifications.*/
for (int oldIndex = c.getFrom(); oldIndex < c.getTo(); oldIndex++) {
int newIndex = c.getPermutation(oldIndex);
dest.remove(oldIndex);
dest.add(newIndex, dest.get(oldIndex));
}
} else if (c.wasUpdated()) {
} else {
/*Respond to removed data.*/
for (SRC item : c.getRemoved()) {
int from = c.getFrom();
dest.remove(from);
}
/*Respond to added data.*/
for (SRC item : c.getAddedSubList()) {
int indexAdded = src.indexOf(item);
dest.add(indexAdded, transformer.apply(item));
}
}
}
});
}