package org.limewire.collection.glazedlists; import java.util.ArrayList; import java.util.List; import ca.odell.glazedlists.EventList; import ca.odell.glazedlists.event.ListEvent; import ca.odell.glazedlists.event.ListEventListener; import ca.odell.glazedlists.util.concurrent.Lock; /** * An abstract ListEventListener for use with glazed lists when you really need * the deleted object. Use this class sparingly, as it will cache the contents * of the list. * <p> * To use, subclass {@link AbstractListEventListener} and {@link #install(EventList)} * it on the list you want to listen to. */ public abstract class AbstractListEventListener<E> { private final List<E> cache = new ArrayList<E>(); /** * Adds this {@link AbstractListEventListener} as a listener on the source * {@link EventList}. Installation this way is required in order to * guarantee that the {@link ListEventListener} has a cache of the current * contents of the list so it can call {@link #itemRemoved(Object, int, EventList)} * with the correct items. */ public void install(EventList<E> source) { Lock lock = source.getReadWriteLock().readLock(); lock.lock(); try { cache.addAll(source); source.addListEventListener(new ListEventListener<E>() { @Override public void listChanged(ListEvent<E> changes) { while (changes.next()) { int type = changes.getType(); int idx = changes.getIndex(); EventList<E> source = changes.getSourceList(); switch (type) { case ListEvent.INSERT: cache.add(idx, changes.getSourceList().get(idx)); itemAdded(cache.get(idx), idx, source); break; case ListEvent.DELETE: E removed = cache.remove(idx); itemRemoved(removed, idx, source); break; case ListEvent.UPDATE: E prior = cache.get(idx); cache.set(idx, changes.getSourceList().get(idx)); itemUpdated(cache.get(idx), prior, idx, source); break; } } } }); } finally { lock.unlock(); } } /** Notification that an item was added. */ protected abstract void itemAdded(E item, int idx, EventList<E> source); /** Notification that an item was removed. */ protected abstract void itemRemoved(E item, int idx, EventList<E> source); /** Notification that an item was replaced. */ protected abstract void itemUpdated(E item, E priorItem, int idx, EventList<E> source); }