user2787386
user2787386

Reputation: 303

Clearing a JTable throws an arrayIndexOutOfBounds Issue

So I have a program that uses a JTable. Every time I want to delete a row and refresh the table it throws the following error.

 Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1

I've seen similar questions to this question posted a few times:

jTable populating and refreshing ArrayIndexOutOfBoundsException

and

Refreshing JTable in Swing Gives Exception

and

ArrayIndexOutOfBoundsException when trying to empty a JTable

and a few others.

but I can't seem to decipher what's causing this for me. What my program does is that on start up the table is populated using data from a database. I am not inserting objects into the table; just string values directly from the database. My screen looks like this:

enter image description here

Selecting a row puts its values into the text boxes at the top of the frame. Ideally if I were to click delete the ID from the Office_ID field would then be used to delete a row from my database and the table would be refreshed to remove the row. The delete is working fine but instead of refreshing the table my program just throws the array index out of bounds error.

The code for building the table is here:

    private DefaultTableModel estateModel;
private JTextField IDField, addressField, suburbField, postcodeField, stateField, phoneField, faxField; 
private JTable estateTable;
private final JPanel containerPanel;
private JButton add, edit, view, delete, search, close;

public EstateScreen()
{
    containerPanel = new JPanel();
    containerPanel.setLayout(new BoxLayout(containerPanel, BoxLayout.Y_AXIS));
    addGridToPanel();
    addTableToPanel();
    addButtonsToPanel();
}


private void addTableToPanel()
{
    JPanel tablePane = new JPanel(new BorderLayout(2,2));
    String[] colNames = {"Office ID", "Address", "Suburb", "Postcode", "State", "Phone Number", "Fax Number"};
    estateModel = new DefaultTableModel()
    {
        @Override
        public boolean isCellEditable(int row, int column)
        {
            return false;
        }
    };
    estateModel.setColumnIdentifiers(colNames);
    estateTable = new JTable(estateModel);
    JScrollPane scroll = new JScrollPane(estateTable);
    tablePane.add(scroll);

    estateTable.getSelectionModel().addListSelectionListener(new ListSelectionListener()
    {
        @Override
        public void valueChanged(ListSelectionEvent event)
        {
            IDField.setText(estateTable.getValueAt(estateTable.getSelectedRow(),0).toString());
            addressField.setText(estateTable.getValueAt(estateTable.getSelectedRow(),1).toString());
            suburbField.setText(estateTable.getValueAt(estateTable.getSelectedRow(),2).toString());
            postcodeField.setText(estateTable.getValueAt(estateTable.getSelectedRow(),3).toString());
            stateField.setText(estateTable.getValueAt(estateTable.getSelectedRow(),4).toString());
            phoneField.setText(estateTable.getValueAt(estateTable.getSelectedRow(),5).toString());
            faxField.setText(estateTable.getValueAt(estateTable.getSelectedRow(),6).toString());
        }
    });

    containerPanel.add(tablePane);
}

My method for clearing the table:

    public void clearTable()
{
    estateModel.setRowCount(0);
    /*
   estateModel.removeTableModelListener(estateTable);
   while(estateModel.getRowCount() > 0)
   {
       estateModel.removeRow(0);
   }
   estateModel.addTableModelListener(estateTable);*/
}

and the actionListener for the delete button:

        gui.getEstateScreen().getDelete().addActionListener(new ActionListener()
    {
        @Override
        public void actionPerformed(ActionEvent e)
        {
            if(office.deleteByID(connB, gui.getEstateScreen().getID(), "office_id"))
            {
                gui.getEstateScreen().clearTable();
                populateEmployerScreen();
            }
            else
            {
                gui.getEstateScreen().outputAddError("Could not delete this office");
            }
        }
    });

and the populate Screen method as well for good measure:

    private void populateEmployerScreen()
{
    try
    {
        ResultSet rs = office.getAllData(connB);
        while(rs.next())
        {
            String[] data = new String[7];
            data[0] = Integer.toString(rs.getInt("OFFICE_ID"));
            data[1] = rs.getString("ADDRESS");
            data[2] = rs.getString("SUBURB");
            data[3] = Integer.toString(rs.getInt("POSTCODE"));
            data[4] = rs.getString("STATE");
            data[5] = rs.getString("PHONE_NUMBER");
            data[6] = rs.getString("FAX_NUMBER");

            gui.getEstateScreen().getModel().addRow(data);
        }

    }
    catch(SQLException s)
    {

    }

}

One last point. Interestingly, if I call the clear table method at the start of my program when no rows are selected it works fine. The moment I click on one of the rows however it begins throwing the array index out of bounds error. The only thing I can think of for this is that it somehow has trouble clearing a row when it is selected.

Can anyone help me with this?

Stack trace:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.Vector.elementData(Vector.java:730)
at java.util.Vector.elementAt(Vector.java:473)
at javax.swing.table.DefaultTableModel.getValueAt(DefaultTableModel.java:649)
at javax.swing.JTable.getValueAt(JTable.java:2717)
at view.main.EstateScreen$2.valueChanged(EstateScreen.java:95)
at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:184)
at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:164)
at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:211)
at javax.swing.DefaultListSelectionModel.removeIndexInterval(DefaultListSelectionModel.java:677)
at javax.swing.JTable.tableRowsDeleted(JTable.java:4509)
at javax.swing.JTable.tableChanged(JTable.java:4412)
at javax.swing.table.AbstractTableModel.fireTableChanged(AbstractTableModel.java:296)
at javax.swing.table.AbstractTableModel.fireTableRowsDeleted(AbstractTableModel.java:261)
at javax.swing.table.DefaultTableModel.setNumRows(DefaultTableModel.java:321)
at javax.swing.table.DefaultTableModel.setRowCount(DefaultTableModel.java:339)
at view.main.EstateScreen.clearTable(EstateScreen.java:158)
at controller.RealEstateAgency$4.actionPerformed(RealEstateAgency.java:154)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6516)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6281)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4872)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4698)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4698)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:740)
at java.awt.EventQueue.access$300(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:699)
at java.awt.EventQueue$3.run(EventQueue.java:697)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:713)
at java.awt.EventQueue$4.run(EventQueue.java:711)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:710)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

Upvotes: 0

Views: 2491

Answers (3)

Hasan
Hasan

Reputation: 1

It's a bit late, but try adding the code line below before setting the text of the textboxes in ListSelectionListener

if (!e.getValueIsAdjusting() && estateTable.getSelectedRow() != -1)

Upvotes: 0

Dakshinamurthy Karra
Dakshinamurthy Karra

Reputation: 5463

It is better to follow the standard idioms of the framework/language. Instead of adding and removing the listener, add a guard to your valueChanged method.

public void valueChanged(ListSelectionEvent event) {
    int selectedRow = estateTable.getSelectedRow();
    if(selectedRow == -1) {
        // Most probably you should be clearing the text fields
        // here. At the least do a return
        return;
    }
    // Other code
}

Upvotes: 2

user2787386
user2787386

Reputation: 303

Big thanks to KDM for pointing out that the problem was with my ListSelectionListener.

Solved my issue by removing the listener before clearing the table and then adding it again afterwards.

public void clearTable()
{
    estateTable.getSelectionModel().removeListSelectionListener(listener);
    estateModel.setRowCount(0);
    estateTable.getSelectionModel().addListSelectionListener(listener);
}

Upvotes: 0

Related Questions