TITLE:TableCellRendererでセルの背景色を変更

TableCellRendererでセルの背景色を変更

編集者:Terai Atsuhiro~

作成日:2004-01-19
更新日:2022-02-01 (火) 22:40:22
  • category: swing folder: StripeTable title: TableCellRendererでセルの背景色を変更 tags: [JTable, TableCellRenderer, UIManager] author: aterai pubdate: 2004-01-19 description: TableCellRendererを継承するレンダラーを作ってテーブルのセルを修飾します。 image: https://lh5.googleusercontent.com/_9Z4BYR88imo/TQTT1bwXoBI/AAAAAAAAAlE/jmpoFwDpvqs/s800/StripeTable.png

概要

TableCellRendererを継承するレンダラーを作ってテーブルのセルを修飾します。

概要

TableCellRendererを継承するレンダラーを作ってテーブルのセルを修飾します。

サンプルコード

#spanend
#spanadd
class StripeTableRenderer extends DefaultTableCellRenderer {
#spanend
  private static final Color evenColor = new Color(240, 240, 255);
  @Override public Component getTableCellRendererComponent(JTable table, Object value,
                           boolean isSelected, boolean hasFocus,
                           int row, int column) {
    super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    if (isSelected) {
      setForeground(table.getSelectionForeground());
      setBackground(table.getSelectionBackground());
    } else {
      setForeground(table.getForeground());
      setBackground((row % 2 == 0) ? evenColor : table.getBackground());
    }
    setHorizontalAlignment((value instanceof Number) ? RIGHT : LEFT);
    return this;
  }
#spanadd
}
#spanend
#spanadd
View in GitHub: Java, Kotlin

#screenshot

解説

上記のサンプルでは、以下のようなセルレンダラーを作成し、Objectを継承するクラスのデフォルトレンダラーとして設定しています。

サンプルコード

  • 奇数偶数で行の背景色を変更してテーブルをストライプ模様にする
  • 0列のカラムのセルを右寄せ
    • ここではTableColumn#setCellRenderer(TableCellRenderer)を使用せずにObject.classのDefaultRendererひとつにまとめているため、TableModel#getColumnClass(0)Integer.classを返すよう設定
    • JTable#setDefaultRenderer(Class, TableCellRenderer)でクラスに関連付けるより、各カラムに関連付けした方が優先順位が高い
 public class TestRenderer extends DefaultTableCellRenderer {
   private static final Color ec = new Color(240, 240, 255);
   public TestRenderer() {
     super();
     setOpaque(true);
     setBorder(BorderFactory.createEmptyBorder(0,5,0,5));
   }
   public Component getTableCellRendererComponent(
         JTable table, Object value,
         boolean isSelected, boolean hasFocus,
         int row, int column) {
     super.getTableCellRendererComponent(table, value, 
         isSelected, hasFocus, row, column);
     if(isSelected) {
       setForeground(table.getSelectionForeground());
       setBackground(table.getSelectionBackground());
     }else{
       setForeground(table.getForeground());
       setBackground((row%2==0)?ec:table.getBackground());
     }
     setHorizontalAlignment((value instanceof Number)?RIGHT:LEFT);
     return this;
   }
 }
#spanadd
table.setDefaultRenderer(Object.class, new StripeTableRenderer());
#spanend
  • &jnlp;
  • &jar;
  • &zip;

解説

上記のサンプルでは、第0列のカラムのセルを右寄せにし、奇数偶数で行の背景色を変更してテーブルをストライプ模様にするレンダラーを作成し、これを以下のように、Objectを継承するクラスのデフォルトレンダラーとして設定しています。
  • - あるセルが描画されるとき、設定されたTableCellRenderergetTableCellRendererComponentメソッドが呼び出されます。レンダラーは引数などから得られる情報(選択されているか何行何列目かなど)を使ってコンポーネントを修飾してからreturnします。
サンプルのTestRendererではJLabelを継承するDefaultTableCellRendererを継承しているので自分自身(this)をsetForegroundsetHorizontalAlignmentなどのメソッドで修飾し直し、さらに自分自身(this)を戻り値としています。このようにコンポーネントを使い回しているためセルの数が膨大になってもオブジェクトを大量に生成しなくて済むようになっています。 また返されたコンポーネントはセルの描画のためだけに利用されマウスイベントなどは無視されます。
  • - セルレンダラーで色を変更する代わりに以下のようにJTable#prepareRendererメソッドをオーバーライドする方法もあります。この場合使用するセルレンダラーに関係なくテーブル全体での前処理が可能です。このためNumberクラス用デフォルトレンダラーのJTable$NumberRendererがそのまま使用され、TableModel#getColumnClass(int)Number.classを返すようにしておけば自動的に右寄せになります。
 table.setDefaultRenderer(Object.class, new TestRenderer());
#spanadd
JTable table = new JTable(model) {
#spanend
  private final Color evenColor = new Color(240, 240, 255);
  @Override public Component prepareRenderer(TableCellRenderer tcr, int row, int column) {
    Component c = super.prepareRenderer(tcr, row, column);
    if (isRowSelected(row)) {
      c.setForeground(getSelectionForeground());
      c.setBackground(getSelectionBackground());
    } else {
      c.setForeground(getForeground());
      c.setBackground((row % 2 == 0) ? evenColor : getBackground());
    }
    return c;
  }
#spanadd
};
#spanend
あるセルが描画されるとき、設定されたTableCellRendererのgetTableCellRendererComponentメソッドが呼び出されます。レンダラーは、引数などから得られる情報(選択されているか、何行何列目かなど)を使って、コンポーネントを修飾してからreturnします。
  • - JDK 1.6.0_10以降では、以下のように設定する方法もあります。
サンプルのTestRendererでは、JLabelを継承するDefaultTableCellRendererを継承しているので、自分自身(this)をsetForeground、setHorizontalAlignmentなどのメソッドで修飾し戻り値としています。このようにコンポーネントを使い回しているため、セルの数が膨大になっても、オブジェクトを大量に生成しなくて済むようになっています。 また、返されたコンポーネントは、セルの描画のみに利用されて、コンポーネントとしては機能しません。
#spanend
#spanadd
UIManager.put("Table.alternateRowColor", Color.PINK);
#spanend
#spanadd
セルレンダラーを作成する代わりに、以下のようにJTable#prepareRendererメソッドをオーバーライドする方法もあります。
  • 注: デフォルトのBoolean用レンダラーの背景色は変更されない
 JTable table = new JTable(sorter) {
   public Component prepareRenderer(TableCellRenderer renderer,
                                    int row, int column) {
     Component c = super.prepareRenderer(renderer, row, column);
     if(row%2==0 && !isRowSelected(row)) {
       c.setForeground(getForeground());
       c.setBackground(evenColor);
     }
     return c;
   }
 };
#spanadd
import java.awt.*;
#spanend
#spanadd
import javax.swing.*;
#spanend
#spanadd
import javax.swing.table.*;
#spanend
#spanadd
public class TableAlternateRowColorTest {
#spanend
  public static void main(String... args) {
    EventQueue.invokeLater(() -> {
      UIManager.put("Table.alternateRowColor", Color.ORANGE);
      String[] columnNames = {"String", "Integer", "Boolean"};
      Object[][] data = {
        {"A", 1, true}, {"B", 2, false}, {"C", 0, true}
      };
      TableModel model = new DefaultTableModel(data, columnNames) {
        @Override public Class<?> getColumnClass(int column) {
          return getValueAt(0, column).getClass();
        }
      };
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      f.getContentPane().add(new JScrollPane(new JTable(model)));
      f.setSize(320, 240);
      f.setLocationRelativeTo(null);
      f.setVisible(true);
    });
  }
#spanadd
}
#spanend

参考リンク

参考リンク

コメント

コメント