JTable使用AbstractTableModel删除多行

时间:2015-01-09 18:47:11

标签: java swing jtable

我的删除功能无法正常工作。我有一个带有customTableModel的JTable,扩展了AbstractTableModel。当我只删除1行时,它可以正常工作,但是当我尝试一次删除多行时,只有部分行被删除。

我的代码如下:

1。)主要方法的GUI类:

package jtabletest;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.*;

@SuppressWarnings("serial")
public class TableDeletingTest extends JFrame {

    private String[] columnNames = { "Selection", "ID" };
    private ArrayList<TableTestData> data;
    private JTable table;

    private JScrollPane scp;
    private JPanel pnlControls;
    private JButton btnDelete;

    public TableDeletingTest() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        createTestData(5);
        constructTable();
        createGUI();
        setListeners();

        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    private void createGUI() {
        scp = new JScrollPane(table);
        pnlControls = new JPanel(new FlowLayout(FlowLayout.CENTER));
        btnDelete = new JButton("delete");
        add(scp, BorderLayout.CENTER);
        add(pnlControls, BorderLayout.SOUTH);
        pnlControls.add(btnDelete);
    }

    private void createTestData(int length) {
        data = new ArrayList<TableTestData>();
        for (int i = 0; i < length; i++) {
            data.add(new TableTestData(i));
        }
    }

    private void constructTable() {
        MyTableTestModel model = new MyTableTestModel(data, columnNames);
        table = new JTable(model);
    }

    private void setListeners() {
        btnDelete.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                for (int i = 0; i < data.size(); i++) {
                    if (data.get(i).isSelected()) {
                        ((MyTableTestModel) table.getModel()).removeRow(i);
                    }
                }
            }
        });
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TableDeletingTest();
            }
        });
    }

}

2。)模型

package jtabletest;

import java.util.ArrayList;

import javax.swing.table.AbstractTableModel;

@SuppressWarnings("serial")
public class MyTableTestModel extends AbstractTableModel {

    private ArrayList<TableTestData> data;
    private String[] columnNames;

    public MyTableTestModel(ArrayList<TableTestData> data, String[] columnNames) {
        this.data = data;
        this.columnNames = columnNames;
    }

    @Override
    public int getRowCount() {
        return data.size();
    }

    @Override
    public int getColumnCount() {
        return columnNames.length;
    }

    @Override
    public String getColumnName(int col) {
        return columnNames[col];
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        switch (columnIndex) {
        case 0:
            return data.get(rowIndex).isSelected();
        case 1:
            return data.get(rowIndex).getId();
        default:
            return -1;
        }
    }

    @Override
    public Class<?> getColumnClass(int column) {
        return getValueAt(0, column).getClass();
    }

    @Override
    public boolean isCellEditable(int row, int column) {
        return column == 0;
    }

    @Override
    public void setValueAt(Object value, int row, int column) {
        if (value instanceof Boolean && column == 0) {
            data.get(row).setSelected((boolean) value);
            fireTableCellUpdated(row, column);
        }
    }

    public void removeRow(int row) {
        data.remove(row);
        fireTableRowsDeleted(row, row);
    }
}

3。)TableData:

    package jtabletest;

public class TableTestData {

    private int id;
    private boolean selected;

    public TableTestData(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }

}

任何人都知道我做错了什么?

提前致谢!

1 个答案:

答案 0 :(得分:0)

在本节中:

@Override
public void actionPerformed(ActionEvent e) {
    for (int i = 0; i < data.size(); i++) {
        if (data.get(i).isSelected()) {
            ((MyTableTestModel) table.getModel()).removeRow(i);
        }
    }
}

从结尾开始并迭代到开头删除,因为当你删除时,它正在删除data中的元素,并且当你迭代到下一个元素时你正在跳过一些行(通过i++ )。替换为:

@Override
public void actionPerformed(ActionEvent e) {
    for (int i = data.size()-1; i >= 0; --i) {
        if (data.get(i).isSelected()) {
            ((MyTableTestModel) table.getModel()).removeRow(i);
        }
    }
}