我收到一个java.lang.IndexOutOfBoundsException:我设置的AbstractTableModel的无效范围错误,用于显示我的ArrayList的内容。我认为这与自动排序表有关。如何修复setAutoRowSorter()?
我有一个班级'帐户'它包含另一个类' Client'的ArrayList。
Client类包含将在表格中显示的信息:
该表是使用拖放创建的。我还在这里创建了一个快速帐户和客户,并列出了该表的简短列表:
package presentation;
import domain.Account;
import domain.Client;
public class ClientTable extends javax.swing.JFrame {
private Account account = null;
private ClientAbstractTableModel model = new ClientAbstractTableModel();
private int selectedRow = -1;
public void setAccount(Account account) {
this.account = account;
model.setClients(account.getClientList());
}
public ClientTable() {
initComponents();
myTable.setModel(model);
myTable.setAutoCreateRowSorter(true);
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
myTable = new javax.swing.JTable();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
myTable.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
},
new String [] {
"Select", "First name", "Last name"
}
) {
Class[] types = new Class [] {
java.lang.Boolean.class, java.lang.String.class, java.lang.String.class
};
public Class getColumnClass(int columnIndex) {
return types [columnIndex];
}
});
jScrollPane1.setViewportView(myTable);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(187, 187, 187)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(243, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(91, 91, 91)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(154, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
Account account = new Account();
Client clientA = new Client(false, "John", "Smith", "New York", "Current");
Client clientB = new Client(false, "Jane", "Doe", "London", "Prospective");
account.addClient(clientA);
account.addClient(clientB);
ClientTable clientTable = new ClientTable();
clientTable.setAccount(account);
clientTable.setVisible(true);
}
// Variables declaration - do not modify
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTable myTable;
// End of variables declaration
}
最后这里是AbstractTableModel:
package presentation;
import domain.Client;
import java.util.ArrayList;
import javax.swing.table.AbstractTableModel;
public class ClientAbstractTableModel extends AbstractTableModel {
private String[] columnNames = {"Select", "First Name", "Last Name", "City", "Status"};
private ArrayList<Client> clients = new ArrayList<>();
public void setClients(ArrayList<Client> clients) {
this.clients = clients;
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public int getRowCount() {
return clients.size();
}
@Override
public String getColumnName(int column) {
return columnNames[column];
}
@Override
public Object getValueAt(int row, int column) {
Object value = null;
Client client = clients.get(row);
switch (column) {
case 0:
value = client.getSelected();
break;
case 1:
value = client.getFirstName();
break;
case 2:
value = client.getLastName();
break;
case 3:
value = client.getCity();
break;
case 4:
value = client.getStatus();
break;
}
return value;
}
@Override
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
@Override
public boolean isCellEditable(int row, int col) {
return true;
}
@Override
public void setValueAt(Object value, int row, int column) {
Client client = clients.get(row);
switch (column) {
case 0:
if (value instanceof Boolean)
client.setSelected((boolean)value);
break;
case 1:
client.setFirstName((String)value);
break;
case 2:
client.setLastName((String)value);
break;
case 3:
client.setCity((String)value);
break;
case 4:
client.setStatus((String)value);
break;
}
fireTableCellUpdated(row, column);
}
}
单击其中一个复选框时发生错误。点击一个之后,我再也无法点击其他的,但我可以继续点击我点击的第一个。
在Exception详细信息中,我注意到了这一点:
at presentation.ClientListTableModel.setValueAt(ClientListTableModel.java:152)
是fireTableCellUpdated(行,列);在setValueAt()方法中。
有趣的是,当我删除
myTable.setAutoCreateRowSorter(true);
从代码中,程序正常运行。但是,我该如何解决这个问题呢?我仍然希望能够通过单击其中一个列标题对表进行排序。
作为参考,我从this post和this Java documentation获得了有关如何设置表格的一些信息。
谢谢!
编辑:删除了一些不必要的代码段。