/*
* QueuedWRVectorModel.java, (c) Raimond Reichert July 1999
*/
package mldemo;
import java.util.*;
import java.lang.ref.*;
/**
* Implements VectorModel with weak references, ie, using
* a Vector to hold WeakReferences which in turn
* hold the references to the VectorModel.Listeners.
*
*
ThreadedWRVectorModel registers the
* WeakReferences with a ReferenceQueue.
* Before firing an event, the cleanUp method is called. This method
* polls the queue. If there is any enqueued reference, then the reference
* is removed from the listeners list.
*
* @author Raimond Reichert
*/
public class QueuedWRVectorModel implements VectorModel {
private Vector vector;
private Vector listeners;
private ReferenceQueue queue;
public QueuedWRVectorModel() {
vector = new Vector();
listeners = new Vector();
queue = new ReferenceQueue();
} // QueuedWRVectorModel //
public void addElement (Object object) {
vector.addElement (object);
fireElementAdded (object);
} // addElement //
public void removeElement (Object object) {
vector.removeElement (object);
fireElementRemoved (object);
} // removeElement //
public Object elementAt (int index) {
return vector.elementAt (index);
} // elementAt //
public int size() {
return vector.size();
} // size //
public void addListener (VectorModel.Listener l) {
WeakReference wr = new WeakReference (l, queue);
listeners.addElement (wr);
} // addListener //
/**
* Polls the reference queue, and removes all references on it from
* the listeners vector.
*/
public void cleanUp() {
WeakReference wr = (WeakReference)queue.poll();
while (wr != null) {
listeners.removeElement (wr);
System.out.println ("QueuedWRVectorModel: removed weak reference");
wr = (WeakReference)queue.poll();
}
} // cleanUp //
public void removeListener (VectorModel.Listener l) {
int size = listeners.size();
int i = 0;
while (i < size) {
WeakReference wr = (WeakReference)listeners.elementAt(i);
VectorModel.Listener vml = (VectorModel.Listener)wr.get();
if (vml == l) {
listeners.removeElement (wr);
size--;
}
else
i++;
}
} // removeListener //
protected void fireElementAdded (Object object) {
cleanUp();
VectorModel.Event e = null;
int size = listeners.size();
int i = 0;
while (i < size) {
WeakReference wr = (WeakReference)listeners.elementAt(i);
VectorModel.Listener vml = (VectorModel.Listener)wr.get();
if (vml != null) {
if (e == null) // lazily create event
e = new VectorModel.Event (this, object);
vml.elementAdded (e);
i++;
}
}
} // fireElementAdded //
protected void fireElementRemoved (Object object) {
cleanUp();
VectorModel.Event e = null;
int size = listeners.size();
int i = 0;
while (i < size) {
WeakReference wr = (WeakReference)listeners.elementAt(i);
VectorModel.Listener vml = (VectorModel.Listener)wr.get();
if (vml != null) {
if (e == null) // lazily create event
e = new VectorModel.Event (this, object);
vml.elementRemoved (e);
i++;
}
}
} // fireElementRemoved //
} // QueuedWRVectorModel //