import java.io.Serializable;
import java.util.*;
import java.lang.ref.*;
import javax.swing.*;
import javax.swing.event.*;
class WeakListModel implements ListModel, Serializable {
private final Object present = new Object();
private Map listenerList = Collections.synchronizedMap(new WeakHashMap());
private ArrayList delegate = new ArrayList();
public int getSize() {
return delegate.size();
}
public Object getElementAt(int index) {
return delegate.get(index);
}
public void trimToSize() {
delegate.trimToSize();
}
public void ensureCapacity(int minCapacity) {
delegate.ensureCapacity(minCapacity);
}
public int size() {
return delegate.size();
}
public boolean isEmpty() {
return delegate.isEmpty();
}
public Enumeration elements() {
return Collections.enumeration(delegate);
}
public boolean contains(Object elem) {
return delegate.contains(elem);
}
public int indexOf(Object elem) {
return delegate.indexOf(elem);
}
public int lastIndexOf(Object elem) {
return delegate.lastIndexOf(elem);
}
public Object elementAt(int index) {
return delegate.get(index);
}
public Object firstElement() {
return delegate.get(0);
}
public Object lastElement() {
return delegate.get(delegate.size()-1);
}
public void setElementAt(Object obj, int index) {
delegate.set(index, obj);
fireContentsChanged(this, index, index);
}
public void removeElementAt(int index) {
delegate.remove(index);
fireIntervalRemoved(this, index, index);
}
public void insertElementAt(Object obj, int index) {
delegate.add(index, obj);
fireIntervalAdded(this, index, index);
}
public void addElement(Object obj) {
int index = delegate.size();
delegate.add(obj);
fireIntervalAdded(this, index, index);
}
public boolean removeElement(Object obj) {
int index = indexOf(obj);
boolean rv = delegate.remove(obj);
if (index >= 0) {
fireIntervalRemoved(this, index, index);
}
return rv;
}
public void removeAllElements() {
int index1 = delegate.size()-1;
delegate.clear();
if (index1 >= 0) {
fireIntervalRemoved(this, 0, index1);
}
}
public String toString() {
return delegate.toString();
}
public synchronized void addListDataListener(ListDataListener l) {
listenerList.put(l, present);
}
public synchronized void removeListDataListener(ListDataListener l) {
listenerList.remove(l);
}
protected synchronized void fireContentsChanged(Object source, int index0, int index1) {
ListDataEvent e = null;
Set set = new HashSet(listenerList.keySet());
Iterator iter = set.iterator();
while (iter.hasNext()) {
if (e == null) {
e = new ListDataEvent(source, ListDataEvent.CONTENTS_CHANGED, index0, index1);
}
ListDataListener ldl = (ListDataListener)iter.next();
ldl.contentsChanged(e);
}
}
protected synchronized void fireIntervalAdded(Object source, int index0, int index1) {
ListDataEvent e = null;
Set set = new HashSet(listenerList.keySet());
Iterator iter = set.iterator();
while (iter.hasNext()) {
if (e == null) {
e = new ListDataEvent(source, ListDataEvent.INTERVAL_ADDED, index0, index1);
}
ListDataListener ldl = (ListDataListener)iter.next();
ldl.intervalAdded(e);
}
}
protected synchronized void fireIntervalRemoved(Object source, int index0, int index1) {
ListDataEvent e = null;
Set set = new HashSet(listenerList.keySet());
Iterator iter = set.iterator();
while (iter.hasNext()) {
if (e == null) {
e = new ListDataEvent(source, ListDataEvent.INTERVAL_REMOVED, index0, index1);
}
ListDataListener ldl = (ListDataListener)iter.next();
ldl.intervalRemoved(e);
}
}
public EventListener[] getListeners(Class listenerType) {
Set set = listenerList.keySet();
return (EventListener[])set.toArray(new EventListener[0]);
}
}
public class TestListModel {
public static void main (String args[]) {
ListDataListener ldl = new ListDataListener() {
public void intervalAdded(ListDataEvent e) {
System.out.println("Added: " + e);
}
public void intervalRemoved(ListDataEvent e) {
System.out.println("Removed: " + e);
}
public void contentsChanged(ListDataEvent e) {
System.out.println("Changed: " + e);
}
};
WeakListModel model = new WeakListModel();
model.addListDataListener(ldl);
model.addElement("New Jersey");
model.addElement("Massachusetts");
model.addElement("Maryland");
model.removeElement("New Jersey");
ldl = null;
System.gc();
model.addElement("New Jersey");
System.out.println(model);
}
}