拥有Collection Listener的好方法?

时间:2009-12-21 19:36:32

标签: java collections listener observer-pattern

有没有更好的方法在java集合上拥有一个监听器,而不是将它包装在一个实现观察者模式的类中?

5 个答案:

答案 0 :(得分:13)

您应该查看Glazed Lists

它包含可观察的List类,每当添加,删除,替换元素等时都会触发事件

答案 1 :(得分:6)

您可以使用ForwardingSet中的ForwardingListGuava等来装饰具有所需行为的特定实例。

这是我自己的实现,只使用普通的JDK API:

// create an abstract class that implements this interface with blank implementations
// that way, annonymous subclasses can observe only the events they care about
public interface CollectionObserver<E> {

    public void beforeAdd(E o);

    public void afterAdd(E o);

    // other events to be observed ...

}

// this method would go in a utility class
public static <E> Collection<E> observedCollection(
    final Collection<E> collection, final CollectionObserver<E> observer) {
        return new Collection<E>() {
            public boolean add(final E o) {
                observer.beforeAdd(o);
                boolean result = collection.add(o);
                observer.afterAdd(o);
                return result;
            }

            // ... generate rest of delegate methods in Eclipse

    };
    }

答案 2 :(得分:2)

Apache Events

“Commons-Events提供了用于触发和处理事件的附加类。它专注于Java Collections框架,为其他触发事件的集合提供装饰器。”

答案 3 :(得分:1)

好吧,如果您实际上不需要java.util.Collection或List实例,则可以使用DefaultListModel。我不知道任何具有内置监听器/观察器支持的“真正的”Collection实现。

答案 4 :(得分:0)

有很多方法可以实现这一目标 - 通常我会使用这种方法

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class ObservableArrayList<E> extends ArrayList<E> {

    private @interface MethodId {
         private static final int REMOVE = 2;
         private static final int ADD = 1;
    }

    public interface ListObserver<E> {
        void onElementAdded(E element);
        void onElementRemoved(E element);
    }

    public ObservableArrayList(int capacity) {
        super(capacity);
        ensureObserver();
    }

    public ObservableArrayList() {
        ensureObserver();
    }

    public ObservableArrayList(Collection<? extends E> collection) {
        super(collection);
        ensureObserver();
    }

    private List<WeakReference<ListObserver<E>>> _listObserverWeakRefList;

    public void addObserver(ListObserver<E> observer) {
         _listObserverWeakRefList.add(new WeakReference<ListObserver<E>>   (observer));
    }

    private void ensureObserver() {
       if (_listObserverWeakRefList == null) {
            _listObserverWeakRefList = new ArrayList<>();
       }
    }

    @Override
    public boolean add(E object) {
        super.add(object);
        callObservable(MethodId.ADD, object);
        return true;
    }

    @Override
    public boolean remove(Object object) {
        boolean removed = super.remove(object);
        if (removed) callObservable(MethodId.REMOVE, object);
        return removed;
    }

    private void callObservable(@MethodId int methodId, Object element) {
         for (WeakReference<ListObserver<E>> observerRef :  _listObserverWeakRefList) {
             ListObserver<E> observer = observerRef.get();
             if (observer != null) {
                 switch (methodId) {
                    case MethodId.ADD:
                        observer.onElementAdded((E) element);
                        break;
                    case MethodId.REMOVE:
                        observer.onElementRemoved((E) element);
                        break;
                } 
            }
        }
    }

}