3

我有一个自定义项TableCellRenderer,我想根据鼠标在单元格中的位置显示不同的工具提示。我遇到的问题getWidth()0getToolTipText.

这是一个SSCCE:

import javax.swing.*;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.awt.event.MouseEvent;

public class Sandbox {
  public static void main(String[] args) {
    JFrame testFrame = new JFrame("Test");
    testFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    testFrame.setLayout(new BorderLayout());

    JTable testTable = new JTable(new Object[][]{{"Value 1", null}}, new Object[] {"Column 1", "Column 2"});
    testTable.getColumnModel().getColumn(1).setCellRenderer(new CustomCellRenderer());

    testFrame.add(new JScrollPane(testTable), BorderLayout.CENTER);
    testFrame.pack();
    testFrame.setLocationRelativeTo(null);
    testFrame.setVisible(true);
  }

  private static class CustomCellRenderer implements TableCellRenderer {
    private final JLabel renderer = new JLabel()
    {
      @Override
      protected void paintComponent(Graphics g) {
        g.setColor(Color.RED);
        g.fillRect(0, 0, getWidth(), getHeight());
        System.out.println("Width from paintComponent = " + getWidth());
      }

      @Override
      public String getToolTipText(MouseEvent event) {
        System.out.println("Width from getToolTipText = " + getWidth());
        return super.getToolTipText(event);
      }
    };

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

您可以看到组件已调整大小,并且从paintComponent方法中打印出正确的结果。但是,当您将鼠标悬停在“第 2 列”中的单元格上时,该getToolTipText方法不会打印相同的值。

我发现以前问过类似的问题,但答案通常是Component尚未调整大小。在我的例子中,组件的大小已经很明显了。有人可以解释为什么在方法中getWidth()返回吗?有一个更好的方法吗?0getToolTipText

4

2 回答 2

3

覆盖 JTable 的 getToolTipText() 方法:

JTable testTable = new JTable(new Object[][]{{"Value 1", null}}, new Object[] {"Column 1", "Column 2"})
{
  @Override
  public String getToolTipText(MouseEvent event)
  {
    JTable table = (JTable)event.getSource();
    int column = table.columnAtPoint( event.getPoint() );

    if (column == 1)
    {
        int row = table.rowAtPoint( event.getPoint() );
        Rectangle r = table.getCellRect(row, column, false);
        Point p = new Point(event.getX() - r.x, event.getY() - r.y);
//          System.out.println("Width from getToolTipText = " + r.width);

        return p.toString();
    }

    return super.getToolTipText(event);
  }
};

如果要在渲染器中设置工具提示,代码应该在 getTableCellRenderComponent() 方法中。在这种情况下,您需要使用 MouseInfo 类来获取当前鼠标位置并将该位置转换为相对于表格单元格的位置。就像是:

@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
                                               boolean hasFocus, int row, int column)
{
    Point pointInTable = MouseInfo.getPointerInfo().getLocation();
    SwingUtilities.convertPointFromScreen(pointInTable, table);
    Rectangle r = table.getCellRect(row, column, false);
    Point p = new Point(pointInTable.x - r.x, pointInTable.y - r.y);
    table.setToolTipText(p.toString());

  return renderer;
}
于 2013-06-07T00:29:12.943 回答
2

您会在两种不同getWidth()的情况下看到相同的结果:JLabel

  1. paintComponent()中,JLabel已添加到CellRendererPane调用validate()以计算宽度的 a 。

  2. getToolTipText()中,表访问的标签ToolTipManager尚未经过验证。

CellRendererPane 这里有一个使用示例。

于 2013-06-07T00:35:15.933 回答