TITLE:JTableで文字列をクリックした場合だけセルを選択状態にする
Posted by terai at 2006-12-25

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

JTableの文字列以外の場所がクリックされた場合、そのセルが選択されないようにします。
  • category: swing folder: TableFileList title: JTableで文字列をクリックした場合だけセルを選択状態にする tags: [JTable, TableCellRenderer] author: aterai pubdate: 2006-12-25T16:51:36+09:00 description: JTableの文字列以外の場所がクリックされた場合、そのセルが選択されないようにします。 image: https://lh3.googleusercontent.com/_9Z4BYR88imo/TQTUdT6R-SI/AAAAAAAAAmE/AYebcaiE77Y/s800/TableFileList.png hreflang:
       href: https://java-swing-tips.blogspot.com/2010/01/make-explorer-like-jtable-file-list.html
       lang: en

概要

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

#screenshot

サンプルコード

#spanend
#spandel
private static final int ICON_SIZE = 16;
#spanend
#spandel
private static Rectangle getCellRect2(JTable table, Point pt, int row, int col) {
#spanend
  FontMetrics fm = table.getFontMetrics(table.getFont());
  Object o = table.getValueAt(row, col);
  int w = fm.stringWidth(o.toString()) + ICON_SIZE + 2 + 2;
  Rectangle rect = table.getCellRect(row, col, true);
  rect.setSize(w, rect.height);
  return rect;
#spanadd
* サンプルコード [#sourcecode]
#spanend
#spanadd
#code(link){{
#spanend
#spanadd
// @see SwingUtilities2.pointOutsidePrefSize(...)
#spanend
#spanadd
private static Rectangle getCellRect2(JTable table, int row, int col) {
#spanend
  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;
}
#spandel

#spanend
#spandel
class TestRenderer extends Box implements TableCellRenderer {
#spanend
  private final MyLabel textLabel;
  private final JLabel  iconLabel = new JLabel();
  public int getStringWidth(int row, int column) {
    FontMetrics fm = table.getFontMetrics(table.getFont());
    Object o = table.getValueAt(row, column);
    return fm.stringWidth(o.toString())
           + iconLabel.getPreferredSize().width
           + textLabel.getInsets().left
           + textLabel.getInsets().right;
  }
#spandel
//......
#spanend

解説

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

解説

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

参考リンク

参考リンク

コメント