• 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

概要

JTableのセルがクリップされている場合のみJToolTipを表示します。

サンプルコード

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;
  }
}
View in GitHub: Java, Kotlin

解説

  • ヘッダセル
    • TableCellRendererで、セルの幅と文字列の長さを比較して、ToolTipを設定
    • ソートアイコンと文字列の間のgapJLabel#getIconTextGap()で取得してセル幅から除外する
      • Windows 10で使用されるWindowsLookAndFeelのように文字列の上にソートアイコンが表示される場合(TableCellRenderer#getIcon()null)は、このアイコンの幅を無視する
  • セル
    • JTable#prepareRendererメソッドをオーバーライドし、セルの幅と文字列の長さを比較して、ToolTipを設定
      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;
        }
      };
      

参考リンク

コメント