开发者

JTable -> TableModeListener

I have this JTable having a DefaultTableModel as its model. On the table I have several swing component, JComboBox a开发者_开发技巧nd JCheckBox, set on a particular column via DefaultCellEditor and DefaultCellRenderer. The TableModelListener was added to the table to capture changes on editable columns. The rest of the columns will display details of the selected component, i.e. item code -> item price, item count, item classification,etc.

I have this problem wherein if the selectedItem of the JComboBox(itemCode) changes, the items of the other JComboBox(itemClassification) changes. But together with the change of the other JComboBox I need to display the item price on the same table. This change refires the valueChanged method which makes an infinite loop of valueChanged.

How can I get rid of the infinite loop thing?


One way is to check the update event to see what column the event is for and ignore columns that are automatically updated:

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();
            }
        });
*/
    }
}


You could remove the listener when making changes from within the listener itself, and then re-add it when done with changes. Or you could give the Listener a boolean property that activates and deactivates the listener code, and set it appropriately from within the listener.


Actually... I have also my answer. I just get into the API of TableModelListener and I found the TableModelEvent.getColumn()

Thanks guys...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜