カスタムのセルレンダラーを作りセルの値によって背景色を変更する方法
前の記事「デフォルトセルレンダラーを使って中央揃えにする方法」では、 デフォルトセルレンダラーをいじって、中央揃えで表示する方法を示しました。
その結果が次のような画面でした。
この記事では、カスタムのセルレンダラーを実装して、データの値によって背景色を変更する方法を示します。
次のような画面を作ります。最初のカラムで X が赤、Y が青にしています。
カスタムで作るといっても、ベースはデフォルトセルレンダラーです。 そこから派生して明示的にセルレンダラークラスを作るということです。
JTable は次のように作りました。
package com.keicode.java.testapp;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.TableColumn;
@SuppressWarnings("serial")
public class TableTest15 extends JFrame {
public TableTest15() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(350, 150);
JTable table = new JTable();
MyTableModel2 tableModel = new MyTableModel2();
table.setModel(tableModel);
MyTableCellRenderer tableCellRenderer = new MyTableCellRenderer();
TableColumn col = table.getColumnModel().getColumn(0);
col.setCellRenderer(tableCellRenderer);
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
TableTest15 app = new TableTest15();
app.setVisible(true);
}
});
}
}
ここでテーブルモデルの MyTableModel2 は以前と同様ですが、念のため再度載せて置きます。
package com.keicode.java.testapp;
import javax.swing.table.AbstractTableModel;
@SuppressWarnings("serial")
class MyTableModel2 extends AbstractTableModel {
Object[][] data = {
{"X", "100", true},
{"X", "200", false},
{"X", "300", false},
{"Y", "400", false},
{"Y", "500", false},
{"Z", "600", false},
{"Z", "700", false}};
String[] columns = {"Column 0", "Column 1", "Column 2"};
@Override
public Class<?> getColumnClass(int columnIndex) {
return data[0][columnIndex].getClass();
}
@Override
public String getColumnName(int column) {
return columns[column];
}
@Override
public int getRowCount() {
return data.length;
}
@Override
public int getColumnCount() {
return columns.length;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return data[rowIndex][columnIndex];
}
}
さて、次が本題のテーブルセルレンダラーです。DefaultTableCellRenderer から派生して作成しています。
package com.keicode.java.testapp;
import java.awt.Color;
import java.awt.Component;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
@SuppressWarnings("serial")
public class MyTableCellRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(
JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
Component renderer = super.getTableCellRendererComponent(
table,
value,
isSelected,
hasFocus,
row,
column);
if(value == null) {
return renderer;
}
setHorizontalAlignment(JLabel.CENTER);
switch(value.toString().toUpperCase()) {
case "X":
setBackground(Color.RED);
break;
case "Y":
setBackground(Color.BLUE);
break;
default:
setBackground(Color.WHITE);
}
return renderer;
}
}
要はデフォルトセルレンダラーをデータの値によっていじっているに過ぎないので、 「デフォルトセルレンダラーを使って中央揃えにする方法」で行ったものと考え方は同じです。
しかし、実装としてはコード量が増えればソースを分ける方がわかりやすいし、間違いも少なく、再利用もしやすいので優れていると言えます。