如何在JTable的单元格中添加工具提示?

30

我有一个表格,每一行代表一张图片。在“路径”列中,我存储了它的绝对路径。由于字符串有点长,因此当我将鼠标悬停在特定单元格上时,我希望应该会出现一个工具提示,其中包含单元格中的信息。

3个回答

50

在创建JTable对象时,只需使用下面的代码。

JTable auditTable = new JTable(){

            //Implement table cell tool tips.           
            public String getToolTipText(MouseEvent e) {
                String tip = null;
                java.awt.Point p = e.getPoint();
                int rowIndex = rowAtPoint(p);
                int colIndex = columnAtPoint(p);

                try {
                    tip = getValueAt(rowIndex, colIndex).toString();
                } catch (RuntimeException e1) {
                    //catch null pointer exception if mouse is over an empty line
                }

                return tip;
            }
        };

1
实际上,我认为它比被接受的解决方案更有效率。 - Béatrice Cassistat
当我们根据某一列对表格进行排序时,这可能不起作用。 - Nagendra Varma
2
使用 getRowSorter().convertRowIndexToModel(rowIndex)getRowSorter().convertRowIndexToModel(rowIndex) 从模型中获取确切的行。 - Nagendra Varma
1
在这个例子中,使用了JTable.getValueAt,它使用视图索引。只有在使用模型查找值时(即getModel().getValueAt),才需要使用模型索引。因此,如示例所写,当表格被排序、过滤等操作时,它仍然可以正常工作。 - TT.

34

我假设你没有为路径编写自定义的 CellRenderer,而是使用了DefaultTableCellRenderer。你应该继承 DefaultTableCellRenderer 并在 getTableCellRendererComponent 中设置提示。然后为列设置渲染器。

class PathCellRenderer extends DefaultTableCellRenderer {
    public Component getTableCellRendererComponent(
                        JTable table, Object value,
                        boolean isSelected, boolean hasFocus,
                        int row, int column) {
        JLabel c = (JLabel)super.getTableCellRendererComponent( /* params from above (table, value, isSelected, hasFocus, row, column) */ );
        // This...
        String pathValue = <getYourPathValue>; // Could be value.toString()
        c.setToolTipText(pathValue);
        // ...OR this probably works in your case:
        c.setToolTipText(c.getText());
        return c;
    }
}

...
pathColumn.setCellRenderer(new PathCellRenderer()); // If your path is of specific class (e.g. java.io.File) you could set the renderer for that type
...

你不能调用 super.getTableCellRendererComponent。 - codenamezero
2
@codenamezero 为什么不呢?您知道在示例代码中,我对 DefaultTableCellRenderer 进行了子类化,该类以非抽象的方式具有该方法,并且本身就是 JLabel 吗? - Hauke Ingmar Schmidt
getTableCellRendererComponent() 方法中有一个参数 Object value。那么这里的 value 是什么意思呢?它是我们放置 tooltip 的行数据还是列数据? - chamzz.dot
@chamzz.dot 我不确定我完全理解你的意图,但我会尝试。渲染器仅用于单个单元格。DefaultTableCellRenderer JLable 的层次结构,并被强制转换为此,以便可以使用其所有方法。 - Hauke Ingmar Schmidt
好的,我的意思是这样的,Hauke Ingmar Schmidt,你传递给 getTableCellRendererComponent 方法的值在这里非常重要。这里第二个参数 Object value 必须是您列的值。然后,您可以尝试使用 JLabel cellComponent = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 再加上 cellComponent.setToolTipText(value.toString()); - chamzz.dot
转换为JLabel似乎太多了,只需测试super.getTableCellRenderer的引用与JComponent,并且您可以设置提示:Component c = super.getTableCellRendererComponent(); if (c instanceof JComponent) {((JComponent) c).setToolTipText("what you need");} - Amadeu Barbosa

0

你说你在单元格中存储了一个绝对路径。你可能正在使用 JLabel 来设置 绝对路径字符串。假设你的单元格中有一个标签,使用 HTML 标签来表达工具提示内容:

JLabel label = new JLabel("Bla bla");
label.setToolTipText("<html><p>information about cell</p></html>");

setToolTipText() 可以用于一些其他的 Swing 组件,如果你正在使用除 JLabel 之外的东西。


1
"绝对不可能". 我想知道 @deporter 是否理解这条评论。可惜我并不理解。:( - Andrew Thompson
3
请更准确一些:在您的单元格中“有一个标签”可能会具有误导性(单元格中不应该有任何组件)。相反,这是渲染器提供的标签,作为呈现组件的一部分。 - kleopatra
2
这意味着我不理解评论。如果您理解,请向我解释。否定所指的是什么?“nope”是什么? - Andrew Thompson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接