2009-12-21 10 views

risposta

13

Si dovrebbe verificare Glazed Lists

Contiene classi List osservabili, quali eventi di fuoco ogni volta che vengono aggiunti elementi, rimossi, sostituiti, ecc

+0

concordato. GlazedLists è eccellente. – Barend

+0

Infatti, uno o due delle stesse persone hanno lavorato su entrambi ... –

+0

TransformationList di Liste glazed si aspetta che dispose() venga invocato manualmente invece di utilizzare WeakReferences per gli ascoltatori ....? 0.o Deve esserci qualcosa di meglio là fuori. – user515655

1

Bene, se in realtà non è necessaria un'istanza java.util.Collection o List, è possibile utilizzare uno DefaultListModel. Non sono a conoscenza di eventuali implementazioni di raccolte "reali" con supporto incorporato di listener/observer.

+0

È collegato la versione di Java 6 di DefaultListModel, che non usa Generics. La [versione di Java 7] (http://docs.oracle.com/javase/7/docs/api/javax/swing/DefaultListModel.html), che potrebbe rendere il tuo suggerimento più attraente. –

+0

@MartinRust bene, sì, la risposta è da 2 anni prima che uscisse Java 7. Se lo aggiornerò, potrei usare Java 8 ora –

2

Apache Events.

"Commons-Events fornisce classi aggiuntive per eventi di accensione e gestione. Si concentra sul framework Java Collections, fornendo decoratori ad altre raccolte che generano eventi".

+3

Dovrebbe essere notato che questo è ancora un progetto sandbox. Uno interessante comunque. – BalusC

6

È possibile utilizzare il ForwardingSet, ForwardingList, ecc, da Guava a decorare un'istanza particolare con il comportamento desiderato.

Ecco la mia implementazione che utilizza solo le API JDK pianura:

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

ci sono molti modi per raggiungere questo - spesso io uso questo approccio

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

} 
Problemi correlati