TITLE:JTableで文字列をクリックした場合だけセルを選択状態にする

Posted by at 2006-12-25

JTableで文字列をクリックした場合だけセルを選択状態にする

`JTable`の文字列以外の場所がクリックされた場合、そのセルが選択されないようにします。

  • &jnlp;
  • &jar;
  • &zip;
TableFileList.png

サンプルコード

//SwingUtilities2.pointOutsidePrefSize(...)
private static Rectangle getCellRect2(JTable table, int row, int col) {
  TableCellRenderer tcr = table.getCellRenderer(row, col);
  Object value = table.getValueAt(row, col);
  Component cell = tcr.getTableCellRendererComponent(table, value, false, false, row, col);
  Dimension itemSize = cell.getPreferredSize();
  Rectangle cellBounds = table.getCellRect(row, col, false);
  cellBounds.width = itemSize.width;
  return cellBounds;
//   FontMetrics fm = table.getFontMetrics(table.getFont());
//   Object o = table.getValueAt(row, col);
//   int w = fm.stringWidth(o.toString()) + 16 + 2 + 2;
//   Rectangle rect = table.getCellRect(row, col, true);
//   rect.setSize(w, rect.height);
//   return rect;
}
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、`Name`カラムのセル中にあるアイコンと文字列の上でクリックされた場合のみ、そのセルが選択されるようになっています。

  • `JTable#columnAtPoint(Point)メソッドをオーバーライドし MouseAdapterを設定し、Name`カラムのセルの文字列上でクリックされたかどうかを判別
  • クリックされたポイントがそのセルの文字列上に無い場合、別のセル(幅`0`のダミーカラム)がクリックされたように偽装し、現在の選択状態を解除
  • `JTable.putClientProperty("Table.isFileList", Boolean.TRUE)で、0`列目の文字列以外がクリックされても選択されないように変更
    • `WindowsLookAndFeel`のみ?
  • 範囲選択の場合は、文字列の幅を自前で計算

参考リンク

コメント

  • `JTable#columnAtPoint(Point)メソッドをオーバーライドする方法では、CPU100%`になってしまうので、クリック、ドラッグした場合だけ、評価するように修正しました。 -- aterai
  • `JTable#getToolTipText(MouseEvent)メソッドをオーバーライドして、Name`カラムのセルの余白では、ツールチップも表示しないように変更しました。 -- aterai
  • `table.putClientProperty("Table.isFileList", Boolean.TRUE);を使えば、MouseListener`などもすべて必要なさそう…。 -- aterai
  • `Ctrl-AなどのJTable#selectAll()で、Comment`カラムが選択できるのを修正。 -- aterai