6

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));
                }
            }
        }
    });
}
4

2 に答える 2

2

ここで行っていることはEasyBindで実装されていることに注意してください。リストをマップしてバインドする方法を参照してください。

基本的に、これはメソッドを実装するbindLists方法です。

public static <SRC, DEST> void bindLists(
        ObservableList<DEST> dest, ObservableList<SRC> src,
        Function<? super SRC, ? extends DEST> transformer) {

    EasyBind.listBind(dest, EasyBind.map(src, transformer));
}
于 2014-09-10T19:00:56.353 に答える