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が発生することもあります。

スイングタイマーなどについてはあまり知らないので、同じ問題を抱えている人の解決策がわかりませんでした。

また、この質問で提案されているように、行のインデックスをモデルに変換するようにしました。

これを修正する方法について何かアイデアはありますか?

更新:これは、起こっていることの基本的なスクリーンショットです。 ここに画像の説明を入力してください 「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);
} 
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 に答える