TITLE:JTableのセル文字揃え

JTableのセル文字揃え

Posted by terai at 2008-08-25
  • category: swing folder: CellTextAlignment title: JTableのセル文字揃え tags: [JTable, TableCellRenderer, Alignment] author: aterai pubdate: 2008-08-25T14:45:47+09:00 description: JTableのセルに表示されている文字列の揃えを変更します。 image: https://lh6.googleusercontent.com/_9Z4BYR88imo/TQTIs6qWcBI/AAAAAAAAATM/AnH_ZWdWA5o/s800/CellTextAlignment.png

概要

JTableのセルに表示されている文字列の揃えを変更します。

概要

JTableのセルに表示されている文字列の揃えを変更します。
  • &jnlp;
  • &jar;
  • &zip;

#screenshot

サンプルコード

#spanend
#spanadd
* サンプルコード [#sourcecode]
#spanend
#spanadd
#code(link){{
#spanend
TableColumn col = table.getColumnModel().getColumn(1);
#spandel
col.setCellRenderer(new HorizontalAlignmentTableRenderer(
#spanend
                          new DefaultTableCellRenderer()));
#spandel
#spanend
#spandel
class HorizontalAlignmentTableRenderer implements TableCellRenderer {
#spanend
  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);
#spanadd
col.setCellRenderer(new HorizontalAlignmentTableRenderer());
#spanend
#spanadd
// ...
#spanend
#spanadd
class HorizontalAlignmentTableRenderer extends DefaultTableCellRenderer {
#spanend
  @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);
    if (c instanceof JLabel) {
      initLabel((JLabel) c, row);
    }
    return c;
  }
#spanadd

#spanend
  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);
    if (leftRadio.isSelected()) {
      l.setHorizontalAlignment(SwingConstants.LEFT);
    } else if (centerRadio.isSelected()) {
      l.setHorizontalAlignment(SwingConstants.CENTER);
    } else if (rightRadio.isSelected()) {
      l.setHorizontalAlignment(SwingConstants.RIGHT);
    } else if (customRadio.isSelected()) {
      l.setHorizontalAlignment(row % 3 == 0 ? SwingConstants.LEFT:
                               row % 3 == 1 ? SwingConstants.CENTER:
                                              SwingConstants.RIGHT);
    }
  }
}

解説

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

解説

上記のサンプルでは、JTableの第1列目のセルに表示されている文字列の揃えを変更するテストを行っています。
  • left: 左揃え
  • center: 中央揃え
  • right: 右揃え
  • custom: 行ごとに左、中央、右揃えを変更

JTableは、Object、Number、Booleanクラスのデフォルトセルレンダラーを持っているため、モデル*1が各列のクラスを正しく返すように、TableModel#getColumnClass(int)をオーバーライドしてやると、そのクラスのデフォルトセルレンダラーが使用され*2、表示は数字右揃え、文字列左揃え*3になります。
  • JTableは、ObjectNumberBooleanクラスのデフォルトセルレンダラーを持っているため、モデルが各列のクラスを正しく返すようにTableModel#getColumnClass(int)をオーバーライドすることでそのクラスのデフォルトセルレンダラーが使用される
    • Object: SwingConstants.LEFT(文字列などは左揃え)
    • Number: SwingConstants.RIGHT(数字は右揃え)
    • Boolean: JCheckBox, CENTER(チェックボックスは中央揃え)
  • DefaultTableModel#TableModel#getColumnClass(int)のデフォルトは、すべての列のクラスとしてObject.classを返す
  • 各クラスのデフォルトセルレンダラーが使用されるのは、列にセルレンダラーが割り当てられていない場合に限られる
    #spandel
    //ちょっとしたサンプルの場合は、以下のようにオーバーライドすると便利かも?
    #spanend
    #spanadd
    // JTableの手抜きサンプルなら、以下のようにオーバーライドするのが簡単?(モデルが空になる場合、例外が発生する可能性がある)
    #spanend
    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) {
      @Override public Class<?> getColumnClass(int column) {
        return getValueAt(0, column).getClass();
      }
    };
    JTable table = new JTable(model);
    
クラスのデフォルトセルレンダラーではなく、任意の列にセルレンダラーを割り当てて、例えば中揃えにしたい場合は、以下のように設定します。
  • クラスのデフォルトセルレンダラーではなく、任意の列にセルレンダラーを割り当てて文字揃えを変更する方法もある
    DefaultTableCellRenderer r = new DefaultTableCellRenderer();
    #spandel
    r.setHorizontalAlignment(JLabel.CENTER);
    #spanend
    #spanadd
    r.setHorizontalAlignment(SwingConstants.CENTER);
    #spanend
    table.getColumnModel().getColumn(2).setCellRenderer(r);
    
  • -
  • テスト中
    • ヘッダの字揃えを以下のように行った場合、フォントの指定は第二列のみ、字揃えは全体に作用する?
    • Microsoft Windows XP [Version 5.1.2600]
    • Java(TM) SE Runtime Environment (build 1.6.0_07-b06)

参考リンク

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

コメント

コメント