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が発生することもあります。
スイングタイマーなどについてはあまり知らないので、同じ問題を抱えている人の解決策がわかりませんでした。
また、この質問で提案されているように、行のインデックスをモデルに変換するようにしました。
これを修正する方法について何かアイデアはありますか?
更新:これは、起こっていることの基本的なスクリーンショットです。
「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
};
}
}
修正(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);
}