Tool tip in JPanel in JTable not working

2019-05-10 14:13发布

问题:

I have a JTable. One column holds a JPanel which contains some JLabels with ImageIcons. I have created a custom cell render and all works fine apart from the tool tip on the JLabel. When I mouse over any of these JLabels I need to show the Tooltip of that particular JLabel. Its not showing the tootlip of the JLabel.

Here is the CustomRenderer.

private class CustomRenderer extends
            DefaultTableCellRenderer implements TableCellRenderer {

        @Override
        public Component getTableCellRendererComponent(JTable table,
            Object value, boolean isSelected, boolean hasFocus, int row,
                int column) {   

            if (value != null && value instanceof List) {

                JPanel iconsPanel = new JPanel(new GridBagLayout());
                List<ImageIcon> iconList = (List<ImageIcon>) value;
                int xPos = 0;
                for (ImageIcon icon : iconList) {
                    JLabel iconLabel = new JLabel(icon);
                    iconLabel.setToolTipText(icon.getDescription());
                    GridBagConstraints gbc = new GridBagConstraints();
                    gbc.gridy = 1;
                    gbc.gridx = xPos++;
                    iconsPanel.add(iconLabel, gbc);
                }
                iconsPanel.setBackground(isSelected ? table
                        .getSelectionBackground() : table.getBackground());
                this.setVerticalAlignment(CENTER);
                return iconsPanel;
            }
            return this;
        }
    }

回答1:

The problem is that you set tooltips on subcomponents of the component returned by your CellRenderer. To perform what you want, you should consider override getToolTipText(MouseEvent e) on the JTable. From the event, you can find on which row and column the mouse is, using:

java.awt.Point p = e.getPoint();
int rowIndex = rowAtPoint(p);
int colIndex = columnAtPoint(p);

From there you could then re-prepare the cell renderer, find which component is located at the mouse position and eventually retrieve its tooltip.

Here is a snippet of how you could override JTable getToolTipText:

@Override
public String getToolTipText(MouseEvent event) {
    String tip = null;
    Point p = event.getPoint();

    // 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);
        Rectangle cellRect = getCellRect(hitRowIndex, hitColumnIndex, false);
        component.setBounds(cellRect);
        component.validate();
        component.doLayout();
        p.translate(-cellRect.x, -cellRect.y);
        Component comp = component.getComponentAt(p);
        if (comp instanceof JComponent) {
            return ((JComponent) comp).getToolTipText();
        }
    }

    // No tip from the renderer get our own tip
    if (tip == null) {
        tip = getToolTipText();
    }

    return tip;
}