2013-03-23 95 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