JTableHeaderのヘッダカラムセルの背景色を変更
Total: 105, Today: 3, Yesterday: 4
Posted by aterai at
Last-modified:
Summary
JTableHeaderの各カラムにHeaderRendererを設定し、その曜日に応じた文字列と背景色でヘッダセルを描画します。
Screenshot

Advertisement
Source Code Examples
class MonthTable extends JTable {
@Override public void updateUI() {
super.updateUI();
JTableHeader header = getTableHeader();
header.setResizingAllowed(false);
header.setReorderingAllowed(false);
updateWeekHeaderRenderer();
}
@Override protected JTableHeader createDefaultTableHeader() {
return new JTableHeader(columnModel) {
@Override public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
d.height = 24;
return d;
}
};
}
@Override public void setModel(TableModel dataModel) {
super.setModel(dataModel);
EventQueue.invokeLater(this::updateWeekHeaderRenderer);
}
private void updateWeekHeaderRenderer() {
TableColumnModel cm = getColumnModel();
TableCellRenderer r = new WeekHeaderRenderer();
for (int i = 0; i < cm.getColumnCount(); i++) {
cm.getColumn(i).setHeaderRenderer(r);
}
getTableHeader().repaint();
}
// ...
}
class WeekHeaderRenderer extends DefaultTableCellRenderer {
public static final Color SUNDAY_BGC = new Color(0xB0_12_1A);
public static final Color SATURDAY_BGC = new Color(0x1A_12_B0);
private final WeekFields weekFields = WeekFields.of(Locale.getDefault());
@Override public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
Component c = super.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, column);
DayOfWeek week = weekFields.getFirstDayOfWeek().plus(column);
if (week.equals(DayOfWeek.SUNDAY)) {
c.setForeground(table.getSelectionForeground());
c.setBackground(SUNDAY_BGC);
} else if (week.equals(DayOfWeek.SATURDAY)) {
c.setForeground(table.getSelectionForeground());
c.setBackground(SATURDAY_BGC);
} else {
c.setForeground(table.getForeground());
c.setBackground(table.getTableHeader().getBackground());
}
if (c instanceof JLabel) {
JLabel l = (JLabel) c;
l.setHorizontalAlignment(CENTER);
Color gridColor = UIManager.getColor("Table.gridColor");
Border border = BorderFactory.createMatteBorder(0, 0, 1, 1, gridColor);
Border b = BorderFactory.createCompoundBorder(border, l.getBorder());
l.setBorder(b);
}
return c;
}
}
View in GitHub: Java, KotlinDescription
DefaultTableCellRendererを継承する曜日表示用のセルレンダラーを作成DefaultTableCellRenderer#getTableCellRendererComponent(...)をオーバーライドして、現在描画する列が土曜、日曜、それ以外かをWeekFields.of(Locale.getDefault()).getFirstDayOfWeek().plus(column)で調査して背景色を設定- カレンダーの曜日表示用の
JTableHeaderからTableColumnを取得し、すべてに上記のセルレンダラーを設定- このサンプルの
JTableではautoCreateColumnsFromModelがtrueで、表示する月やLookAndFeelの変更でモデル変更されるとそれに合わせて列モデルも新規作成するため、JTable#setModel(...)をオーバーライドしてその内部で上記のセルレンダラーを再設定している - 土日平日用に
3種類のTableCellRendererを作成して対応するTableColumnに設定する方法もある
- このサンプルの
JViewportの高さを基準にJTableHeaderの高さを調整していたので、JTableの行の高さ調整と競合してループする場合があった? →JTableHeaderの高さを固定して表示するよう修正