0

セルの内容がユーザーからの入力と一致する場合は常に、JTableの特定の行を強調表示したいと思います。次のコードは、これまでに機能するものです。

JTable table = new JTable(model) {
    public Component prepareRenderer(
            TableCellRenderer renderer, int row,
            int column) {
        Component c = super.prepareRenderer(renderer,
                row, column);
        if (!isRowSelected(row) ) {
            c.setBackground((hashMapcontainer
                    .containsKey(row)) ? Color.GREEN
                    : getBackground());
        }
        return c;
    }
    @Override
    public boolean isCellEditable(int row, int column) {
        return false;
    }
};

注:hashMapcontainerhashmap、ソースファイル内でグローバルにスコープが設定されているです。

これはある程度機能しますが、内にあるにこれJTableを追加しています。JTableは、プログラムの実行中に動的に作成されます。ただし、このメソッドでは、作成されたすべてのJTable内のすべての特定のセルが強調表示されます。JTabbedPaneJFrameprepareRenderer

すべてのJTableに同じ正確に強調表示されたセルを含めるのではなく、すべてのJTableにセルを保持して、特定の強調表示されたセルを保持するにはどうすればよいですか?

前もって感謝します!

4

3 に答える 3

4

レンダラーは「ゴム印」です。これは基本的に、以前の設定を次のセルに引き継ぐことを意味します。

あなたがする必要があるのは、「デフォルト」の動作を提供することです

if (!isRowSelected(row) ) {
    c.setBackground((hashMapcontainer
        .containsKey(row)) ? Color.GREEN
        : getBackground());
} else {

    // Define the default background color
    // Don't forget to take into the selection state

}

個人的にはprepareRenderer、この場合はおそらく公正な解決策だと思いますが、ベースライン レンダラーを提供する可能性を検討する必要があります。これを正しく行うには多くの作業が必要ですが、(テーブルの実装を変更した場合) 移植可能であるという利点があり、他の人が特定のセルのハイライト ルールを定義する機会を与えることができます。 、 私見では。

また、強調表示が組み込まれているJXTableを確認することをお勧めします

于 2012-08-08T20:42:55.087 に答える
3

一般に、基本的な Swing クラスのメソッドをオーバーライドすることはお勧めできません。推奨される方法は、Jcomponentを実装する を作成し、 を使用TableCellRendererしてテーブルに適用することsetDefaultRenderer()です。デフォルトでは、JTable は Object、Number、および Boolean 型に対してこれらのうちの 3 つを提供することに注意してください。通常、レンダラーは次のようになります。

public class MyRenderer extends JLable, implements TableCellRenderer{
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, 
         boolean isSelected, boolean hasFocus, int row, int column) {
    // Set up default state here 
    c.setBackground(Color.white);
    c.setForeground(Color.black);
    // ...
    if (!isRowSelected(row) ) {
        c.setBackground((hashMapcontainer
                .containsKey(row)) ? Color.GREEN
                : getBackground());
    }
    return c;
}

これにより、作成するすべての場所で JTable を拡張する必要がなくなり、再利用可能なコンポーネントが得られます。すべてのテーブルで同じセルが選択されているのは、インスタンスごとの状態ではなくグローバル状態にアクセスisRowSelectedしているためです。hashMapContainerすべてJComponentに と が getClientPropertyありputClientPropertyます。これらを使用すると、独自の状態オブジェクトを にアタッチできますJTable。次に、あなたは にisRowSelectedなりisRowSelected(table, row)、単に呼び出します:

MyObject myObj = (MyObject)table.getClientProperty("MySelectionProperty");
myObj.isRowSelected(row);

同様にhashMapContainer、テーブルから取得することもできます。

MyHashContainer myHash = (MyHash)table.getClientProperty("MyHashContainer");

アップデート:

これは、動的に生成されたテーブルの場合とほとんど同じです。テーブルの作成は次のようになります。

JTable t = new JTable();
// other typical table setup, t.setModel(...); etc
t.setDefaultRenderer(String.class, myRenderer);
t.putClientProperty("MySelectionProperty", new MyObject());
t.putClientProperty("MyHashContainer", new MyHashContainer());

レンダラーが状態を保持しない限り、テーブルごとにインスタンスを作成する必要がないことに注意してください。通常は 1 つ作成し、それをすべてのテーブルに使用します。

以下は、グローバル状態を使用せず、テーブルのプロパティを参照する上記のレンダラーの更新です。

public class MyRenderer extends JLable, implements TableCellRenderer{
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, 
        boolean isSelected, boolean hasFocus, int row, int column) {

        // Pull hashMapContainer from the per-table client properties
        MyHashContainer hashMapcontainer = (MyHashContainer)table.getClientProperty("MyHashContainer");

        // Set defaults as above            

        if (!isRowSelected(table, row) ) {
            // Same as above
        }
        return c;
    }
    // Private method to check for row selection
    private boolean isRowSelected(JTable t, int row) {
        int[] selectedRows = table.getSelectedRows();
        for (int i = 0; i < selectedRows.length; i++) {
            if (selectedRows[i] == row) {
                return true;
            }
         }
         return false;
    }
}
于 2012-08-09T11:20:28.093 に答える