我有一个带有JTable的Swing桌面应用程序。向JTable添加行时没有问题。我也可以排序(使用JTable.autoCreateRowSorter
),然后顺利删除该行(使用convertRowIndexToModel
)。
当我在JTable更新的文本框中搜索时,我确实遇到了问题,只显示包含查询的行。当我在输入搜索词后尝试删除一行时,会发生奇怪的事情:
public class EmployeeRecords extends javax.swing.JFrame {
ArrayList<Employee> employees = new ArrayList <Employee> ();
...
private void search(String query) {
//Create new table sorter for the table
TableRowSorter sorter = new TableRowSorter(employeeTable.getModel());
//Add row filter to the tablerowsorter (regex)
sorter.setRowFilter(RowFilter.regexFilter("(?i).*\\Q"+query+"\\E.*") );
//Apply the results to the output table
employeeTable.setRowSorter(sorter);
}
private void deleteButtonActionPerformed() {
//Get the index of the employee to delete
int employee = employeeTable.convertRowIndexToModel(
employeeTable.getSelectedRow());
employees.remove(employee); //This is where the IndexOutOfBoundsException occurs
refreshTable();
}
/**
* Refreshes the employee table. Uses the "employees" class array list to
* populate the rows.
*/
private void refreshTable() {
//Delete all the rows in the table
DefaultTableModel tbm = (DefaultTableModel) employeeTable.getModel();
for (int i=employeeTable.getRowCount()-1; i >= 0; i--) {
tbm.removeRow(i);
}
//For every employee
for (int i=0; i < employees.size(); i++) {
//Add the employee's data to a table row
tbm.addRow(employees.get(i).getData());
}
}
}
我会尝试删除一行,有时它会复制我想要删除的行。其他时候我得到一个IndexOutOfBoundsException,可能是因为indeces搞砸了。
我不理解someone with the same problem的解决方案,因为我对Swing Timers等知之甚少。
我还确保将行indeces转换为模型suggested in this question.
关于如何解决此问题的任何想法?
更新:这是正在发生的事情的基本截图。 搜索“a”,“a”和“aa”显示:
当我选择“a”并单击“删除所选项”时,结果如下:
现在,如果我试图继续删除“aa”,那么我最终会得到一个IndexOutOfBoundsException。
更新2:这是员工类:
public class Employee {
//Class fields
Integer employeeIdNumber;
String firstName, lastName, startDate;
Double annualSalary;
/* Constructor for the Employee object */
public Employee(Integer employeeIdNumber, String firstName, String lastName,
Double annualSalary, String startDate) {
//Assign paramters to class fields
this.employeeIdNumber = employeeIdNumber;
this.firstName = firstName;
this.lastName = lastName;
this.annualSalary = annualSalary;
this.startDate = startDate;
}
/**
* Gets the data for the employee (ID, firstname, lastname, annual salary,
* and start date, in that order)
*
* @return an Object[] of the abovementioned employee data.
*/
public Object[] getData() {
return new Object[] {
employeeIdNumber,
firstName,
lastName,
annualSalary,
startDate
};
}
}
FIX(感谢camickr): 我为删除按钮更改了以下代码
private void deleteButtonActionPerformed(java.awt.event.ActionEvent evt) {
DefaultTableModel tbm = (DefaultTableModel) employeeTable.getModel();
//Get the index of the employee to delete
int employee = employeeTable.convertRowIndexToModel(
employeeTable.getSelectedRow());
//Delete the row directly
tbm.removeRow(employee);
//as well as delete the employee from the array
employees.remove(employee);
}
答案 0 :(得分:3)
不确定我理解你的设计。您有一个DefaultTableModel,并且您还有一个包含您的员工的ArrayList。
员工数据应存储在TableModel中。应该不需要重新创建TableModel,因为您应该从模型中删除该行,并且表将重新绘制自己。
另外,作为使用DefaultTableModel时的注释,您只需使用以下内容删除所有行:
model.setRowCount(0);
答案 1 :(得分:0)
删除refreshTable
方法中的所有行时,请尝试更改逻辑
while(employeeTable.getRowCount() > 0) {
tbm.removeRow(0);
}
这可确保您不会获得IndexOutOfBoundsException
。也可以解决重复行显示的其他问题。