从JTable中删除行 - Java

时间:2016-07-25 12:03:04

标签: java swing jtable indexoutofboundsexception

我正在尝试从JTable中删除用户已选择的多行。代码工作并删除除一行之外的行,此时它会抛出ArrayOutOfBoundsException。以下是删除按钮的代码。

public void mouseClicked(MouseEvent e) {

            int[] rows = dataTable.getSelectedRows();

            if(rows.length == 0){
                JOptionPane.showMessageDialog(null, "No records are selected");
            }else if(JOptionPane.showConfirmDialog(null, "Are you sure you want to permanently delete " +
                        rows.length + " selected record(s)") == 0){

                for(int i = 0; i < rows.length; i++){
                    System.out.println("Value at " + rows[i] + ": " + dataModel.getValueAt(rows[i], 0));

                }

                for(int i = 0; i < rows.length; i++){
                    System.out.println("Current Row ("+ i +"): " + rows[i]);
                    dataModel.removeRow(rows[i]); // Throws error

                }

                    dataTable.revalidate();
                    dataTable.repaint();
                }
        }

dataModel的代码

dataModel = new DefaultTableModel() {
        @Override
        public boolean isCellEditable(int row, int column) {
            return false;
        }
    };

栈跟踪

java.lang.ArrayIndexOutOfBoundsException: 3 >= 2
at java.util.Vector.removeElementAt(Vector.java:558)
at javax.swing.table.DefaultTableModel.removeRow(DefaultTableModel.java:462)
at com.company.fitness.DataPanel$4.mouseClicked(DataPanel.java:213)
at java.awt.AWTEventMulticaster.mouseClicked(AWTEventMulticaster.java:270)

3 个答案:

答案 0 :(得分:2)

当您从模型中删除项目时,集合大小会减少。因此,任何对大小以上项目的引用都将通过例外。

答案 1 :(得分:1)

这是一种简单的方法,允许您通过一次只获取一个索引来从表(或JList)中删除选定的行:

import java.awt.*;
import java.awt.event.*;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.*;
import javax.swing.table.*;

public class ItemDeletion extends JPanel
{
    private JList<String> list;
    private JTable table;

    public ItemDeletion()
    {
        setLayout( new BorderLayout(5, 5) );

        String[] items =
        {
            "One",
            "Two",
            "Three",
            "Four",
            "Five",
            "Six",
            "Seven",
            "Eight",
            "Nine",
            "Ten"
        };

        //  Add the list

        DefaultListModel<String> listModel = new DefaultListModel<String>();

        for (String item: items)
            listModel.addElement( item );

        list = new JList<String>( listModel );


        JButton listDelete = new JButton( "Delete From List" );
        listDelete.addActionListener( new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                DefaultListModel model = (DefaultListModel)list.getModel();
                int row = list.getSelectedIndex();

                while (row != -1)
                {
                    model.removeElementAt( row );
                    row = list.getSelectedIndex();
                }
            }
        });

        JPanel listPanel = new JPanel( new BorderLayout(5, 5) );
        listPanel.add(new JScrollPane( list ), BorderLayout.CENTER);
        listPanel.add(listDelete, BorderLayout.PAGE_END);

        //  Add the table

        DefaultTableModel tableModel = new DefaultTableModel(0, 1);
        List<String> tableItems = Arrays.asList( items );
        Collections.shuffle( tableItems );

        for (String item: tableItems)
        {
            tableModel.addRow( new String[]{item} );
        }

        table = new JTable( tableModel );

        table.setAutoCreateRowSorter(true);
        ((DefaultRowSorter)table.getRowSorter()).toggleSortOrder(0);

        JButton tableDelete = new JButton( "Delete From Table" );
        tableDelete.addActionListener( new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                DefaultTableModel model = (DefaultTableModel)table.getModel();
                int row = table.getSelectedRow();

                while (row != -1)
                {
                    int modelRow = table.convertRowIndexToModel( row );
                    model.removeRow( modelRow );
                    row = table.getSelectedRow();
                }
            }
        });

        JPanel tablePanel = new JPanel( new BorderLayout(5, 5) );
        tablePanel.add(new JScrollPane( table ), BorderLayout.CENTER);
        tablePanel.add(tableDelete, BorderLayout.PAGE_END);

        add(listPanel, BorderLayout.LINE_START);
        add(tablePanel, BorderLayout.LINE_END);
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("Multiple Item Deletion");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new ItemDeletion(), BorderLayout.NORTH);
        frame.setLocationByPlatform( true );
        frame.pack();
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
    }
}

它还将处理已排序或过滤的表。

答案 2 :(得分:0)

理论上,您需要将所选行转换为指定here

的模型
for(int i = 0; i < rows.length; i++)
{
    System.out.println("Current Row ("+ i +"): " + rows[i]);
    rows[i] = dataTable.convertRowIndexToModel(rows[i]);                              
    dataModel.removeRow(rows[i]); 

}

但是如果您没有任何排序功能,则可能不需要。只需确保循环遍历表中“当前”的行列表​​。