Swing/StripeTable のバックアップの現在との差分(No.17)
TITLE:TableCellRendererでセルの背景色を変更
Posted by aterai at 2004-01-19
TableCellRendererでセルの背景色を変更
TableCellRendererを継承するレンダラーを作ってテーブルのセルを修飾します。- category: swing folder: StripeTable title: TableCellRendererでセルの背景色を変更 tags: [JTable, TableCellRenderer, UIManager] author: aterai pubdate: 2004-01-19 description: TableCellRendererを継承するレンダラーを作ってテーブルのセルを修飾します。 image:
概要
TableCellRenderer
を継承するレンダラーを作ってテーブルのセルを修飾します。
- &jnlp;
- &jar;
- &zip;
Screenshot
Advertisement
サンプルコード
#spanend
#spanadd
* サンプルコード [#sourcecode]
#spanend
#spanadd
#code(link){{
#spanend
class StripeTableRenderer extends DefaultTableCellRenderer {
private static final Color evenColor = new Color(240, 240, 255);
public Component getTableCellRendererComponent(JTable table, Object value,
@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) {
if (isSelected) {
setForeground(table.getSelectionForeground());
setBackground(table.getSelectionBackground());
}else{
} else {
setForeground(table.getForeground());
setBackground((row%2==0)?evenColor:table.getBackground());
setBackground((row % 2 == 0) ? evenColor : table.getBackground());
}
setHorizontalAlignment((value instanceof Number)?RIGHT:LEFT);
setHorizontalAlignment((value instanceof Number) ? RIGHT : LEFT);
return this;
}
}
解説
上記のサンプルでは、以下のようなセルレンダラーを作成し、Objectを継承するクラスのデフォルトレンダラーとして設定しています。- 奇数偶数で行の背景色を変更してテーブルをストライプ模様にする
- 第0列のカラムのセルを右寄せ
- ここでは、TableColumn#setCellRenderer(TableCellRenderer)*1を使わず、Object.classのDefaultRendererひとつにまとめているため、TableModel#getColumnClass(0)がInteger.classを返すようにしている
解説
上記のサンプルでは、以下のようなセルレンダラーを作成し、Object
を継承するクラスのデフォルトレンダラーとして設定しています。
- 奇数偶数で行の背景色を変更してテーブルをストライプ模様にする
- 第
0
列のカラムのセルを右寄せ- ここでは
TableColumn#setCellRenderer(TableCellRenderer)
を使用せずにObject.classのDefaultRenderer
ひとつにまとめているため、TableModel#getColumnClass(0)
がInteger.class
を返すよう設定 -
JTable#setDefaultRenderer(Class, TableCellRenderer)
でクラスに関連付けるより、各カラムに関連付けした方が優先順位が高い
- ここでは
table.setDefaultRenderer(Object.class, new StripeTableRenderer());
あるセルが描画されるとき、設定されたTableCellRendererのgetTableCellRendererComponentメソッドが呼び出されます。レンダラーは、引数などから得られる情報(選択されているか、何行何列目かなど)を使って、コンポーネントを修飾してからreturnします。
- -
あるセルが描画されるとき、設定された
TableCellRenderer
のgetTableCellRendererComponent
メソッドが呼び出されます。レンダラーは引数などから得られる情報(選択されているか何行何列目かなど)を使ってコンポーネントを修飾してからreturn
します。
TestRenderer
ではJLabel
を継承するDefaultTableCellRenderer
を継承しているので自分自身(this
)をsetForeground
、setHorizontalAlignment
などのメソッドで修飾し直し、さらに自分自身(this
)を戻り値としています。このようにコンポーネントを使い回しているためセルの数が膨大になってもオブジェクトを大量に生成しなくて済むようになっています。
また、返されたコンポーネントは、セルの描画のみに利用されて、コンポーネントとしては機能しません。
また返されたコンポーネントはセルの描画のためだけに利用されマウスイベントなどは無視されます。
セルレンダラーで色を変更する代わりに、以下のようにJTable#prepareRendererメソッドをオーバーライドする方法もあります。使用するセルレンダラーに関係なく、テーブル全体で前処理することができます。このため、Numberクラス用のDefaultTableCellRendererがそのまま使われるので、TableModel#getColumnClass(int)が、Number.classを返すようにしておけば、勝手に右寄せしてくれます。 セルレンダラーで色を変更する代わりに以下のように
JTable#prepareRenderer
メソッドをオーバーライドする方法もあります。この場合使用するセルレンダラーに関係なくテーブル全体での前処理が可能です。このためNumber
クラス用デフォルトレンダラーのJTable$NumberRenderer
がそのまま使用され、TableModel#getColumnClass(int)
がNumber.class
を返すようにしておけば自動的に右寄せになります。
JTable table = new JTable(model) {
private final Color evenColor = new Color(240, 240, 255);
public Component prepareRenderer(TableCellRenderer tcr, int row, int column) {
@Override public Component prepareRenderer(TableCellRenderer tcr, int row, int column) {
Component c = super.prepareRenderer(tcr, row, column);
if(isRowSelected(row)) {
if (isRowSelected(row)) {
c.setForeground(getSelectionForeground());
c.setBackground(getSelectionBackground());
}else{
} else {
c.setForeground(getForeground());
c.setBackground((row%2==0)?evenColor:getBackground());
c.setBackground((row % 2 == 0) ? evenColor : getBackground());
}
return c;
}
};
Java6u10 以降なら、以下のように設定する方法もあります。
- java.net Forums : JTable-Zebra with one line ... ...
JDK 1.6.0_10
以降では、以下のように設定する方法もあります。
UIManager.put("Table.alternateRowColor", Color.PINK);
- 注:デフォルトのBoolean用レンダラーの背景色が変わらないようです。
- 注: デフォルトの
Boolean
用レンダラーの背景色は変更されない
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
#spandel
class TableAlternateRowColorTest {
#spanend
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() { createAndShowGUI(); }
#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);
});
}
public static void createAndShowGUI() {
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);
}
}
参考リンク
- Sorting and Otherwise Manipulating Data - How to Use Tables (The Java™ Tutorials > Creating a GUI with JFC/Swing > Using Swing Components)
- SwingのJTableコンポーネントでセルを描く
参考リンク
- Sorting and Otherwise Manipulating Data - How to Use Tables (The Java™ Tutorials > Creating a GUI with JFC/Swing > Using Swing Components)
- SwingのJTableコンポーネントでセルを描く
コメント
- JTable#prepareRendererメソッドを使用する場合のサンプルを修正。 -- aterai
- メモ:JTable でセルのないところに行っぽい表示を出せますか? - KrdLabの不定期日記。これおもしろいです。 -- aterai
- ↑ありがとうございます.terai様のサイトは情報が充実していてすばらしいです.参考にさせていただきます. -- KrdLab?
コメント
-
JTable#prepareRenderer
メソッドを使用する場合のサンプルを修正。 -- aterai - メモ: JTable でセルのないところに行っぽい表示を出せますか? - KrdLabの不定期日記。これおもしろいです。 -- aterai
- ↑ありがとうございます.terai様のサイトは情報が充実していてすばらしいです.参考にさせていただきます. -- KrdLab