title: CellEditorListener will not detect when a cell has been edited
body: <p>I am working on my CapStone project to graduate this semester, and have run into a few issues with the program I am working on.  The code is for the Serendipity Booksellers Program.  I am to design a Point-of-Sales system for a fictitious bookstore.</p>
  
  <p>At the moment, I am stuck trying to get the "Total" column (column 5) to update when the user edits the "Qty" cell, for a given row.  The "Qty" field also needs to validate that it value in its cell is not greater than the quantity in stock (column 1).</p>
  
  <p>I have also read <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/table.html" rel="nofollow">How to Use Tables</a> from the Java Tutorials, and searched Google for hours last night to try to find some helpful code on how to get CellEditorListener to work.</p>
  
  <p>I have previously also tried having the CashierPanel class implement CellEditorListener, and register it by:</p>
  
  <pre><code>CellEditorListener listener = null;
  table.getDefaultEditor(String.class).addCellEditorListener(listener);
  </code></pre>
  
  <p>This method did not work either.</p>
  
  <p>Here is the code I have now (217 lines):</p>
  
  <pre><code>/* Imported Dependencies */
  
  import java.awt.BorderLayout;
  import java.awt.Color;
  import java.awt.event.ActionEvent;
  import java.awt.event.ActionListener;
  import java.awt.event.KeyAdapter;
  import java.awt.event.KeyEvent;
  import java.math.BigDecimal;
  import java.math.RoundingMode;
  import java.util.ArrayList;
  
  import javax.swing.DefaultCellEditor;
  import javax.swing.JFrame;
  import javax.swing.JLabel;
  import javax.swing.JPanel;
  import javax.swing.JScrollPane;
  import javax.swing.JTable;
  import javax.swing.JTextField;
  import javax.swing.event.CellEditorListener;
  import javax.swing.event.ChangeEvent;
  import javax.swing.table.AbstractTableModel;
  import javax.swing.table.DefaultTableCellRenderer;
  import javax.swing.table.TableColumn;
  
  import net.miginfocom.swing.MigLayout;
  
  public class CashierPanel extends JFrame {
  
      /**
      * Serial Version UID
      */
      private static final long serialVersionUID = 6922826100788686147L;
  
      /* Private Fields */
      private JPanel searchPanel;
      private JLabel isbn_lbl;
      private JLabel title_lbl;
      private JTextField isbn_tf;
      private JTextField title_tf;
      private JTextField currentCell;
      private BookCollection myCollection;
      private CashierTableModel tableData;
  
      private CellEditorListener listener;
  
      /**
      * Constructor
      */
      public CashierPanel() {
  
          // Set window properties
          setTitle("Testing this table");
          setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          setSize(585, 300);
          setLayout(new BorderLayout());
  
          tableData = new CashierTableModel();
          final JTable table = new JTable(tableData);
          table.setRowHeight(25);
          table.getTableHeader().setReorderingAllowed(false);
          table.setCellSelectionEnabled(true);
          table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
          add(new JScrollPane(table), BorderLayout.CENTER);
  
          // Define a cell renderer to render text to center of cell
          DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
          centerRenderer.setHorizontalAlignment(JLabel.CENTER);
  
          // Set column properties
          int[] sizes = new int[] { 50, 50, 87, 275, 50, 50 };
          String[] columnNames = new String[] { "Qty", "Stock", "ISBN", "Title",
                  "Price", "Total" };
          TableColumn[] column = new TableColumn[columnNames.length];
          for (byte i = 0; i &lt; columnNames.length; i++) {
              column[i] = table.getColumnModel().getColumn(i);
              column[i].setMinWidth(sizes[i]);
              column[i].setHeaderValue(columnNames[i]);
              if (i != 3) {
                  column[i].setMaxWidth(sizes[i]);
                  column[i].setCellRenderer(centerRenderer);
              }
          }
  
          /* Make the quantity field only display digits */
          currentCell = new JTextField();
          column[0].setCellEditor(new DefaultCellEditor(currentCell));
          // Add a key listener to the current cell
          currentCell.addKeyListener(new KeyAdapter() {
              public void keyTyped(KeyEvent e) {
                  // if the key typed is not a digit or backspace
                  if (!Character.isDigit(e.getKeyChar())
                          &amp;&amp; e.getKeyChar() != KeyEvent.VK_BACK_SPACE) {
                      currentCell.setEditable(false);
                      currentCell.setBackground(Color.WHITE);
                  } else {
                      currentCell.setEditable(true);
                  }
              }
          });
  
          /* Search panel */
          searchPanel = new JPanel();
          myCollection = new BookCollection();
  
          isbn_lbl = new JLabel("Search by ISBN:");
          isbn_tf = new JTextField();
          isbn_tf.addActionListener(new ActionListener() {
              public void actionPerformed(ActionEvent event) {
                  ArrayList&lt;BookData&gt; data = myCollection.select(isbn_tf.getText(), BookCollection.FIELD_ISBN);
                  tableData.addNewRow();
                  table.setValueAt((new BigDecimal("1").toString()), tableData.getRowCount() - 1, 0);
                  table.setValueAt(Integer.toString(data.get(0).getQtyOnHand()), tableData.getRowCount() - 1, 1);
                  table.setValueAt(data.get(0).getIsbn(),tableData.getRowCount() - 1, 2);
                  table.setValueAt(data.get(0).getTitle(),tableData.getRowCount() - 1, 3);
                  table.setValueAt(data.get(0).getRetail().setScale(2, RoundingMode.HALF_UP).toString(), tableData.getRowCount() - 1, 4);
                  table.setValueAt(table.getValueAt(tableData.getRowCount() - 1, 4), tableData.getRowCount() - 1, 5);
                  isbn_tf.setText("");
              }
          });
  
          title_lbl = new JLabel("Search by Title:");
          title_tf = new JTextField();
          title_tf.addActionListener(new ActionListener() {
              public void actionPerformed(ActionEvent event) {
                  ArrayList&lt;BookData&gt; data = myCollection.select(title_tf.getText(), BookCollection.FIELD_TITLE);
                  tableData.addNewRow();
                  table.setValueAt((new BigDecimal("1").toString()), tableData.getRowCount(), 0);
                  table.setValueAt(Integer.toString(data.get(0).getQtyOnHand()), tableData.getRowCount() - 1, 1);
                  table.setValueAt(data.get(0).getIsbn(), tableData.getRowCount(), 2);
                  table.setValueAt(data.get(0).getTitle(), tableData.getRowCount(), 3);
                  table.setValueAt(data.get(0).getRetail().setScale(2, RoundingMode.HALF_UP).toString(), tableData.getRowCount(), 4);
                  table.setValueAt(data.get(0).getRetail().setScale(2, RoundingMode.HALF_UP).toString(), tableData.getRowCount(), 5);
                  title_tf.setText("");
              }
          });
  
          searchPanel.setLayout(new MigLayout("", "[78px][202px,grow]", "[24px][29px]"));
          searchPanel.add(isbn_lbl, "cell 0 0, alignx left, aligny center");
          searchPanel.add(isbn_tf, "cell 1 0,growx, aligny center");
          searchPanel.add(title_lbl, "cell 0 1, alignx left, aligny center");
          searchPanel.add(title_tf, "cell 1 1, growx, aligny center");
  
          add(searchPanel, BorderLayout.SOUTH);
  
      };
  
      public static void main(String[] args) {
          CashierPanel myCashierPanel = new CashierPanel();
          myCashierPanel.setVisible(true);
      }
  }
  
  class CashierTableModel extends AbstractTableModel implements CellEditorListener{
  
      /**
       * 
       */
      private static final long serialVersionUID = -1500952132717353189L;
      private ArrayList&lt;Object[]&gt; data = new ArrayList&lt;Object[]&gt;();
  
      public void addNewRow() {
          data.add(new String[] { null, null, null, null, null, null });
          fireTableDataChanged();
      }
  
      public int getRowCount() {
          return data.size();
      }
  
      public int getColumnCount() {
          return 6;
      }
  
      public Object getValueAt(int row, int col) {
          return data.get(row)[col];
      }
  
      public void setValueAt(Object value, int row, int col) {
          data.get(row)[col] = value;
          fireTableCellUpdated(row, col);
      }
  
      public boolean isCellEditable(int row, int col) {
          if (col &gt; 0) {
              return false;
          } else {
              return true;
          }
      }
  
      public void editingCanceled(ChangeEvent e) {
          for (int i = 0; i &lt;= getRowCount() - 1; i++) {
              BigDecimal[] data = new BigDecimal[3];
              data[0] = data[0].add((BigDecimal) getValueAt(i, 1));
              data[1] = data[1].add((BigDecimal) getValueAt(i, 4));
              data[2] = data[2].add(calculateTotal(data[0], data[1]));
              setValueAt(data[2], i, 5);
          }
      }
  
      public void editingStopped(ChangeEvent e) {
          for (int i = 0; i &lt;= getRowCount() - 1; i++) {
              BigDecimal[] data = new BigDecimal[3];
              data[0] = data[0].add((BigDecimal) getValueAt(i, 1));
              data[1] = data[1].add((BigDecimal) getValueAt(i, 4));
              data[2] = data[2].add(calculateTotal(data[0], data[1]));
              setValueAt(data[2], i, 5);
          }
      }
  
      public BigDecimal calculateTotal(BigDecimal qty, BigDecimal retail) {
          BigDecimal total = new BigDecimal("0.00");
          total = total.add(qty.multiply(retail));
          return total;
      }
  }
  </code></pre>
  
  <p>As this is homework, I do not want to be handed a working version of my code, with the bugs worked out.  I would just like some guidance on what it is that I am doing wrong to get the editor listener to actually be called.</p>
  
  <p>If there is any other information that I can provide that can help to guide me to a solution, please let me know.</p>
  
  <p>Thanks for taking the time to look at this!</p>