2009-12-21 2 views

ответ

13

Вы должны проверить Glazed Lists

Он содержит наблюдаемые классы List, которые огненные события, когда добавляются элементы, удалены, заменены, и т.д.

+0

Согласовано. GlazedLists отлично. – Barend

+0

Действительно, один или два из тех же людей работали над ними обоими ... –

+0

Заглавные списки TransformationList ожидает, что dispose() будет вызываться вручную, вместо использования WeakReferences для слушателей ....? 0.o Там должно быть что-то лучше. – user515655

1

Ну, если вам действительно не нужен экземпляр java.util.Collection или List, вы можете использовать DefaultListModel. Я не знаю никаких «реальных» реализаций коллекции со встроенной поддержкой слушателя/наблюдателя.

+0

Вы связали версию Java 6 из DefaultListModel, который не использует Generics. [Версия Java 7] (http://docs.oracle.com/javase/7/docs/api/javax/swing/DefaultListModel.html), что может сделать ваше предложение более привлекательным. –

+0

@MartinRust хорошо, да, ответ от 2 лет до появления Java 7. Если я собираюсь обновить его, я мог бы также использовать Java 8 –

2

Apache Events.

«Commons-Events предоставляет дополнительные классы для запуска и обработки событий. Он фокусируется на структуре коллекций Java, предоставляя декораторы другим коллекциям, которые запускают события».

+3

Следует отметить, что это все еще проект песочницы. Интересно, однако. – BalusC

6

Вы можете с помощью ForwardingSet, ForwardingList и т.д., от Guava к украсить конкретный экземпляр желаемым поведением.

Вот моя собственная реализация, которая использует только простой API, JDK:

// 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 

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

} 
Смежные вопросы