package lettergame.model; import java.util.*; /** * Wraps a list so that any changes can be observed. * Changes made through an iterator also result in * notification of observers; * @author kjg * @param */ public class ObservableList extends Observable implements List { private List list; // the wrapped list public ObservableList(List list) { this.list = list; } private void mutated() { setChanged(); notifyObservers(); } public void add(int arg0, T arg1) { list.add(arg0, arg1); mutated(); } public boolean add(T arg0) { boolean result = list.add(arg0); mutated(); return result; } public boolean addAll(Collection arg0) { boolean result = list.addAll(arg0); mutated(); return result; } public boolean addAll(int arg0, Collection arg1) { boolean result = list.addAll(arg0, arg1); mutated(); return result; } public void clear() { list.clear(); mutated(); } public boolean contains(Object arg0) { return list.contains(arg0); } public boolean containsAll(Collection arg0) { return list.containsAll(arg0); } public boolean equals(Object arg0) { return list.equals(arg0); } public T get(int arg0) { return list.get(arg0); } public int hashCode() { return list.hashCode(); } public int indexOf(Object arg0) { return list.indexOf(arg0); } public boolean isEmpty() { return list.isEmpty(); } public Iterator iterator() { return new NotifyingIterator(list.listIterator()); } public int lastIndexOf(Object arg0) { return list.lastIndexOf(arg0); } public ListIterator listIterator() { return new NotifyingIterator(list.listIterator()); } public ListIterator listIterator(int arg0) { return new NotifyingIterator(list.listIterator(arg0)); } /** * Moves the object from indexA to the position indexB. * @param indexA * @param indexB */ public void move(int indexA, int indexB) { if (indexA != indexB) { try { list.add(indexB, list.remove(indexA)); } finally { mutated(); } } } public T remove(int arg0) { T result = list.remove(arg0); mutated(); return result; } public boolean remove(Object arg0) { boolean result = list.remove(arg0); mutated(); return result; } public boolean removeAll(Collection arg0) { boolean result = list.removeAll(arg0); mutated(); return result; } public boolean retainAll(Collection arg0) { boolean result = list.retainAll(arg0); mutated(); return result; } public T set(int arg0, T arg1) { T result = list.set(arg0, arg1); mutated(); return result; } public int size() { return list.size(); } public List subList(int arg0, int arg1) { return list.subList(arg0, arg1); } public Object[] toArray() { return list.toArray(); } public X[] toArray(X[] arg0) { return list.toArray(arg0); } public String toString() { return list.toString(); } class NotifyingIterator implements ListIterator { private ListIterator it; // the wrapped iterator NotifyingIterator(ListIterator it) { this.it = it; } public void add(T arg0) { it.add(arg0); mutated(); } public boolean hasNext() { return it.hasNext(); } public boolean hasPrevious() { return it.hasPrevious(); } public T next() { return it.next(); } public int nextIndex() { return it.nextIndex(); } public T previous() { return it.previous(); } public int previousIndex() { return it.previousIndex(); } public void remove() { it.remove(); mutated(); } public void set(T arg0) { it.set(arg0); mutated(); } } // Test program illustrating creating a list and adding // an observer that reacts to changes. public static void main(String[] args) { List model = new LinkedList(); final ObservableList l = new ObservableList(model); l.addObserver(new Observer() { public void update(Observable arg0, Object arg1) { System.out.println(l); } }); l.add("hello"); l.add("there"); l.remove(1); l.clear(); l.add("world"); l.add("peace"); l.move(1,0); l.move(0,1); Iterator it = l.iterator(); while (it.hasNext()) { it.next(); it.remove(); } } }