0

私はいくつかのかなり複雑なデータを持っており、保持しようとしているデータ内に一対多の関係があるため、ハッシュテーブルを含む他のクラスを指すハッシュテーブルに現在存在しています。

世界の反対側には、データ モデルとの接続がないことを除いて、非常にうまく機能するテーブルがあります。独自のテーブルモデルがあります。私はそれを非常に簡単な方法で作成します-

Object[][] tableData = new Object[4][ tableHeaders.length ];
modelTablet  = new TabletTableModel(tableData, tableHeaders );

私のタブレットのデータ モデルは非常に単純です。

class TabletTableModel extends DefaultTableModel {

   public TabletTableModel(Object rowData[][], Object columnNames[]) {
      super(rowData, columnNames);
   }

   @Override
   public Class getColumnClass(int col) {
        if (col == 0) {
           return String.class;
        } else {
           return Double.class;
        }
   }

   @Override
   public boolean isCellEditable(int row, int col)
   {
      if (col == 0 || col == activeColumn)
         return true;
      else
         return false;
   }
}

行の追加や削除なども行う必要がありますが、この単純なデータ モデルを使用すると、ほとんどの作業が自動的に行われます。

class AddRowActionListener implements ActionListener {
    public void actionPerformed(ActionEvent event) {
    DefaultTableModel model = (DefaultTableModel)tableTablet.getModel();
    model.addRow(new Object[3]);
    System.out.println(Arrays.deepToString(tableData));
    }
}

また、マウス リスナとセル レンダラーも実装して、列のヘッダーをクリックするとアクティブになり、隣接する列のセルが別の色で再描画されて、編集できなくなったことを示します。

ここまでは順調ですが、私のインターフェイスでは、最初のテーブルの結果をまとめた 2 番目のテーブルがあります。3 行だけで、ヘッダーはありません。私がそれを作ったとき、私は必要以上の仕事をしたかもしれないと思います。

modelSummary = new SummaryTableModel(1, tableHeaders.length);
tableSummary = new JTable(modelSummary);

class SummaryTableModel extends DefaultTableModel {

   public SummaryTableModel(int rows, int columns) {
      super(rows, columns);
   }

   @Override
   public Class getColumnClass(int col) {
        if (col == 0) {
           return String.class;
        } else {
           return Double.class;
        }

   @Override
   public boolean isCellEditable(int row, int col)
   {
      if (col == 1 && activeColumn == 2)
         return true;
      else
         return false;
   }
}

これにより、素敵なテーブルのセットが得られます。想定どおりに色が変更され、データが有効な値に制限され、適切にフォーマットされます (一覧にないレンダラーを使用)。

しかし、これが起こるはずです-ユーザーがテーブル1の列1に値を入力すると、列1のすべての値を合計し、テーブル2の列1の値を出してから、すべての値を再計算する必要がありますこの新しい値に基づく表 1 の列 2。

逆に、列 2 がアクティブな列で、ユーザーがテーブル 1 の列 2 の値を変更した場合、テーブル 2 の列 1 の値を取得し、それを使用してテーブル 1 の列 1 のすべての値を再計算する必要があります。また、列 2 の値を合計して、表 2 の列 2 に配置します。列 2 の数値の合計が 100 を超えるような新しい値をユーザーが入力できないことに注意してください。

表 2 を編集することもできますが、その場合、表 1 のすべての値を計算する必要があります。

だから...私には、オブザーバブルが必要であり、オブザーバーとオブザーバブルのコントローラーの両方としてテーブルを登録する必要があるように思えます。したがって、オブザーバブルを作成できますが、まだ 2 つのテーブル データ モデルもあります。私はたくさん読んできましたが、私が見つけたすべての例は、テキストフィールドやテーブルモデルなどの単純なもので使用されているオブザーバブルで示されていますが、Observable クラスは使用されていません。もう 1 つの問題は、既定のモデルが既定で喜んで行ってくれるクールなこと (行の追加や型のチェックなど) のほとんどを行う方法がわからないことです。

プロジェクトにまったく新しい次元の複雑さを追加する前に、誰かが私にいくつかの指針を与えることができますか? 行や列の概念をほとんど持たないデータ モデルをテーブル データ モデルと混在させるのは簡単で、デフォルトのテーブル モデル操作をすべて書き直す必要はありませんか? 現時点では、プロセス全体が信じられないほど複雑に思えます。これがどのように機能するかについて、明確な説明がどうしても必要です。

4

1 に答える 1

1

テーブル モデルは既に監視可能です。テーブル モデルに TableModelListener を追加すると、テーブル モデルに変更が発生するたびに呼び出すことができます。したがって、2 番目のモデルは最初のモデルのリスナーになる可能性があり、その逆も同様です。

すべてのドメイン オブジェクトを配列に変換する必要があるため、通常は DefaultTableModel を使用しません。私は通常、ドメイン オブジェクトのリストをラップする AbstractTableModel サブクラスを作成します。セルの値を取得するには、通常、リスト内の特定の行 (インデックス) でオブジェクト モデルを取得し、列に応じてオブジェクトの適切なゲッターを呼び出します。

値を設定するには、オブジェクトで適切なセッターを呼び出し、イベントを発生させます。

テーブル モデルのチュートリアルについては、http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#dataを参照してください。

于 2011-12-14T10:27:29.367 に答える