JList项目中各个JComponents的工具提示

时间:2016-03-11 12:21:14

标签: java swing

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

word entry

单词条目由五个JLabel组成。 JLabels EN n 明星包含工具提示文字,用于说明缩写或符号的含义。当单词条目放置在常规JPanel中时,这可以正常工作,但如果它被放置在JList项目中,则不会显示工具提示文本 - 可能是由JList(不存在的)工具提示覆盖。

我见过像this这样的答案,但是他们只为JList项添加了一个工具提示,而不是为包含该项的单个JComponents添加。

有没有办法,例如,更改Z顺序,以便JLabel的工具提示可见?

2 个答案:

答案 0 :(得分:2)

  

单词条目由五个JLabel组成。

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

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

接下来,您需要覆盖JList的getToolTipText(MouseEvent)方法。此代码的默认实现获取渲染器,然后只返回渲染器的tootip。这很简单,因为渲染器通常只是一个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(),

答案 1 :(得分:1)

你很困惑。您没有将组件添加到JList,而是使用ListRenderer。

所以你有两个选择:你可以为JList构建自己的自定义工具提示,也可以创建自己的JList版本