Swing JFC Java

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