Swing/ClippedCellTooltips のバックアップの現在との差分(No.3)
TITLE:JTableのセルがクリップされている場合のみJToolTipを表示
Posted by aterai at 2009-10-12
JTableのセルがクリップされている場合のみJToolTipを表示
JTableのセルがクリップされている場合のみJToolTipを表示します。- 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:
概要
JTable
のセルがクリップされている場合のみJToolTip
を表示します。
- &jnlp;
- &jar;
- &zip;
Screenshot
Advertisement
サンプルコード
#spanend
#spanadd
* サンプルコード [#sourcecode]
#spanend
#spanadd
#code(link){{
#spanend
class ToolTipHeaderRenderer implements TableCellRenderer {
private final TableCellRenderer renderer;
private final Icon icon = UIManager.getIcon("Table.ascendingSortIcon");
public ToolTipHeaderRenderer(TableCellRenderer renderer) {
this.renderer = renderer;
}
public Component getTableCellRendererComponent(JTable table,Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
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
// 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());
}
FontMetrics fm = l.getFontMetrics(l.getFont());
String str = value.toString();
int cellTextWidth = fm.stringWidth(str);
l.setToolTipText(cellTextWidth>rect.width?str:null);
return l;
return c;
}
#spanadd
#spanend
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);
}
}
解説
- ヘッダセル
- TableCellRendererで、セルの幅と文字列の長さを比較して、ToolTipを設定
- ソートアイコンと文字列の間のgapが不明?
解説
- ヘッダセル
-
TableCellRenderer
内でセルの幅と文字列の長さを比較しToolTip
を設定 - ソートアイコンなどが存在する場合を考慮して
SwingUtilities.layoutCompoundLabel(...)
メソッドを使用してJLabel
内の文字列が省略されているかどうかを判断する -
ソートアイコンと文字列の間隔はJLabel#getIconTextGap()
で取得してセル幅から除外する-
Windows 10
で使用されるWindowsLookAndFeel
のように文字列の上にソートアイコンが表示される場合(TableCellRenderer#getIcon()
がnull
)はこのアイコンの幅を無視する
-
-
- セル
-
JTable#prepareRenderer
メソッドをオーバーライドし、セルの幅と文字列の長さを比較してToolTip
を設定
-
- セル
- JTable#prepareRendererメソッドをオーバーライドし、セルの幅と文字列の長さを比較して、ToolTipを設定
JTable table = new JTable(model) {
public Component prepareRenderer(TableCellRenderer tcr, int row, int column) {
@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);
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;
}
};