---
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 [#summary]
`JTable`のセルがクリップされている場合のみ`JToolTip`を表示します。
#download(https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTJNQAyg-I/AAAAAAAAAUA/F6oQbiUShl4/s800/ClippedCellTooltips.png)
* Source Code Examples [#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) {
JTableHeader header = table.getTableHeader();
TableCellRenderer r = header.getDefaultRenderer();
Component c = r.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, column);
if (c instanceof JLabel) {
JLabel l = (JLabel) c;
Insets i = l.getInsets();
Rectangle rect = header.getHeaderRect(column);
rect.width -= i.left + i.right;
boolean isClipped = isClipped(l, rect);
// isClipped = fontMetrics.stringWidth(l.getText()) > rect.width;
l.setToolTipText(isClipped ? l.getText() : header.getToolTipText());
}
return c;
}
private static boolean isClipped(JLabel label, Rectangle viewR) {
Rectangle iconR = new Rectangle();
Rectangle textR = new Rectangle();
String str = SwingUtilities.layoutCompoundLabel(
label,
label.getFontMetrics(label.getFont()),
label.getText(),
label.getIcon(),
label.getVerticalAlignment(),
label.getHorizontalAlignment(),
label.getVerticalTextPosition(),
label.getHorizontalTextPosition(),
viewR,
iconR,
textR,
label.getIconTextGap());
return !Objects.equals(label.getText(), str);
}
}
}}
* Description [#explanation]
* Description [#description]
- ヘッダセル
-- `TableCellRenderer`内でセルの幅と文字列の長さを比較し`ToolTip`を設定
-- ソートアイコンなどが存在する場合を考慮して`SwingUtilities.layoutCompoundLabel(...)`メソッドを使用して`JLabel`内の文字列が省略されているかどうかを判断する
-- %%ソートアイコンと文字列の間隔は`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;
Insets i = l.getInsets();
Rectangle rect = getCellRect(row, column, false);
rect.width -= i.left + i.right;
FontMetrics fm = l.getFontMetrics(l.getFont());
String str = Objects.toString(getValueAt(row, column), "");
int cellTextWidth = fm.stringWidth(str);
l.setToolTipText(cellTextWidth > rect.width ? str : getToolTipText());
}
return c;
}
};
}}
* Reference [#reference]
- [[JTableHeaderのTooltipsを列ごとに変更>Swing/HeaderTooltips]]
- [[JTableのTooltipsを行ごとに変更>Swing/RowTooltips]]
- [[Fontから文字列の境界を取得する>Swing/StringBounds]]
* Comment [#comment]
#comment
#comment