I apologize for asking a question that's been asked a lot in various forms, but I have yet to find a complete answer that works. All I'm trying to do is to append a row to a tablemodel. I've tried doing it in a lot of different ways but always run into similar issues (or sometimes new and exciting ones). Anyway, when I try to add the row I get an "ArrayIndexOutOfBoundsException" error. I've marked the line where the error occurs in the code below. I've also included the errors I've seen and debugging output I've been using. I'm aware I don't really need to extend the DefaultTableModel for what you see here, but this is a stripped down version that I've been working with to chase the bug.
Exception:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 2 > 0 at java.util.Vector.insertElementAt(Vector.java:594) at javax.swing.table.DefaultTableModel.insertRow(DefaultTableModel.java:374) at javax.swing.table.DefaultTableModel.addRow(DefaultTableModel.java:350) at javax.swing.table.DefaultTableModel.addRow(DefaultTableModel.java:361) at SMC.RoleCard$1.actionPerformed(RoleCard.java:69) 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:6505) at javax.swing.JComponent.processMouseEvent(JComponent.java:3321) at java.awt.Component.processEvent(Component.java:6270) at java.awt.Container.processEvent(Container.java:2229) at java.awt.Component.dispatchEventImpl(Component.java:4861) at java.awt.Container.dispatchEventImpl(Container.java:2287) at java.awt.Component.dispatchEvent(Component.java:4687) 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:4687) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:729) at java.awt.EventQueue.access$200(EventQueue.java:103) at java.awt.EventQueue$3.run(EventQueue.java:688) at java.awt.EventQueue$3.run(EventQueue.java:686) 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:702) at java.awt.EventQueue$4.run(EventQueue.java:700) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) at java.awt.EventQueue.dispatchEvent(EventQueue.java:699) 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)
Debug Output:
There are 2 elements in roleData
roleData has 2 elements
Performing WHILE loop
tableData[0][0] is assigned ECC
tableData[0][1] is assigned 1
Performing WHILE loop
tableData[1][0] is assigned Portal
tableData[1][1] is assigned 2
Called getColumnCount()
Returned 2
tableDate has 2 columns and 2 rows.
Called getColumnCount()
Returned 2
Called getColumnName()
Returned Role
Called getColumnCount()
Returned 2
Called getColumnName()
Returned Sort Order
Called getColumnCount()
Returned 2
arg is :Role Data:
Clicked on Role
Called getColumnClass()
Called getColumnClass()
Called getColumnClass()
Called getColumnClass()
B: There are 2 rows in RoleTableModel
Add was pressed
Code:
package SMC;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.Vector;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
/**
* @author Larry Krigbaum
*/
public class RoleCard
{
public JPanel getRoleCard()
{
final JPanel roleCard = new JPanel();
roleCard.setLayout(new BoxLayout(roleCard, BoxLayout.PAGE_AXIS));
roleCard.setAlignmentX(Component.CENTER_ALIGNMENT);
JPanel role_title = new JPanel();
role_title.add(new JLabel(" "));
role_title.add(new JLabel("Configure SAP Roles"));
role_title.add(new JLabel(" "));
roleCard.add(role_title);
final JPanel role_table = new JPanel();
String[] roleColumnNames = {"Role", "Sort Order"};
ArrayList<Role> roleData = Role.loadRoleData();
System.out.println("There are " + roleData.size() + " elements in roleData");
//ArrayList<Role> roleData = null;
final RoleTableModel roleTableModel = new RoleTableModel(roleColumnNames, roleData);
JTable roleEditTable = new JTable(roleTableModel);
roleEditTable.setAutoCreateRowSorter(true);
//final DefaultTableModel roleTableModel = (DefaultTableModel) roleEditTable.getModel();
//final JTable roleEditTable = getRoleTable();
role_table.add(new JScrollPane(roleEditTable)); // ScrollPane needed to show headers
roleCard.add(role_table);
JPanel buttonPanel = new JPanel();
JButton addButton = new JButton("Add");
addButton.setActionCommand("Add");
JButton deleteButton = new JButton("Delete");
deleteButton.setActionCommand("Delete");
final JButton cancelButton = new JButton("Cancel");
cancelButton.setActionCommand("Cancel");
cancelButton.setEnabled(false);
buttonPanel.add(addButton);
buttonPanel.add(deleteButton);
buttonPanel.add(cancelButton);
roleCard.add(buttonPanel);
addButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
System.out.println("B: There are " + roleTableModel.getRowCount() + " rows in RoleTableModel");
System.out.println("Add was pressed");
cancelButton.setEnabled(true);
Object[] newRole = null;
roleTableModel.addRow(newRole);
//Object[] newRole = new Object[] {" ", " "};
System.out.println("A: There are " + roleTableModel.getRowCount() + " rows in RoleTableModel");
//roleTableModel.setRowCount((roleTableModel.getRowCount()) + 1);
System.out.println("B: There are " + roleTableModel.getRowCount() + " rows in RoleTableModel");
roleTableModel.fireTableRowsInserted(roleTableModel.getRowCount(), roleTableModel.getRowCount());
roleTableModel.fireTableDataChanged();
}
});
deleteButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
System.out.println("Delete was pressed");
cancelButton.setEnabled(true);
}
});
cancelButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
System.out.println("Cancel was pressed");
cancelButton.setEnabled(false);
}
});
return roleCard;
}
class RoleTableModel extends DefaultTableModel
{
private String[] roleColumnNames = {"Role", "Sort Order"};
private Object[][] tableData;
public RoleTableModel(String[] roleColumnNames, ArrayList<Role> roleData)
{
System.out.println("roleData has " + roleData.size() + " elements");
tableData = new Object[roleData.size()][2];
Role role = new Role();
Collections.sort(roleData, Role.MakeComparator);
Iterator rolesOrderByRole = roleData.iterator();
int i = 0;
while (rolesOrderByRole.hasNext())
{
System.out.println("Performing WHILE loop");
role = (Role)rolesOrderByRole.next();
tableData[i][0] = role.xrole;
System.out.println("tableData[" + i + "][0] is assigned " + tableData[i][0]);
tableData[i][1] = role.sortOrder;
System.out.println("tableData[" + i + "][1] is assigned " + tableData[i][1]);
i++;
}
System.out.println("tableDate has " + getColumnCount() + " columns and " + getRowCount() + " rows.");
}
@Override
public int getColumnCount()
{
System.out.println("Called getColumnCount()");
System.out.println("Returned " + roleColumnNames.length);
return roleColumnNames.length;
}
@Override
public int getRowCount()
{
if (tableData == null)
return 0;
return tableData.length;
}
@Override
public String getColumnName(int col)
{
System.out.println("Called getColumnName()");
System.out.println("Returned " + roleColumnNames[col]);
return roleColumnNames[col];
}
@Override
public Object getValueAt(int row, int col)
{
return tableData[row][col];
}
@Override
public Class getColumnClass(int c)
{
System.out.println("Called getColumnClass()");
return getValueAt(0, c).getClass();
}
/*
* Don't need to implement this method unless your table's
* editable.
*/
@Override
public boolean isCellEditable(int row, int col)
{
System.out.println("Called isCellEditable()");
//Note that the data/cell address is constant,
//no matter where the cell appears onscreen.
return true;
}
/*
* Don't need to implement this method unless your table's
* data can change.
*/
@Override
public void setValueAt(Object value, int row, int col)
{
System.out.println("Called setValueAt()");
tableData[row][col] = value;
fireTableCellUpdated(row, col);
}
}