    01: import java.util.*;
    02: import javax.swing.event.*;
    03:
    04: /**
    05:    An invoice for a sale, consisting of line items.
    06: */
    07: public class Invoice
    08: {
    09:    /**
    10:       Constructs a blank invoice.
    11:    */
    12:    public Invoice()
    13:    {
    14:       items = new ArrayList<LineItem>();
    15:       listeners = new ArrayList<ChangeListener>();
    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: }