TITLE:JTableHeaderのフォントを変更

Posted by terai at 2004-08-23

JTableHeaderのフォントを変更

TableCellRendererを使って、JTableのヘッダが使用するフォントを変更します。

  • &jnlp;
  • &jar;
  • &zip;

#screenshot

サンプルコード

JTableHeader h = table.getTableHeader();
Font font = new Font("Sans-serif", Font.PLAIN, 32);
TableCellRenderer hr = h.getDefaultRenderer();
TableColumn col = table.getColumnModel().getColumn(0);
col.setHeaderRenderer(new HeaderRenderer(hr, font));

class HeaderRenderer implements TableCellRenderer {
  private final TableCellRenderer tcr;
  private final Font font;
  public HeaderRenderer(TableCellRenderer tcr, Font font) {
    this.tcr  = tcr;
    this.font = font;
  }
  public Component getTableCellRendererComponent(JTable tbl, Object val,
                          boolean isS, boolean hasF, int row, int col) {
    JLabel l = (JLabel)tcr.getTableCellRendererComponent(
                                        tbl, val, isS, hasF, row, col);
    l.setFont(font);
    return l;
  }
}

解説

ヘッダを修飾する場合も、セルの場合と同様に、TableCellRendererを実装したセルレンダラーを使います。

サンプルのセルレンダラーは、TableCellRenderer#getTableCellRendererComponentメソッドの中で、委譲しているヘッダのデフォルトのレンダラーから描画に使用するコンポーネント(JLabel)を取得し、そのラベルのフォントだけJLabel#setFontメソッドで置き換えています。

同様の方法で、文字色、背景色、ボーダー、文字の中央揃え、右揃えなども変更することができます。

すべてのヘッダを同じフォントや文字色で変更する場合は、以下のようにUIManagerを使用する方法もあります。

UIManager.put("TableHeader.font", new FontUIResource(font));

  • 以下、Swing/HorizontalAlignmentHeaderRendererに移動予定。
    • ヘッダの字揃えを以下のように行った場合、フォントの指定は第二列のみ、字揃えは全体に作用する?
col = table.getColumnModel().getColumn(2);
TableCellRenderer hr = table.getTableHeader().getDefaultRenderer();
col.setHeaderRenderer(new HeaderRenderer(hr));
static class HeaderRenderer implements TableCellRenderer {
  private final TableCellRenderer renderer;
  private final Font font = new Font("Sans-serif", Font.BOLD, 14);
  public HeaderRenderer(TableCellRenderer renderer) {
    this.renderer  = renderer;
  }
  public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) {
    JLabel l = (JLabel)renderer.getTableCellRendererComponent(table, value,
              isSelected, hasFocus, row, column);
    l.setHorizontalAlignment(JLabel.CENTER);
    l.setFont(font);
    return l;
  }
}
  • 以下のようにすれば、先頭列だけ中央揃えにできるが、LookAndFeelを変更するとNullPointerExceptionが発生する。
final TableCellRenderer renderer = table.getTableHeader().getDefaultRenderer();
//table.getColumnModel().getColumn(0).setHeaderRenderer(new TableCellRenderer() {
table.getTableHeader().setDefaultRenderer(new TableCellRenderer() {
  public Component getTableCellRendererComponent(JTable table, Object value,
          boolean isSelected, boolean hasFocus, int row, int column) {
    JLabel l = (JLabel)renderer.getTableCellRendererComponent(
          table,value,isSelected,hasFocus,row,column);
    if(table.convertColumnIndexToModel(column)==0) {
      l.setHorizontalAlignment(SwingConstants.CENTER);
    }else{
      l.setHorizontalAlignment(SwingConstants.LEFT);
    }
    return l;
  }
});

以下のように変更する。

TableColumnModel m = table.getColumnModel();
m.getColumn(0).setHeaderRenderer(new MyHeaderRenderer(SwingConstants.CENTER));
m.getColumn(1).setHeaderRenderer(new MyHeaderRenderer(SwingConstants.LEFT));
m.getColumn(2).setHeaderRenderer(new MyHeaderRenderer(SwingConstants.LEFT));
class MyHeaderRenderer implements TableCellRenderer{
  private int horizontalAlignment = SwingConstants.LEFT;
  public HorizontalAlignmentHeaderRenderer(int horizontalAlignment) {
    this.horizontalAlignment = horizontalAlignment;
  }
  public Component getTableCellRendererComponent(JTable table,
      Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    TableCellRenderer r = table.getTableHeader().getDefaultRenderer();
    JLabel l = (JLabel)r.getTableCellRendererComponent(
      table,value,isSelected,hasFocus,row,column);
    l.setHorizontalAlignment(horizontalAlignment);
    return l;
  }
}

参考リンク

コメント