在自定义CellRenderer中覆盖createToolTip() [英] Overriding createToolTip() in a custom CellRenderer

查看:122
本文介绍了在自定义CellRenderer中覆盖createToolTip()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为JTable的特定列获取自定义工具提示.我已经创建了一个CellRenderer(已经成功更改了其他特定于单元格的属性):

I'm trying to get a custom ToolTip for a specific column of a JTable. I've already created a CellRenderer (of which I've been changing other cell-specific attributes successfully):

private class CustomCellRenderer extends DefaultTableCellRenderer
{
    private static final long   serialVersionUID    = 1L;

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column)
    {
        JComponent c = (JComponent) super.getTableCellRendererComponent(table, value,
                isSelected, hasFocus, row, column);

        if (value != null)
        {
            if(column == 1 && value instanceof Date)
            {
                final DateFormat df = new SimpleDateFormat("h:mm aa");
                table.setValueAt(df.format(value), row, column);
            }
            else if(column == 2)
            {
                c.setToolTipText((String) value);
            }
            else if(column == 4)
            {
                final Mail m = main.selectedPage.messages.get(row);
                JCheckBox checkBox;

                if((Boolean) value)
                {
                    checkBox = new JCheckBox()
                    {
                        @Override
                        public JToolTip createToolTip()
                        {
                            System.out.println("Passed");
                            return new ImageToolTip(m.getImage());
                        }
                    };
                    checkBox.setToolTipText(m.attachName);
                }
                else 
                    checkBox = new JCheckBox();

                checkBox.setSelected(((Boolean)value).booleanValue());
                c = checkBox;
            }
        }
        else
        {
            c.setToolTipText(null);
        }
        return c;
    }
}

当我像这样重写任何其他JComponent的createTooltip()方法时,在Renderer之外一切正常.

When I override any other JComponent's createTooltip() method like so, it all works fine outside of the Renderer.

checkBox = new JCheckBox()
{
    @Override
    public JToolTip createToolTip()
    {
        System.out.println("Passed");
        return new ImageToolTip(m.getImage());
    }
};

据我所知,该工具提示是在其他地方创建的,因为"Passed"从未打印过. checkBox.setToolTipText(m.attachName);仅产生带有该字符串的默认工具提示.

From what I can tell, the tooltip is created elsewhere, because "Passed" is never even printed. The checkBox.setToolTipText(m.attachName); only results in a default ToolTip with that String.

我发现有人遇到类似问题 ,但我不能说我完全理解唯一的解决方案.我是否需要扩展JTable并覆盖getToolTipText(MouseEvent e)?如果是这样,我不确定该如何获取正确的(提示)工具提示.

I've found someone with a similar question, but I can't say I completely understand the only resolving answer. Do I need to extend JTable and override getToolTipText(MouseEvent e)? If so, I'm not sure what with to get the correct (mine) Tooltip.

请原谅我任何自学成才的怪癖.提前致谢. :-)

Please excuse any of my self-taught weirdness. Thanks in advance. :-)

多亏了Robin,我能够基于JTable的getToolTipText(MouseEvent e)代码拼凑出一些东西.我会将它留给其他有类似问题的人使用.同样,我不确定这是否是实现此目标的最佳方法,请随时在下面对其进行评论. :-)

Thanks to Robin, I was able to piece together something based on JTable's getToolTipText(MouseEvent e) code. I'll leave it here for anyone else with a similar problem. Again, I'm not sure it this it the best way to do it, so feel free to critique it below. :-)

messageTable = new JTable()
{
    @Override
    public JToolTip createToolTip()
    {
        Point p = getMousePosition();

        // Locate the renderer under the event location
        int hitColumnIndex = columnAtPoint(p);
        int hitRowIndex = rowAtPoint(p);

        if ((hitColumnIndex != -1) && (hitRowIndex != -1)) 
        {
            TableCellRenderer renderer = getCellRenderer(hitRowIndex, hitColumnIndex);
            Component component = prepareRenderer(renderer, hitRowIndex, hitColumnIndex);

            if (component instanceof JCheckBox) 
            {
                Image img = main.selectedPage.messages.get(hitRowIndex).getImage();
                if(((JCheckBox) component).isSelected())
                    return new ImageToolTip(img);
            }
        }
        return super.createToolTip();
    }
}

推荐答案

在实现中可以看到JTable不使用工具提示的原因. JTable确实会使用渲染器返回的组件,但会要求其提供工具提示文本.因此,如果您坚持使用默认的JTable实施方式,则只有设置自定义工具提示文本才有效.只需快速复制粘贴JTable源代码的相关部分即可说明这一点:

The reason that the JTable does not use your tooltip can be seen in the implementation. The JTable will indeed use the component returned by the renderer, but it will ask it for its tooltip text. So only settings a custom tooltip text will work if you stick to the default JTable implementation. Just a quick copy-paste of the relevant part of the JTable source code to illustrate this:

    if (component instanceof JComponent) {
        // Convert the event to the renderer's coordinate system
        Rectangle cellRect = getCellRect(hitRowIndex, hitColumnIndex, false);
        p.translate(-cellRect.x, -cellRect.y);
        MouseEvent newEvent = new MouseEvent(component, event.getID(),
                                  event.getWhen(), event.getModifiers(),
                                  p.x, p.y,
                                  event.getXOnScreen(),
                                  event.getYOnScreen(),
                                  event.getClickCount(),
                                  event.isPopupTrigger(),
                                  MouseEvent.NOBUTTON);

        tip = ((JComponent)component).getToolTipText(newEvent);
    }

是的,如果您确实希望将图像用作复选框的工具提示,则必须覆盖JTable方法.

So yes, you will have to override the JTable method if you really want an image as tooltip for your check box.

在旁注:您的渲染器代码具有怪异的行为.

On a side-note: your renderer code has weird behavior. The

final DateFormat df = new SimpleDateFormat("h:mm aa");
table.setValueAt(df.format(value), row, column);

似乎不正确.您应将

JLabel label = new JLabel();//a field in your renderer
//in the getTableCellRendererComponent method
label.setText( df.format( value ) );
return label;

或类似的东西.渲染器不应调整表值,而应创建适当的组件以可视化数据.在这种情况下,JLabel似乎足够.正如斯坦尼斯拉夫(Stanislav)在评论中所指出的那样,您不应该不断创建新组件.这违反了为避免为每个行/列组合创建新组件而引入的渲染器的目的.请注意,该方法称为getTableCellRendererComponent(强调get)而不是createTableCellRendererComponent

or something similar. The renderer should not adjust the table values, but create an appropriate component to visualize the data. In this case a JLabel seems sufficient. And as Stanislav noticed in the comments, you should not constantly create new components. That defeats the purpose of the renderer which was introduced to avoid creating new components for each row/column combination. Note that the method is called getTableCellRendererComponent (emphasis on get) and not createTableCellRendererComponent

这篇关于在自定义CellRenderer中覆盖createToolTip()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆