package model; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import javax.swing.ListModel; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; public class AddressBook implements ListModel, Iterable { private final List people; private int size; private final Set listeners; private void checkRep() { assert people != null; assert size == people.size(); assert listeners != null; } public AddressBook() { people = new ArrayList(); size = 0; listeners = new HashSet(); checkRep(); } public void add(Person person) { if (!people.contains(person)) { people.add(person); ++size; int i = size-1; fireEvent(new ListDataEvent(this, ListDataEvent.INTERVAL_ADDED, i, i)); } checkRep(); } public void remove(Person person) { int i = people.indexOf(person); if (i != -1) { people.remove(person); --size; fireEvent(new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, i, i)); } checkRep(); } public Iterator iterator() { return people.iterator(); } /** * @effects remove all Person objects that have a blank name */ public void removeEmptyPeople1() { for (Person p : people) { if (p.getName().equals("")) { remove(p); } } checkRep(); } public void removeEmptyPeople2() { // We have to use the Iterator directly, instead of // using the "for (Person p: people)" syntax, because // we want to delete elements from the collection. int i = 0; for (Iterator g = people.iterator(); g.hasNext(); ) { Person p = g.next(); if (p.getName().equals("")) { g.remove(); fireEvent(new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, i, i)); } else { ++i; } } size = people.size(); checkRep(); } public void removeEmptyPeople3() { // We have to use the Iterator directly, instead of // using the "for (Person p: people)" syntax, because // we want to delete elements from the collection. int i = 0; for (Iterator g = people.iterator(); g.hasNext(); ) { Person p = g.next(); if (p.getName().equals("")) { g.remove(); --size; checkRep(); // because we're about to lose control fireEvent(new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, i, i)); } else { ++i; } } checkRep(); } // ListModel interface public Object getElementAt(int index) { return people.get(index); } public int getSize() { return size; } public void addListDataListener(ListDataListener l) { listeners.add(l); } public void removeListDataListener(ListDataListener l) { listeners.remove(l); } private void fireEvent(ListDataEvent event) { for (ListDataListener l : listeners) { switch (event.getType()) { case ListDataEvent.INTERVAL_ADDED: l.intervalAdded(event); break; case ListDataEvent.INTERVAL_REMOVED: l.intervalRemoved(event); break; case ListDataEvent.CONTENTS_CHANGED: l.contentsChanged(event); break; } } } }