好的,我知道如何制作一个简单的自定义JComponent。我知道如何重写TableCellRenderer。我似乎无法将两者结合起来。
这是我创建的示例JComponent
:
public static class BarRenderer extends JComponent
{
final private double xmin;
final private double xmax;
private double xval;
public BarRenderer(double xmin, double xmax)
{
this.xmin=xmin;
this.xmax=xmax;
}
@Override protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Rectangle r = g.getClipBounds();
g.drawRect(r.x, r.y,
(int)(r.width * ((xval-xmin)/(xmax-xmin))), r.height);
}
public void setXval(double x) {
this.xval = x;
repaint();
}
public double getXval() { return xval; }
}
它可以作为独立的JComponent正常工作。我叫
setXval(something)
,它更新就好了。 (编辑:我有一个Swing计时器,可以定期更新数据)但是,如果此组件是我在TableCellRenderer.getTableCellRendererComponent()中返回的组件,则仅在单击相关单元格时才重新绘制。是什么赋予了?我一定会遗漏一些非常简单的东西。
最佳答案
出于性能方面的考虑,JTable会重复使用渲染器组件来绘制多个单元格-因此,当您看到JTable中的组件时,按照传统意义上的某个容器中存在于某个位置的容器,它实际上并不存在。这意味着在渲染器组件上调用repaint()不会执行任何操作。
最有效的选择是将Bar的Integer值存储在TableModel中。然后,您的TableCellRenderer看起来像这样:
public class BarTableCellRenderer implements TableCellRenderer {
private final BarRenderer rendererComponent = new BarRenderer(0, 10);
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
rendererComponent.setXval((Integer)value);
return rendererComponent;
}
}
然后,您可以在TableModel中更改Integer,这将触发重新绘制栏(您可能需要TableModel.fireTableCellUpdated,具体取决于您使用的TableModel实现)。
关于java - 在TableCellRenderer中使用自定义的Swing JComponent,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/864707/