1  import java.util.*;
  2  import javax.swing.event.*;
  3  
  4  /**
  5     An invoice for a sale, consisting of line items.
  6  */
  7  public class Invoice
  8  {
  9     /**
 10        Constructs a blank invoice.
 11     */
 12     public Invoice()
 13     {
 14        items = new ArrayList<>();
 15        listeners = new ArrayList<>();
 16     }
 17  
 18    /**
 19        Adds an item to the invoice.
 20        @param item the item to add
 21     */
 22     public void addItem(LineItem item)
 23     {
 24        items.add(item);
 25        // Notify all observers of the change to the invoice
 26        ChangeEvent event = new ChangeEvent(this);
 27        for (ChangeListener listener : listeners)
 28           listener.stateChanged(event);
 29     }
 30  
 31     /**
 32        Adds a change listener to the invoice.
 33        @param listener the change listener to add
 34     */
 35     public void addChangeListener(ChangeListener listener)
 36     {
 37        listeners.add(listener);
 38     }
 39  
 40     /**
 41        Gets an iterator that iterates through the items.
 42        @return an iterator for the items
 43     */
 44     public Iterator<LineItem> getItems()
 45     {
 46        return new
 47           Iterator<LineItem>()
 48           {
 49              public boolean hasNext()
 50              {
 51                 return current < items.size();
 52              }
 53  
 54              public LineItem next()
 55              {
 56                 return items.get(current++);
 57              }
 58  
 59              public void remove()
 60              {
 61                 throw new UnsupportedOperationException();
 62              }
 63  
 64              private int current = 0;
 65           };
 66     }
 67  
 68     public String format(InvoiceFormatter formatter)
 69     {
 70        String r = formatter.formatHeader();
 71        Iterator<LineItem> iter = getItems();
 72        while (iter.hasNext())
 73           r += formatter.formatLineItem(iter.next());
 74        return r + formatter.formatFooter();
 75     }
 76  
 77     private ArrayList<LineItem> items;
 78     private ArrayList<ChangeListener> listeners;
 79  }