JTable使用AbstractTableModel删除多行 [英] JTable delete multiple rows with AbstractTableModel

查看:62
本文介绍了JTable使用AbstractTableModel删除多行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I cannot get my delete function work correctly. I have a JTable with a customTableModel, extending AbstractTableModel. When I delete just 1 row, it works alright, but as soon as I try to delete multiple rows at once just part of it gets deleted.

我的代码如下:

1.)具有主要方法的GUI类:

1.) GUI class with main method:

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:

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;
    }

}

有人知道我在做什么错吗?

Anyone knows what I'm doing wrong?

提前谢谢!

推荐答案

在本节中:

@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++),您将跳过一些行.替换为:

Start from the end and iterate to the beginning to delete because when you delete, it is deleting elements from data, and you are skipping some rows when you iterate to the next element (via i++). Replace with:

@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);
        }
    }
}

这篇关于JTable使用AbstractTableModel删除多行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆