java - JList 项中各个 JComponent 的工具提示

标签 java swing

我正在开发一个字典应用程序,它显示这样的单词条目:

word entry

单词条目由五个 JLabel 组成。 JLabel ENn星号 具有解释缩写或符号含义的工具提示文本。当单词条目放置在常规 JPanel 中时,此功能可以正常工作,但如果将其放置在 JList 项中,则不会显示工具提示文本 - 可能会被 JList 的(不存在的)工具提示覆盖。

我见过类似 this 的答案,但它们只为 JList 项添加工具提示,而不为包含该项的各个 JComponent 添加工具提示。

是否有任何方法可以更改 Z 顺序,以便 JLabels 的工具提示可见?

最佳答案

The word entry is made up of five JLabels.

您不应该将 Swing 组件存储在 ListModel 中。使用渲染器的目的是将数据存储在模型中,然后使用渲染器来显示数据。

因此,在您的情况下,您需要创建一个具有 8 个属性的自定义对象。标签中显示的文本有 5 个属性,工具提示文本有 3 个属性。那么你的渲染器将是一个带有 5 个标签的 JPanel。在渲染代码中,您只需使用自定义对象中的数据设置 5 个标签中每个标签的文本即可。您还可以设置工具提示文本。

接下来您需要重写 JList 的 getToolTipText(MouseEvent) 方法。此代码的默认实现获取渲染器,然后仅返回渲染器的提示。这很简单,因为渲染器通常只是一个 JLabel。

在您的情况下,逻辑会稍微复杂一些,因为渲染器中有子组件,因此您需要获取子组件的工具提示。

以下是 getToolTipText(...) 方法的当前代码:

public String getToolTipText(MouseEvent event) {
    if(event != null) {
        Point p = event.getPoint();
        int index = locationToIndex(p);
        ListCellRenderer<? super E> r = getCellRenderer();
        Rectangle cellBounds;

        if (index != -1 && r != null && (cellBounds =
                           getCellBounds(index, index)) != null &&
                           cellBounds.contains(p.x, p.y)) {
            ListSelectionModel lsm = getSelectionModel();
            Component rComponent = r.getListCellRendererComponent(
                       this, getModel().getElementAt(index), index,
                       lsm.isSelectedIndex(index),
                       (hasFocus() && (lsm.getLeadSelectionIndex() ==
                                       index)));

            if(rComponent instanceof JComponent) {
                MouseEvent      newEvent;

                p.translate(-cellBounds.x, -cellBounds.y);
                newEvent = new MouseEvent(rComponent, event.getID(),
                                          event.getWhen(),
                                          event.getModifiers(),
                                          p.x, p.y,
                                          event.getXOnScreen(),
                                          event.getYOnScreen(),
                                          event.getClickCount(),
                                          event.isPopupTrigger(),
                                          MouseEvent.NOBUTTON);

                String tip = ((JComponent)rComponent).getToolTipText(
                                          newEvent);

                if (tip != null) {
                    return tip;
                }
            }
        }
    }
    return super.getToolTipText();
}

感谢您需要更改的代码位于此区域:

p.translate(-cellBounds.x, -cellBounds.y);
newEvent = new MouseEvent(rComponent, event.getID(),

这会将鼠标点从 JList 转换到渲染器。所以现在我认为你只需要修改逻辑来获取翻译点的标签,然后获取标签工具提示。

所以新的代码可能是这样的:

p.translate(-cellBounds.x, -cellBounds.y);
Component label = rComponent.getComponentAt(p);

if (label == null) return super.getToolTipText();

newEvent = new MouseEvent(label, event.getID(),

关于java - JList 项中各个 JComponent 的工具提示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35940172/

相关文章:

java - object 在java中构造一个对象类

java - 无法在 JTable 中创建带有复选框的列

java - JVM如何调用Swing中的paint?

java - 将 Java Google AppEngine 应用程序转换为 Python AppEngine

java - 在使用泛型参数调用方法时,有什么方法可以避免类型转换?

java - 如何使用 Gradle 拉取 Maven 测试 jar ?

java - 双击 jar 时,java 输出流会发生什么?

java - javax.swing.SwingUtilities.invokeLater 是必要的吗?

java - 如何从 groupbutton 中检索 jbuttons 文本

java - 列表迭代类型不匹配