• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JTableのセル文字揃え
#navi(../)
RIGHT:Posted by [[terai]] at 2008-08-25
*JTableのセル文字揃え [#y99ee441]
Posted by [[terai]] at 2008-08-25

#contents

**概要 [#gb2b7332]
JTableのセルに表示されている文字列の揃えを変更します。

-&jnlp;
-&jar;
-&zip;

#screenshot

**サンプルコード [#ocb54d34]
#code{{
TableColumn col = table.getColumnModel().getColumn(1);
col.setCellRenderer(new HorizontalAlignmentTableRenderer(
                          new DefaultTableCellRenderer()));
}}
#code{{
class HorizontalAlignmentTableRenderer implements TableCellRenderer {
  private final TableCellRenderer renderer;
  public HorizontalAlignmentTableRenderer(TableCellRenderer renderer) {
    this.renderer = renderer;
  }
  public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) {
    Component c = renderer.getTableCellRendererComponent(table, value,
              isSelected, hasFocus, row, column);
    if(c instanceof JLabel) initLabel((JLabel)c, row);
    return c;
  }
  private void initLabel(JLabel l, int row) {
    if(leftRadio.isSelected()) {
      l.setHorizontalAlignment(JLabel.LEFT);
    }else if(centerRadio.isSelected()) {
      l.setHorizontalAlignment(JLabel.CENTER);
    }else if(rightRadio.isSelected()) {
      l.setHorizontalAlignment(JLabel.RIGHT);
    }else if(customRadio.isSelected()) {
      l.setHorizontalAlignment(row%3==0?JLabel.LEFT:
                               row%3==1?JLabel.CENTER:
                                        JLabel.RIGHT);
    }
  }
}
}}

**解説 [#b5da87a2]
上記のサンプルでは、上部のラジオボタンで、第一列のセル文字列の揃えを変更することができます。
-left: 左揃え
-center: 中央揃え
-rihgt: 右揃え
-custom: 行ごとに左、中央、右揃えを変更

----
JTableは、Object、Number、Booleanクラスのデフォルトセルレンダラーを持っているため、モデル((DefaultTableModelはすべての列のクラスとして、Object.classを返す))が各列のクラスを正しく返すように、TableModel#getColumnClass(int)をオーバーライドしてやると、そのクラスのデフォルトセルレンダラーが使用され((列にセルレンダラーが割り当てられていない場合))、表示は数字右揃え、文字列左揃えになります。

-Object: JLabel.LEFT
-Number: JLabel.RIGHT
-Boolean: JCheckBox
-Boolean: JCheckBox, CENTER

#code{{
//JTableの手抜きサンプルなら、以下のようにオーバーライドするのが簡単?
String[] columnNames = {"String", "Integer", "Boolean"};
Object[][] data = {
  {"AAA", 1, true},
  {"BBB", 2, false},
};
DefaultTableModel model = new DefaultTableModel(data, columnNames) {
  @Override
  public Class<?> getColumnClass(int column) {
    return getValueAt(0, column).getClass();
  }
};
JTable table = new JTable(model);
}}

クラスのデフォルトセルレンダラーではなく、任意の列にセルレンダラーを割り当てて、例えば中揃えにしたい場合は、以下のように設定します。
クラスのデフォルトセルレンダラーではなく、任意の列にセルレンダラーを割り当てて、例えば中央揃えにしたい場合は、以下のように設定します。
// -- [[terai]] &new{2007-06-14 (木) 13:19:36};

#code{{
DefaultTableCellRenderer r = new DefaultTableCellRenderer();
r.setHorizontalAlignment(JLabel.CENTER);
table.getColumnModel().getColumn(2).setCellRenderer(r);
}}

----
-テスト中
--ヘッダの字揃えを以下のように行った場合、フォントの指定は第二列のみ、字揃えは全体に作用する?
--Microsoft Windows XP [Version 5.1.2600]
--Java(TM) SE Runtime Environment (build 1.6.0_07-b06)

#code{{
col = table.getColumnModel().getColumn(2);
TableCellRenderer hr = table.getTableHeader().getDefaultRenderer();
col.setHeaderRenderer(new HeaderRenderer(hr));
}}
#code{{
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;
  }
}
}}

//**参考リンク
**コメント [#x640db8a]
#comment