0

jtableに問題があります。

いくつかのスレッドがあり、それぞれがjTableに行を追加する必要がありますが、テーブルは空のままです。私はNetBeansを使用していますが、グラフィックはロジックから完全に分離されています。誰か助けてもらえますか?


これは私が行を追加するために使用するコードです

MainGui.java

public void addToTable(String from, String to, int request, int response, String timeElapsed) {
    Object [][] temp = new Object [data.length + 1][5];

    for (int i = 0; i < data.length; i++) {
        for (int j = 0; j < 5; j++) {
            temp[i][j] = data[i][j];
        }
    }

    temp[data.length][0] = from;
    temp[data.length][1] = to;
    temp[data.length][2] = request;
    temp[data.length][3] = response;
    temp[data.length][4] = timeElapsed;

    data = temp;
    table.setModel(new DefaultTableModel(data, columnName));
}

MyThread.java

public void run() {
    try {
        MainGui mg = new MainGui();
        mg.addtotable("null", "null", 0, 0, "null");
    } catch (Exception e) {
    }
4

6 に答える 6

8

Swingの最初のルール-イベントディスパッチスレッド以外のスレッドからUIを変更しないでください

まず、更新呼び出しが同期されていることを確認します。更新がSwingUtilities#invokeLaterコードパスにとって重要であるかどうかを確認します。SwingUtilities#invokeAndWait

テーブルモデルに行を追加するときは、モデルが変更されたことをビューに通知するために必要な更新イベントを発生させる必要があります。

を使用している場合DefaultTableModel、これはあなたのために行われます。またはを使用している場合、AbstractTableModelまたはあなたが所有しているTableModel場合は、これを自分で行う必要があります。

最も簡単な方法は、addメソッドから拡張し、addメソッド内からAbstractTableModel呼び出す実装を作成することです。これにより、モデルに行が追加され、それに応じてテーブルが更新されることがわかります。AbstractTableModel#fireTableRowsInserted(int, int)JTable

だまされないでください。テーブル全体を再描画する必要がないため、テーブルモデルに行を追加する場合にfireTableRowsInserted使用するよりも、一般的に使用する方が高速です。fireTableDataChangedテーブルを大幅に変更した場合(多くの行を追加/削除/更新した場合)fireTableDataChanged、一連の個別の挿入/削除/更新呼び出しよりも高速になります。

詳細については、Swingでテーブルと同時実行性を使用する方法を参照してください。

更新しました

見た目通り、はっきりしなかったかもしれません。モデルはイベントを発生させる責任があります。つまり、addメソッド内で、を呼び出す必要がありますfireTableRowsInserted。これらのメソッドを外部ソースから呼び出すことは控えてください。

于 2012-11-15T22:40:46.543 に答える
1

Swingはスレッドセーフではありません。AWTイベントディスパッチスレッド以外のスレッドからSwingコンポーネントを変更する必要がある場合は、

SwingUtilities.invokeLater(new Runnable(){public void run() {
 // your code
}});
于 2012-11-15T22:42:31.577 に答える
1
public class TM extends AbstractTableModel {
final List<Integer>ids;

public TM() {
    ids = new ArrayList();
}

@Override
public int getRowCount() {
    return ids.size();
}

@Override
public int getColumnCount() {
    return 1;
}

@Override
public String getColumnName(int column) {
    if(column == 0) {
        return "ID";
    } else {
        return "UNDEF";
    }
}

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
    if(columnIndex == 0) {
        return ids.get(rowIndex);
    } else {
        return "NaN";
    }
}

public void addId(final int id) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            insertNewRow(id);
        }
    });
}

private void insertNewRow(int id) {
    ids.add(id);
    int rowIndex = ids.size();
    fireTableRowsInserted(rowIndex, rowIndex);
}

}

//Somewhere in your code
TM myModel = new TM();
myTable = new JTable(myModel);


//Somewhere from thread:
myModel.addId(123);

//Somewhere from another thread:
myModel.addInd(455);
于 2012-11-16T15:26:25.627 に答える
0

行を追加する方法を明確にしてください。うまくいけば、モデルを使用しますよね?新しい行が追加されたら、モデルのメソッド fireTableDataChanged/ を呼び出す必要があります/最適なオプションではありません/ または fireTableRowsInserted/より良い/ 問題を回避するために SwingUtilities.invokeLater を使用してそれを行うことを忘れないでください Swing

于 2012-11-15T22:44:32.743 に答える
-1

Swingはスレッドセーフではないことをご存知だと思います(いくつかの例外を除いて)。あなたはあなたのコードでそれを世話する必要があります。

于 2012-11-15T22:41:10.290 に答える