java在TableCellRenderer中使用自定义Swing 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)
,它更新得很好。(编辑:我有一个摆动计时器,可以定期更新数据)
但如果这个组件是我在TableCellRenderer中返回的东西。GetTableCellRenderComponent(),则仅当我单击相关单元格时,它才会重新绘制。有什么好处?我一定漏掉了一些非常简单的东西
# 1 楼答案
你们两人(Russ Hayward和Andrew)都提供了帮助,关键是要做到以下几点:
fireTableCellUpdated()
TableCellRenderer.getTableCellRendererComponent()
内存储单元的状态,以便稍后呈现(长期存储在TableModel中)JComponent.PaintComponent()
TableCellRenderer.getTableCellRendererComponent()
中存储单元的状态和return this;
下面是我的代码的相关摘录,现在可以使用了:
# 2 楼答案
出于性能方面的考虑,JTable重用渲染器组件来绘制多个单元格——因此,当您在JTable中看到组件时,它实际上并不存在于传统意义上的容器中的某个位置。这意味着在渲染器组件上调用repaint()不会产生任何效果
最有效的选择是在TableModel中存储条的整数值。您的TableCellRenderer将如下所示:
然后,您可以更改TableModel中的整数,它将触发条的重新绘制(您可能需要TableModel.fireTableCellUpdated,具体取决于您使用的TableModel实现)
# 3 楼答案
如果你制作了一个包含3行的表格,每一行都有一个不同的Xval,那么它最初的渲染是否正确,这意味着每个单元格都有一个不同的外观条
当您说除非单击它,否则它不会重新绘制时,您的基础数据是否发生了本应导致数据(渲染栏)的视觉显示发生变化的情况
如果数据发生了变化,但表没有立即重新呈现,那么我会说您的表模型工作不正常
基础数据更改->;表格模型更改->;fires TableModelEvent->;JTable重新渲染
请看TableModel tuturial:http://java.sun.com/docs/books/tutorial/uiswing/components/table.html#data
确保你做的每件事都是正确的