TITLE:TableColumnの幅を比率で設定
#navi(../)
#tags(JTable, TableHeader, TableColumn, JScrollPane)
RIGHT:Posted by &author(aterai); at 2005-11-28
*TableColumnの幅を比率で設定 [#s3d330d1]
``TableColumn``の幅を比率で設定します。

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

//#screenshot
#ref(http://lh6.ggpht.com/_9Z4BYR88imo/TSs6oj80RcI/AAAAAAAAAxs/hm2gp4ELiDI/s800/HeaderRatio.png)

**サンプルコード [#dc125241]
#code(link){{
private void setTableHeaderColumnRaito() {
  int[] list = getWidthRaitoArray();
  //System.out.println("a: "+table.getColumnModel().getTotalColumnWidth());
  //System.out.println("b: "+table.getSize().width);
  int total = table.getSize().width; //table.getColumnModel().getTotalColumnWidth();
  int raito = total/getRaitoTotal(list);
  for(int i=0;i<table.getColumnModel().getColumnCount()-1;i++) {
    TableColumn col = table.getColumnModel().getColumn(i);
    int colwidth = list[i]*raito;
    col.setPreferredWidth(colwidth); //col.setMaxWidth(colwidth);
    total -= colwidth;
  }
  table.getColumnModel().getColumn(
    table.getColumnModel().getColumnCount()-1).setPreferredWidth(total);
  //table.getColumnModel().getColumnCount()-1).setMaxWidth(total);
  table.revalidate();
}

private void setRaito() {
  int[] list = getWidthRaitoArray();
  int total = getTotalColumnWidth(table);
  int raito = total/getRaitoTotal(table, list);
  for(int i=0;i<table.getColumnModel().getColumnCount()-1;i++) {
    TableColumn col = table.getColumnModel().getColumn(i);
    int colwidth = list[i]*raito;
    col.setMaxWidth(colwidth);
    total = total - colwidth;
  }
  //最後のカラムで誤差を吸収
  table.getColumnModel().getColumn(
    table.getColumnModel().getColumnCount()-1).setMaxWidth(total);
  table.revalidate();
}
}}

**解説 [#r3b250ae]
上記のサンプルでは、``JTextField``にコロン区切りで入力した比率に従って、ヘッダカラムの幅を調整するようになっています。

- ``ComponentListener#componentResized(...)``がチェックされている場合
-- ``JScrollPane``に追加した``ComponentListener``で、リサイズされる毎に全ての列幅を設定し直すので、フレームのサイズを変更してもカラムの比率は保持される
- ``ComponentListener#componentResized(...)``がチェックされていない場合
-- 列幅調整が``AUTO_RESIZE_SUBSEQUENT_COLUMNS``(デフォルト)なので、フレームをリサイズすると、その幅の変更([http://docs.oracle.com/javase/jp/6/api/javax/swing/JTable.html#doLayout() デルタ])が、リサイズ可能なすべての列に分散して加算減算される
--- このため、入力されている比率とは異なる列幅になる

----
``TableColumn#setMaxWidth``メソッドでカラムの幅を指定する場合は、マウスのドラッグによるサイズの変更はできません。

//起動時だけ比率を設定したい場合は、以下のようにTableColumn#setPreferredWidthメソッドを使用することで、マウスのドラッグによるサイズが可能になります。またComponentListenerを追加して初期化しなくても、フレームサイズ変更時には現在のカラム幅の比率などから適当に((詳しくはJTable#doLayout()のデルタの分散を参照してください))リサイズしてくれます((逆にTableColumn#setPreferredWidthメソッドを使用している場合にComponentListenerを追加して初期化してしまうと、比率が微妙に食い違って奇妙な動きになってしまう))。
//#code{{
//int[] list = getWidthRaitoArray();
//int total = table.getColumnModel().getTotalColumnWidth();;
//int raito = total/getRaitoTotal(table, list);
//for(int i=0;i<table.getColumnModel().getColumnCount()-1;i++) {
//  TableColumn col = table.getColumnModel().getColumn(i);
//  int colwidth = list[i]*raito;
//  // - table.getColumnModel().getColumnMargin();
//  col.setPreferredWidth(colwidth);
//  total = total - colwidth;
//}
//table.getColumnModel().getColumn(
//  table.getColumnModel().getColumnCount()-1).setPreferredWidth(total);
//table.revalidate();
//}}

**参考リンク [#h308024b]
-[http://docs.oracle.com/javase/jp/6/api/javax/swing/JTable.html#doLayout() デルタの分散 - JTable#doLayout()]

**コメント [#f4b5dfe7]
#comment