11

を作成するための良い本やウェブサイトはありJTableますか? 1 つの列を編集可能にしたい。編集可能なフィールドに基づいてJCheckBoxテーブルを配置するだけでなく、(ここで作成した)継承されたコンポーネントを実際にテーブルの列の 1 つに配置したいと考えています。JCheckBoxboolean

私はJFC Swing Tutorial Second Editionの本を持っていますが、他の例を見て、テーブルをより適切に処理する方法を学ぶことができるかどうかを知りたいだけです。この本は、Javaの「トレイル」をオンラインで取り上げて本に掲載しただけのようです。

誰かがもっと役立つ何かを見つけたかどうかに興味があります。

4

6 に答える 6

31

isCellEditable列を編集可能にするには、 のメソッドをオーバーライドする必要がありますTableModelTableModel継承する場合、 を作成するのはかなり簡単です。AbstractTableModel最も単純な を除くすべての に対してお勧めしJTableます。

ただし、 を適応させることTableModelは、実行する必要があることの一部にすぎません。でカスタム コンポーネントを実際に取得するにはJTable、カスタム セル レンダラーを設定する必要があります。インタラクティブなカスタム コンポーネントを使用するには、カスタム セル エディターを設定する必要があります。場合によっては、デフォルト クラスを少し変更したバージョンを使用するだけで十分です。

編集者

カスタム コンポーネントが既にある場合は、委任を使用して簡単に実行できます。 を実装する新しいクラスを作成し、メソッドでコンポーネントの新しいインスタンスをTableCellEditor返します。このメソッドのパラメーターには、現在の値、セル座標、テーブルへのリンク、セルが選択されているかどうかが含まれます。getCellEditorComponent

には、ユーザーがセルのTableCellEditor内容への変更をコミットする (ユーザー入力を検証してモデルを調整できる) とき、または編集をキャンセルするときに呼び出されるメソッドもあります。プログラムで編集を中止する場合は、必ずエディタでメソッドを呼び出してstopEditing()ください。そうしないと、エディタ コンポーネントが画面に表示されたままになります。デバッグに 2 時間ほどかかったことがあります。

JTableエディター内では、エディターのみがイベントを受け取ることに注意してください。ボタンの表示は、レンダラーを使用して行うことができます。ただし、機能するボタンを取得するには、正しいEventListeners登録済みのエディターを実装する必要があります。レンダラーにリスナーを登録しても何も起こりません。

レンダラー

レンダラーを実装することは、質問で説明したことに対して厳密に必要というわけではありませんが、マイナーな変更のみの場合でも、通常はとにかくそれを行うことになります。エディターとは異なり、レンダラーは速度が重要です。レンダラーのgetTableCellRendererComponentは、テーブル内のセルごとに 1 回呼び出されます。レンダラーによって返されるコンポーネントは、セルを描画するためにのみ使用され、対話には使用されないため、次のセルに「再利用」できます。つまり、レンダラーでコンポーネントを調整する必要があります (たとえば、setText(...)またはを使用するsetFont(...)場合)。新しいコンポーネントをインスタンス化しないでください。これは、パフォーマンスを低下させる簡単な方法です。TextComponent

注意事項

JTableレンダラーとエディターを機能させるには、特定のレンダラー/エディターをいつ使用するかを伝える必要があることに注意してください。これを行うには、基本的に 2 つの方法があります。それぞれのメソッドを使用して、特定のタイプのデフォルトのセル レンダラー/エディターを設定できます。JTableこの方法を機能TableModelさせるには、メソッドで正確にこのタイプを返す必要がありますgetColumnClass(...)! デフォルトのテーブル モデルはこれを行わ、常に を返しますObject.class。多くの人を困惑させてきた一人だと確信しています。

エディター/レンダラーを設定するもう 1 つの方法は、列自体に明示的に設定することです。つまり、 のメソッドをTableColumn介してを取得します。これはかなり複雑ですが、1 つのクラスに対して 2 つの異なるレンダラー/エディターを持つ唯一の方法でもあります。たとえば、あなたのモデルはクラス String の 2 つの列を持ち、それらはまったく異なる方法でレンダリングされます。たとえば、1 つは を使用し、もう 1 つは を使用して、より精巧なエディターにアクセスします。getTableColumn(...)JTableJLabel/DefaultRendererJButton

JTableカスタム レンダラーとエディターを使用すると、非常に汎用性が高くなりますが、取り入れなければならないことも多く、間違っていることもたくさんあります。幸運を!

Swing チュートリアルでのテーブルの使用方法は、JTable をカスタマイズするすべての人にとって必読です。特に、Concepts: Editor and Renderersを読んで読み直してください。「クリック」するのに通常は時間がかかるためです。カスタム レンダラーとエディターの例も非常に価値があります。

于 2008-09-19T20:35:33.527 に答える
1

1列を編集可能な単純なものを使用しようとしていJTableて、列の場所がわかっている場合は、常にデフォルトのテーブルモデルを使用して、isCellEditable呼び出しをオーバーロードできます。

このようなもの :

myTable.setModel(new DefaultTableModel(){
@Override
public boolean isCellEditable(int row, int column) {
    if (column == x) {
        return true;
    } else
        return false;
}
});

チェックボックスには、レンダラークラスを作成します

MyCheckBoxRenderer extends JCheckBox implements TableCellRenderer
于 2008-09-22T19:36:40.897 に答える
1

独自の動作を作成するために拡張することを検討したいクラスは、DefaultTableModel です。これにより、独自の動作を定義できます。適切なチュートリアルは、sun のサイトにあります。

于 2008-09-17T16:41:49.870 に答える
1

このJava ロビーのチュートリアルは簡単に理解できます。参照しているJTableのオンラインSwing トレイルは、それが更新されたことを示しています。より良い (常に新しいほど良いというわけではない) 情報を得るために、全体をスキャンしましたか?

于 2008-09-17T16:55:17.233 に答える
0

いくつかの便利なクラスは次のとおりです。

Package javax.swing.table:

TableModel- のインターフェイスtablemodel AbstractTableModel- カスタム データ構造を使用して独自のテーブルを作成するために拡張する優れたクラス - をDefaultTableModel処理できるデフォルトのテーブル モデルarrays[]Vectors

セルの編集を無効にするには、isCellEditable(int row, int col)メソッドをオーバーライドする必要があります

于 2008-09-19T19:56:15.993 に答える
0

テーブル モデルでは、以下のように「isCellEditable」および「setValueAt」関数をオーバーライドする必要があります。
列 4 は、編集可能なセルの列です。
次に、セルをダブルクリックして何かを入力すると、
setValueAt() が呼び出され、値が tableModel の DO フィールド col4 に保存されます。

public ArrayList<XXXDO> tbmData = new ArrayList<XXXDO>(); //arraylist for data in table

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

@Override
public void setValueAt(Object value, int row, int col) {
    if ((row >= 0) && (row < this.tbmData.size()) && (col >= 0) && (col < this.colNm.length)) {
        if (col == 4) {
            tbmData.get(row).col4= (String) value;
        }
        fireTableCellUpdated(row, col);
    } else {
    }
}
于 2016-09-05T10:09:47.803 に答える