2009-12-21 4 views

Répondre

13

Vous devriez vérifier Glazed Lists

Il contient des classes Liste observables, les événements de feu lorsque des éléments sont ajoutés, supprimés, remplacés, etc

+0

D'accord. GlazedLists est excellent. – Barend

+0

En effet, une ou deux des mêmes personnes ont travaillé sur les deux ... –

+0

TransformationLists de Glazed Lists s'attend à ce que dispose() soit invoqué manuellement au lieu d'utiliser WeakReferences pour les auditeurs ....? 0.o Il doit y avoir quelque chose de mieux là-bas. – user515655

1

Eh bien, si vous n'avez pas réellement besoin d'une instance java.util.Collection ou List, vous pouvez utiliser un DefaultListModel. Je ne connais aucune implémentation de collection "réelle" avec un support d'écoute/d'observation intégré.

+0

Vous lié la version Java 6 de DefaultListModel, qui n'utilise pas de génériques. La version de [Java 7] (http://docs.oracle.com/javase/7/docs/api/javax/swing/DefaultListModel.html) fait, ce qui pourrait rendre votre suggestion plus attrayante. –

+0

@MartinRust bien, oui, la réponse est de 2 ans avant que Java 7 est sorti. Si je vais le mettre à jour, je pourrais aussi bien utiliser Java 8 maintenant –

2

Apache Events. "Commons-Events fournit des classes supplémentaires pour le déclenchement et la gestion des événements.Il se concentre sur le Java Collections Framework, fournissant des décorateurs à d'autres collections qui déclenchent des événements."

+3

Doit être noté que c'est toujours un projet sandbox. Un intéressant cependant. – BalusC

6

Vous pouvez en utilisant la ForwardingSet, ForwardingList, etc., de Guava à décorer une instance particulière avec le comportement souhaité.

Voilà ma propre implémentation qui utilise simplement les API JDK simples:

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

Il y a plusieurs façons d'y parvenir - souvent j'utiliser cette approche

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

} 
Questions connexes