3

我有一个带有 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,可能是因为索引被搞砸了。

我不理解遇到同样问题的人的解决方案,因为我对 Swing Timers 等知之甚少。

我还确保按照此问题中的建议将行索引转换为模型。

关于如何解决这个问题的任何想法?

更新:这是正在发生的事情的基本屏幕截图。 在此处输入图像描述 搜索“a”和“a”和“aa”出现: 在此处输入图像描述

当我选择“a”并单击 Delete Selected 时,结果如下: 在此处输入图像描述

现在,如果我尝试继续删除“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);
} 
4

2 回答 2

3

不确定我是否理解您的设计。您有一个 DefaultTableModel,并且您还有一个包含您的员工的 ArrayList。

员工数据应存储在 TableModel 中。无需重新创建 TableModel,因为您只需从模型中删除行,表格将自行重新绘制。

此外,作为使用 DefaultTableModel 时的注意事项,您只需使用以下内容删除所有行:

model.setRowCount(0);
于 2013-03-23T05:00:55.947 回答
0

删除refreshTable方法中的所有行时,尝试更改逻辑

while(employeeTable.getRowCount() > 0) {
    tbm.removeRow(0);
}

这样可以确保您不会获得IndexOutOfBoundsException. 也可以解决重复行显示的其他问题。

于 2013-03-23T04:57:27.840 回答