1

I am using a setValue(...) in a TableModelListener after multiplying to cell values. Without the .setValue the program runs fine, however, when it is added it seems as though the program runs indefinitely or until the exception is thrown.

Here is the code:

public void populateTable() {
    DefaultTableModel employeeModel = (DefaultTableModel) jTable1.getModel();
    employeeModel.addTableModelListener(new TableModelListener() {
        public void tableChanged(TableModelEvent e) {
            Integer totalDue = 0;
            Integer quantityValue = 0;
            Integer rateValue = 0;
            try {
                quantityValue = Integer.parseInt(employeeModel.getValueAt(0, 2).toString());
                rateValue = Integer.parseInt(employeeModel.getValueAt(0, 3).toString());
            } catch (NullPointerException f) {
            }
            totalDue = quantityValue * rateValue;
            System.out.println(totalDue);
            employeeModel.setValueAt(totalDue, 0, 4);
        }
    });
}
Erwin Bolwidt
  • 30,799
  • 15
  • 56
  • 79
  • *Never* catch NullPointerException. Check for null values instead. Of course, if your model is not supposed to have null quantity or rate values, then you should not even check; in that case, a NullPointerException indicates a bug in your model that should be fixed, not suppressed. – VGR Apr 15 '18 at 01:52

1 Answers1

3

it seems as though the program runs indefinitely

Every time you do setValue(...) you cause a TableModelEvent to be generated.

The code in your TableModelListener calculates the cost and then does another setValue(...) causing another TableModelEvent to be generated and you get yourself into the infinite loop.

So, in the TableModelListener you need to add a check for which column has changed and only calculate the cost when the value or quantity has changed.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;

public class TableProcessing extends JPanel implements TableModelListener
{
    public TableProcessing()
    {
        String[] columnNames = {"Item", "Quantity", "Price", "Cost"};
        Object[][] data =
        {
            {"Bread", new Integer(1), new Double(1.11), new Double(1.11)},
            {"Milk", new Integer(1), new Double(2.22), new Double(2.22)},
            {"Tea", new Integer(1), new Double(3.33), new Double(3.33)},
            {"Cofee", new Integer(1), new Double(4.44), new Double(4.44)}
        };

        DefaultTableModel model = new DefaultTableModel(data, columnNames)
        {
            //  Returning the Class of each column will allow different
            //  renderers to be used based on Class
            @Override
            public Class getColumnClass(int column)
            {
                return getValueAt(0, column).getClass();
            }

            //  The Cost is not editable
            @Override
            public boolean isCellEditable(int row, int column)
            {
                return (column == 3) ? false : true;
            }
        };
        model.addTableModelListener( this );

        JTable table = new JTable( model );
        table.setPreferredScrollableViewportSize(table.getPreferredSize());

        JScrollPane scrollPane = new JScrollPane( table );
        add( scrollPane );

        String[] items = { "Bread", "Milk", "Tea", "Coffee" };
        JComboBox<String> editor = new JComboBox<String>( items );

        DefaultCellEditor dce = new DefaultCellEditor( editor );
        table.getColumnModel().getColumn(0).setCellEditor(dce);
    }

    /*
     *  The cost is recalculated whenever the quantity or price is changed
     */
    public void tableChanged(TableModelEvent e)
    {
        if (e.getType() == TableModelEvent.UPDATE)
        {
            int row = e.getFirstRow();
            int column = e.getColumn();

            if (column == 1 || column == 2)
            {
                TableModel model = (TableModel)e.getSource();
                int quantity = ((Integer)model.getValueAt(row, 1)).intValue();
                double price = ((Double)model.getValueAt(row, 2)).doubleValue();
                Double value = new Double(quantity * price);
                model.setValueAt(value, row, 3);
            }
        }
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("Table Model Listener");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new TableProcessing());
        frame.pack();
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args) throws Exception
    {
        EventQueue.invokeLater( () -> createAndShowGUI() );
/*
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
*/
    }
}
camickr
  • 321,443
  • 19
  • 166
  • 288