Swing/ClippedCellTooltips の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/ClippedCellTooltips へ行く。
- Swing/ClippedCellTooltips の差分を削除
--- 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) { JTableHeader header = table.getTableHeader(); TableCellRenderer r = header.getDefaultRenderer(); Component c = r.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 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); // = table.getCellRect(row, column, false); Rectangle rect = header.getHeaderRect(column); rect.width -= i.left + i.right; boolean isClipped = isClipped(l, rect); // isClipped = l.getFontMetrics(l.getFont()).stringWidth(l.getText()) > rect.width; // 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); 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); } } }} * 解説 [#explanation] - ヘッダセル -- `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] - [[JTableHeaderのTooltipsを列ごとに変更>Swing/HeaderTooltips]] - [[JTableのTooltipsを行ごとに変更>Swing/RowTooltips]] - [[Fontから文字列の境界を取得する>Swing/StringBounds]] * コメント [#comment] #comment #comment