JTable ->表模式监听器

2022-01-15 00:00:00 event-handling java jtable

我有这个 JTable 有一个 DefaultTableModel 作为它的模型.在桌子上,我有几个摆动组件,JComboBoxJCheckBox,通过 DefaultCellEditorDefaultCellRenderer 在特定列上设置.TableModelListener 已添加到表中以捕获可编辑列的更改.其余列将显示所选组件的详细信息,即商品代码 -> 商品价格、商品数量、商品分类等.

I have this JTable having a DefaultTableModel as its model. On the table I have several swing component, JComboBox and 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.

我有这个问题,如果 JComboBox(itemCode) 的 selectedItem 发生变化,其他 JComboBox(itemClassification) 的项目也会发生变化.但随着其他 JComboBox 的变化,我需要在同一张桌子上显示商品价格.此更改重新触发 valueChanged 方法,该方法使 valueChanged 无限循环.

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

相关文章