Swing JFC Java

/*
Swing, Second Edition
by Matthew Robinson, Pavel Vorobiev
*/
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
import java.text.SimpleDateFormat;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class ExpenseReport extends JFrame 
{
  protected JTable m_table;
  protected ExpenseReportData m_data;
  protected JLabel m_title;
  public ExpenseReport() {
    super("Expense Report");
    setSize(570, 200);
    m_data = new ExpenseReportData(this);
    m_table = new JTable();
    m_table.setAutoCreateColumnsFromModel(false);
    m_table.setModel(m_data); 
    m_table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        
    for (int k = 0; k < ExpenseReportData.m_columns.length; k++) {
      TableCellRenderer renderer;
      if (k==ExpenseReportData.COL_APPROVED)
        renderer = new CheckCellRenderer();
      else {
        DefaultTableCellRenderer textRenderer = 
          new DefaultTableCellRenderer();
        textRenderer.setHorizontalAlignment(
          ExpenseReportData.m_columns[k].m_alignment);
        renderer = textRenderer;
      }
      TableCellEditor editor;
      if (k==ExpenseReportData.COL_CATEGORY)
        editor = new DefaultCellEditor(new JComboBox(
          ExpenseReportData.CATEGORIES));
      else if (k==ExpenseReportData.COL_APPROVED)
        editor = new DefaultCellEditor(new JCheckBox());
      else
        editor = new DefaultCellEditor(new JTextField());
      TableColumn column = new TableColumn(k, 
        ExpenseReportData.m_columns[k].m_width, 
          renderer, editor);
        m_table.addColumn(column);   
    }
    JTableHeader header = m_table.getTableHeader();
    header.setUpdateTableInRealTime(false);
    JScrollPane ps = new JScrollPane();
    ps.setSize(550, 150);
    ps.getViewport().add(m_table);
    getContentPane().add(ps, BorderLayout.CENTER);
    JPanel p = new JPanel();
    p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
    ImageIcon penny = new ImageIcon("penny.gif");
    m_title = new JLabel("Total: $", 
      penny, JButton.LEFT);
    m_title.setForeground(Color.black);
    m_title.setAlignmentY(0.5f);
    p.add(m_title);
    p.add(Box.createHorizontalGlue());
    JButton bt = new JButton("Insert before");
    bt.setMnemonic('b');
    bt.setAlignmentY(0.5f);
    ActionListener lst = new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
        int row = m_table.getSelectedRow();
        m_data.insert(row);
        m_table.tableChanged(new TableModelEvent(
          m_data, row, row, TableModelEvent.ALL_COLUMNS, 
          TableModelEvent.INSERT)); 
        m_table.repaint();
      }
    };
    bt.addActionListener(lst);
    p.add(bt);
    bt = new JButton("Insert after");
    bt.setMnemonic('a');
    bt.setAlignmentY(0.5f);
    lst = new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
        int row = m_table.getSelectedRow();
        m_data.insert(row+1);
        m_table.tableChanged(new TableModelEvent(
          m_data, row+1, row+1, TableModelEvent.ALL_COLUMNS,
          TableModelEvent.INSERT)); 
        m_table.repaint();
      }
    };
    bt.addActionListener(lst);
    p.add(bt);
    bt = new JButton("Delete row");
    bt.setMnemonic('d');
    bt.setAlignmentY(0.5f);
    lst = new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
        int row = m_table.getSelectedRow();
        if (m_data.delete(row)) {
          m_table.tableChanged(new TableModelEvent(
            m_data, row, row, TableModelEvent.ALL_COLUMNS,
            TableModelEvent.INSERT)); 
          m_table.repaint();
          calcTotal();
        }
      }
    };
    bt.addActionListener(lst);
    p.add(bt);
      
    getContentPane().add(p, BorderLayout.SOUTH);
    calcTotal();
    WindowListener wndCloser = new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    };
    addWindowListener(wndCloser);
    
    setVisible(true);
  }
  public void calcTotal() {
    double total = 0;
    for (int k=0; k      Double amount = (Double)m_data.getValueAt(k, 
        ExpenseReportData.COL_AMOUNT);
      total += amount.doubleValue();
    }
    m_title.setText("Total: $"+total);
  }
  public static void main(String argv[]) {
    new ExpenseReport();
  }
}
class CheckCellRenderer extends JCheckBox implements TableCellRenderer
{
  protected static Border m_noFocusBorder;
  public CheckCellRenderer() {
    super();
    m_noFocusBorder = new EmptyBorder(1, 2, 1, 2);
    setOpaque(true);
    setBorder(m_noFocusBorder);
  }
  public Component getTableCellRendererComponent(JTable table,
   Object value, boolean isSelected, boolean hasFocus, 
   int row, int column) 
  {
    if (value instanceof Boolean) {
      Boolean b = (Boolean)value;
      setSelected(b.booleanValue());
    }
    setBackground(isSelected && !hasFocus ? 
      table.getSelectionBackground() : table.getBackground());
    setForeground(isSelected && !hasFocus ? 
      table.getSelectionForeground() : table.getForeground());
        
    setFont(table.getFont());
    setBorder(hasFocus ? UIManager.getBorder(
      "Table.focusCellHighlightBorder") : m_noFocusBorder);
    return this;
  }
}
class ExpenseData
{
  public Date    m_date;
  public Double  m_amount;
  public Integer m_category;
  public Boolean m_approved;
  public String  m_description;
  public ExpenseData() {
    m_date = new Date();
    m_amount = new Double(0);
    m_category = new Integer(1);
    m_approved = new Boolean(false);
    m_description = "";
  }
  public ExpenseData(Date date, double amount, int category, 
   boolean approved, String description) 
  {
    m_date = date;
    m_amount = new Double(amount);
    m_category = new Integer(category);
    m_approved = new Boolean(approved);
    m_description = description;
  }
}
class ColumnData
{
  public String  m_title;
  int m_width;
  int m_alignment;
  public ColumnData(String title, int width, int alignment) {
    m_title = title;
    m_width = width;
    m_alignment = alignment;
  }
}
class ExpenseReportData extends AbstractTableModel 
{
  public static final ColumnData m_columns[] = {
    new ColumnData( "Date", 80, JLabel.LEFT ),
    new ColumnData( "Amount", 80, JLabel.RIGHT ),
    new ColumnData( "Category", 130, JLabel.LEFT ),
    new ColumnData( "Approved", 80, JLabel.LEFT ),
    new ColumnData( "Description", 180, JLabel.LEFT )
  };
  public static final int COL_DATE = 0;
  public static final int COL_AMOUNT = 1;
  public static final int COL_CATEGORY = 2;
  public static final int COL_APPROVED = 3;
  public static final int COL_DESCR = 4;
  public static final String[] CATEGORIES = {
    "Fares", "Logging", "Business meals", "Others"
  };
  protected ExpenseReport m_parent;
  protected SimpleDateFormat m_frm;
  protected Vector m_vector;
  public ExpenseReportData(ExpenseReport parent) {
    m_parent = parent;
    m_frm = new SimpleDateFormat("MM/dd/yy");
    m_vector = new Vector();
    setDefaultData();
  }
  public void setDefaultData() {
    m_vector.removeAllElements();
    try {
      m_vector.addElement(new ExpenseData(
      m_frm.parse("04/06/99"), 200, 0, true, 
        "Airline tickets"));
      m_vector.addElement(new ExpenseData(
        m_frm.parse("04/06/99"), 50,  2, false, 
        "Lunch with client"));
      m_vector.addElement(new ExpenseData(
        m_frm.parse("04/06/99"), 120, 1, true, 
        "Hotel"));
    }
    catch (java.text.ParseException ex) {}
  }
  public int getRowCount() {
    return m_vector==null ? 0 : m_vector.size(); 
  }
  public int getColumnCount() { 
    return m_columns.length; 
  } 
  public String getColumnName(int column) { 
    return m_columns[column].m_title; 
  }
 
  public boolean isCellEditable(int nRow, int nCol) {
    return true;
  }
  public Object getValueAt(int nRow, int nCol) {
    if (nRow < 0 || nRow>=getRowCount())
      return "";
    ExpenseData row = (ExpenseData)m_vector.elementAt(nRow);
    switch (nCol) {
      case COL_DATE: return m_frm.format(row.m_date);
      case COL_AMOUNT: return row.m_amount;
      case COL_CATEGORY: return CATEGORIES[row.m_category.intValue()];
      case COL_APPROVED: return row.m_approved;
      case COL_DESCR: return row.m_description;
    }
    return "";
  }
  public void setValueAt(Object value, int nRow, int nCol) {
    if (nRow < 0 || nRow>=getRowCount())
      return;
    ExpenseData row = (ExpenseData)m_vector.elementAt(nRow);
    String svalue = value.toString();
    switch (nCol) {
      case COL_DATE: 
        Date  date = null;
        try { 
          date = m_frm.parse(svalue); 
        }
        catch (java.text.ParseException ex) { 
          date = null; 
        }
        if (date == null) {
          JOptionPane.showMessageDialog(null, 
            svalue+" is not a valid date",
            "Warning", JOptionPane.WARNING_MESSAGE);
          return;
        }
        row.m_date = date; 
        break;
      case COL_AMOUNT:
        try { 
          row.m_amount = new Double(svalue); 
        }
        catch (NumberFormatException e) { break; }
        m_parent.calcTotal();
        break;
      case COL_CATEGORY:
        for (int k=0; k          if (svalue.equals(CATEGORIES[k])) {
            row.m_category = new Integer(k);
            break;
          }
        break;
      case COL_APPROVED:
        row.m_approved = (Boolean)value; 
        break;
      case COL_DESCR:
        row.m_description = svalue; 
        break;
    }
  }
  public void insert(int row) {
    if (row < 0)
      row = 0;
    if (row > m_vector.size())
      row = m_vector.size();
    m_vector.insertElementAt(new ExpenseData(), row);
  }
  public boolean delete(int row) {
    if (row < 0 || row >= m_vector.size())
      return false;
    m_vector.remove(row);
      return true;
  }
}