1

私はフレームにシンプルJFrameとAを持っています。JTableユーザーは、テーブルの行にデータを提供できます。要件の 1 つは、フレームを閉じた後に新しいデータを保存または破棄できることです。この動作を実現する最も簡単な方法は次のとおりだと思いました。

  1. フレームのメソッドをオーバーライドし、のデータ ベクトルsetVisible()を複製します。DefaultTableModel

  2. フレームに を追加WindowListenerし、イベントに反応しWindowClosingます。このようにして、ウィンドウ リスナーは、モデルを以前に保存されたモデルにリセットする必要があるかどうかを判断できます。

関連するコード スニペットは次のとおりです。

@Override
public void setVisible(boolean b) {
  //save the original models only if setVisible invoked with true (do not save the model when hiding the frame)
  if (b) {
    Vector cloned = (Vector) userTableModel.getDataVector().clone();
    Vector headerNames = new Vector();
    originalModel = new CustomTableModel(cloned, headerNames);
  }
  super.setVisible(b);
}

実は、おかしなことが起こっています。データ ベクトルを複製した後、テーブルをレンダリングできず、次の例外が発生します。

スレッド「AWT-EventQueue-0」での例外 java.lang.ArrayIndexOutOfBoundsException: 0 >= 0
    java.util.Vector.elementAt(Vector.java:470) で
    javax.swing.table.DefaultTableModel.getValueAt(DefaultTableModel.java:650) で
    asc.model.CustomTableModel.getValueAt (CustomTableModel.java:74) で
    javax.swing.JTable.getValueAt(JTable.java:2720) で

この表は、 とはまったく関係がありませんoriginalModel。理論的には、複製がテーブルのモデルに影響を与えるべきではないので、これは私にとって驚きです。originalModel の意図は、新しく作成されたテーブル モデルのコピーへの参照を保持することです。の作成をコメントアウトした後originalModel、すべてが正常に機能しました。

もう 1 つの興味深い点はStringheaderNamesベクターに空を追加すると、テーブル レンダラーがほぼ同じArrayIndexOutOfBounds例外をスローすることですが、次のようになります。

スレッド「AWT-EventQueue-0」での例外 java.lang.ArrayIndexOutOfBoundsException: 1 >= 1

その場合、最初の行の最初の列は完全にレンダリングされました。

MyCustomTableModelは から拡張されてDefaultTableModelおり、特別なメソッドは使用していません。コンストラクターは、単にデータ ベクトルとヘッダー ベクトルをスーパークラスに渡します。

誰かが問題を解決するのを手伝ってくれることを願っています。前もって感謝します。

4

3 に答える 3

1

の実装によりAbstractTableModel、データ構造を直接制御できます。このはを示しMap<String, String>ていますが、選択は任意です。

于 2012-04-08T01:52:57.287 に答える
1

Vector clonedプレーンを返そうとしたのですVectorが、JTableVector<Vector>はあなたのケースに基づいているので、間違いがあると思います

于 2012-04-07T23:57:47.857 に答える
1

headerNamesベクトルの長さは、取得した列の数と一致する必要があります。VectorはCustomTableModelクラス内のヘッダー名の配列に変換されるため、混乱を招きます。そのため、AIOOBEとして表示されます。

したがって、最初のパスでは、headerNamesベクトル/配列で最初の列(インデックス0の列)を探して失敗し、0>=0バージョンのエラーを送信します。列名文字列を追加すると(空の場合もあります)、最初の列全体が正常にレンダリングされ、次に2番目の列(インデックス1の列)が検索されます。headerNamesベクトルに2番目の要素がないため、失敗し、1>=1バージョンのエラーが発生します。

headerNamesベクトルに正しい数の値(データベクトルの列数と一致する)が含まれていることを確認してください。

注-clone()メソッドはデータのSHALLOWコピーを作成しているため、ユーザーがセル内のデータに加えた変更は、元のオブジェクトを変更します。この記事はそれを助けるかもしれません:http: //javatechniques.com/blog/faster-deep-copies-of-java-objects/

于 2012-04-08T00:04:07.687 に答える