2013-03-23 90 views
2

我有一个带JTable的Swing桌面应用程序。将行添加到JTable时没有问题。我也可以排序(使用JTable.autoCreateRowSorter),然后顺利删除该行(使用convertRowIndexToModel)。使用RowFilter删除JTable中的一行

当我在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.

就如何解决这一问题?

更新:这是正在发生的事情的基本截图。 enter image description here 搜索“a”和“a”和“AA”现身: enter image description here

当我选择“是”,然后单击删除选定这就是结果: enter image description here

现在,如果我尝试继续删除“aa”,然后我最终得到一个IndexOutOfBoundsException。

UPDATE 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); 
} 

回答

3

不知道我理解你的设计。你有一个DefaultTableModel,你也有一个包含你的员工的ArrayList。

员工数据应存储在TableModel中。应该不需要重新创建TableModel,因为您应该从模型中删除该行,并且该表将重新绘制它自己。

此外,作为一个音符使用的DefaultTableModel,当你只需要使用下面的删除所有行:

model.setRowCount(0); 
+0

你说得对。这里不需要是ArrayList。但是,这是我的任务的一部分,我们必须使用Object ArrayList(创建一个对象,从中获取字段)。 尽管使用'tbm.removeRow(employee)'完美无瑕! (不重新创建/更新表格) – jessechk 2013-03-23 05:09:20

0

虽然删除在refreshTable所有行方法,尝试通过更改逻辑

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

这确保你不会得到IndexOutOfBoundsException。也可以解决重复行显示的其他问题。

+0

我改变了你建议的代码(很多比我更清洁)。但我仍然遇到同样的问题。 – jessechk 2013-03-23 05:02:53

+0

你可以发布两个类吗? – 2013-03-23 05:07:55

+0

我发布了员工分类 – jessechk 2013-03-23 05:11:29