繁体   English   中英

JTable / DefaultTableModel中的TableModelListener和addRow干扰

[英]TableModelListener and addRow interference in JTable/DefaultTableModel

TableModelListener(第87行/ HERE-1行)是否干扰了JTable的addRow方法(第139行,HERE-2行)? 如果是这样,我该如何解决?

这段代码将编译,但是当我使用“添加行”按钮时会引发错误。 错误是:(堆栈跟踪的时间更长,但是我将其简化为关于我的类的行,而不是关于Java API的行)

线程“ AWT-EventQueue-0”中的异常java.lang.ArrayIndexOutOfBoundsException:

在HPLC.addRow(HPLC.java:142)

HPLC.lambda $ new $ 1(HPLC.java:109)

自从我添加了TableModelListener之后,这只是一个问题。

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

class HPLC extends JFrame
{
    public static void main (String [] args)
    {
        new HPLC();
    }
    HPLC()
    {
        //create window
        JFrame frame = new JFrame();
        frame.setTitle("HPLC Calculator");
        frame.setSize(500,750);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel panel = new JPanel();
        panel.setLayout(new GridBagLayout());

        //row 0
        JLabel title = new JLabel("HPLC Gradient Calculator");
        gridBagAdd(panel, title, 0,0,4,1, GridBagConstraints.CENTER);

        //row 1
        JLabel flowLabel = new JLabel("Flow rate");
        gridBagAdd(panel, flowLabel, 0,1,1,1, GridBagConstraints.CENTER);

        JTextField flow = new JTextField(5);
        gridBagAdd(panel, flow, 1,1,1,1, GridBagConstraints.CENTER);

        JLabel mlMinLabel = new JLabel("ml/min");
        gridBagAdd(panel, mlMinLabel, 2,1,1,1, GridBagConstraints.CENTER);

        //row 2
        JLabel numInjLabel = new JLabel("Number of injections");
        gridBagAdd(panel, numInjLabel, 0,2,1,1, GridBagConstraints.CENTER);

        JTextField numInj = new JTextField(5);
        gridBagAdd(panel, numInj, 1,2,1,1, GridBagConstraints.CENTER);

        //row 3
        JLabel volALabel = new JLabel("Volume of A");
        gridBagAdd(panel, volALabel, 0,3,1,1, GridBagConstraints.CENTER);

        JTextField volA = new JTextField(5);
        volA.setEditable(false);
        gridBagAdd(panel, volA, 1,3,1,1, GridBagConstraints.CENTER);

        JLabel volBLabel = new JLabel("Volume of B");
        gridBagAdd(panel, volBLabel, 2,3,1,1, GridBagConstraints.CENTER);

        JTextField volB = new JTextField(5);
        volB.setEditable(false);
        gridBagAdd(panel, volB, 3,3,1,1, GridBagConstraints.CENTER);

        //row 4
        JButton calculate = new JButton("calculate");
        gridBagAdd(panel, calculate, 0,4,1,1, GridBagConstraints.CENTER);

        JButton addRow = new JButton("add row");
        gridBagAdd(panel, addRow, 1,4,1,1, GridBagConstraints.CENTER);

        JButton removeRow = new JButton("remove row");
        gridBagAdd(panel, removeRow, 2,4,1,1, GridBagConstraints.CENTER);

        //the gradient table
        String[] columns = {"Time", "%A", "%B"};
        DefaultTableModel model = new DefaultTableModel(columns, 2)
        {
            public boolean isCellEditable(int row, int column)
            //this overrides the default method to suit these conditions to make the 3rd column read only
            {
                if (column == 2)
                    return false;
                return true;
            }
        };
        JTable table = new JTable(model);
        table.setFillsViewportHeight(true);
        JScrollPane tablePane = new JScrollPane(table);
        gridBagAdd(panel, tablePane, 0,5,4,4, GridBagConstraints.CENTER);
        table.getModel().addTableModelListener(new TableModelListener()
   //HERE-1 {
                public void tableChanged(TableModelEvent e)
                //overriding the TableModelListener method
                {
                    //the basics in order to get the table cell
                    int row = e.getFirstRow();
                    int column = e.getColumn();
                    TableModel model = (TableModel)e.getSource();
                    String ColumnName = model.getColumnName(column);
                    Object data = model.getValueAt(row, column);

                    //what i do with that cell
                    volB.setText(data.toString());
                }   
            });

        //button methods
        calculate.addActionListener(e -> calculate(model, volA));
        addRow.addActionListener(e -> addRow(model));
        removeRow.addActionListener(e -> removeRow(model));

        //make visible
        frame.add(panel);
        frame.setVisible(true);
    }
    //method for placement of components
    private void gridBagAdd(JPanel p, JComponent c, int x, int y, int width, int height, int align)
    {
        GridBagConstraints gc = new GridBagConstraints();
        gc.gridx = x;
        gc.gridy = y;
        gc.gridwidth = width;
        gc.gridheight = height;
        gc.weightx = 100;
        gc.weighty = 100;
        gc.insets = new Insets(5,5,5,5);
        gc.anchor = align;
        gc.fill = GridBagConstraints.NONE;
        p.add(c, gc);
    }
    //button method execution
    private void calculate(DefaultTableModel model, JTextField volA)
    {
            int rowCount = model.getRowCount();
            String msg = rowCount + " rows";
            volA.setText(msg);
    }
    private void addRow(DefaultTableModel model)
    {
        int colCount = model.getColumnCount();
//HERE-2 Object [] newRow = new Object[colCount];
        model.addRow(newRow);
    }
    private void removeRow(DefaultTableModel model)
    {
        int rowCount = model.getRowCount();
        if (rowCount > 2)
            model.removeRow(rowCount -1);
    }
}

我想要我的表做的是基于表的内容创建一个数组,以便执行计算。 添加了TableModelListener,以便%B列将自动完成以总计100%。

我是自学成才的,这是任何人第一次看到我的任何代码。 如果您对如何改善我的写作方法有任何建议,我将很高兴听到。

您将添加一个新行,因此TableModelListener将在您的事件中为column属性返回ALL_COLUMNS常量,该值为-1 reference

int column = e.getColumn(); // here

然后尝试在此处使用该-1值:

Object data = model.getValueAt(row, column);

这显然是行不通的。

解决方案:使用监听器之前,请检查它们的columns值。 也许您会希望将int文字用作列值。

已添加TableModelListener,以便%B列将自动完成以总计为100%

该事件将告诉您生成它的原因。 在我看来,您只想在更改单元格中的值时执行代码。

因此,代码应类似于:

public void tableChanged(TableModelEvent e)
{
    if (e.getType() == TableModelEvent.UPDATE)
    {
        // add processing here
    }
}

有关工作示例,请查看: JTable-> TableModeListener

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM