---
category: swing
folder: ClippedCellTooltips
title: JTableのセルがクリップされている場合のみJToolTipを表示
tags: [JTable, JTableHeader, TableCellRenderer, JToolTip]
author: aterai
pubdate: 2009-10-12T17:37:22+09:00
description: JTableのセルがクリップされている場合のみJToolTipを表示します。
image: https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTJNQAyg-I/AAAAAAAAAUA/F6oQbiUShl4/s800/ClippedCellTooltips.png
---
* 概要 [#summary]
`JTable`のセルがクリップされている場合のみ`JToolTip`を表示します。

#download(https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTJNQAyg-I/AAAAAAAAAUA/F6oQbiUShl4/s800/ClippedCellTooltips.png)

* サンプルコード [#sourcecode]
#code(link){{
class ToolTipHeaderRenderer implements TableCellRenderer {
  // private final Icon icon = UIManager.getIcon("Table.ascendingSortIcon");
  @Override public Component getTableCellRendererComponent(JTable table,
      Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    TableCellRenderer renderer = table.getTableHeader().getDefaultRenderer();
    JLabel l = (JLabel) renderer.getTableCellRendererComponent(
      table, value, isSelected, hasFocus, row, column);
    Insets i = l.getInsets();
    Rectangle rect = table.getCellRect(row, column, false);
    rect.width -= i.left + i.right;
    // RowSorter<? extends TableModel> sorter = table.getRowSorter();
    // if (sorter != null && !sorter.getSortKeys().isEmpty()
    //                    && sorter.getSortKeys().get(0).getColumn() == column) {
    //   rect.width -= icon.getIconWidth() + 2; // XXX
    // }
    Optional.ofNullable(l.getIcon())
            .ifPresent(icon -> rect.width -= icon.getIconWidth() + l.getIconTextGap());
    FontMetrics fm = l.getFontMetrics(l.getFont());
    String str = value.toString();
    int cellTextWidth = fm.stringWidth(str);
    l.setToolTipText(cellTextWidth > rect.width ? str : null);
    return l;
  }
}
}}

* 解説 [#explanation]
- ヘッダセル
-- `TableCellRenderer`内でセルの幅と文字列の長さを比較し`ToolTip`を設定
-- ソートアイコンと文字列の間の`gap`は`JLabel#getIconTextGap()`で取得してセル幅から除外する
--- `Windows 10`で使用される`WindowsLookAndFeel`のように文字列の上にソートアイコンが表示される場合(`TableCellRenderer#getIcon()`が`null`)は、このアイコンの幅を無視する
-- ソートアイコンと文字列の間隔は`JLabel#getIconTextGap()`で取得してセル幅から除外する
--- `Windows 10`で使用される`WindowsLookAndFeel`のように文字列の上にソートアイコンが表示される場合(`TableCellRenderer#getIcon()`が`null`)はこのアイコンの幅を無視する
- セル
-- `JTable#prepareRenderer`メソッドをオーバーライドし、セルの幅と文字列の長さを比較して`ToolTip`を設定

#code{{
JTable table = new JTable(model) {
  @Override public Component prepareRenderer(
      TableCellRenderer tcr, int row, int column) {
    Component c = super.prepareRenderer(tcr, row, column);
    if (c instanceof JComponent) {
      JComponent l = (JComponent) c;
      Object o = getValueAt(row, column);
      Insets i = l.getInsets();
      Rectangle rect = getCellRect(row, column, false);
      rect.width -= i.left + i.right;
      FontMetrics fm = l.getFontMetrics(l.getFont());
      String str = o.toString();
      int cellTextWidth = fm.stringWidth(str);
      l.setToolTipText(cellTextWidth > rect.width ? str : null);
    }
    return c;
  }
};
}}

* 参考リンク [#reference]
- [[JTableHeaderのTooltipsを列ごとに変更>Swing/HeaderTooltips]]
- [[JTableのTooltipsを行ごとに変更>Swing/RowTooltips]]

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