我有一个自定义TableCellRenderer
我希望根据鼠标位于单元格中的位置显示不同的工具提示。我遇到的问题是getWidth()
从0
调用时始终返回getToolTipText
。
这是一个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()
会在0
方法中返回getToolTipText
吗?有更好的方法吗?
答案 0 :(得分: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;
}
答案 1 :(得分:2)
您在两个不同的背景下看到来自同一getWidth()
的{{1}}的结果:
在JLabel
中,paintComponent()
已添加到JLabel
调用CellRendererPane
来计算宽度。
在validate()
中,表格getToolTipText()
访问的标签尚未经过验证。
有一个使用ToolTipManager
here的例子。