0

I am trying to delete multiple rows from a JTable that have been selected by the user. The code works and deletes the rows except for one row at which point it throws an ArrayOutOfBoundsException. The following is the code for the delete button.

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

Code for dataModel

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

StackTrace

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)
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Josh Beaver
  • 127
  • 8
  • 18

3 Answers3

2

As and when you remove an item from the model, the collection size reduces. hence any reference to an item above the size will through an exception.

1

Here is a simple approach that will allow you to delete selected rows from a table (or JList) by getting only one index at a time:

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

It will also handle tables that have been sorted or filtered.

camickr
  • 321,443
  • 19
  • 166
  • 288
0

In theory you need to convert selected rows to model as specified 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]); 

}

But if you don't have any sorting functionality, it may not be required. Just make sure that you are looping through list of rows which are "currently" present in table.

SomeDude
  • 13,876
  • 5
  • 21
  • 44