[英]TImerTask on paintComponent
我已经使用TimerTask在我的一个类的循环上添加了一个计时器,该循环由paint组件类调用。 基本上,页面上已经绘制了白色圆圈,然后有一个for循环,该循环从数组中读取一个值,并根据该值的范围来改变颜色。 每个圆圈应代表数组中的下一个值。 但它不起作用。 我是一个基本的程序员,真的不明白出了什么问题。 如果有人可以帮我,我将非常感激。 到目前为止,这是我的代码:
public DoThePaint() {
String fileName;
fileName = "/Users/Desktop/test2.txt";
read = new Reader(fileName);
read.displayArrayList();
panel = new JPanel();
newImage = new ImageIcon(this.getClass().getResource("resource/background2T.png")).getImage();
circlesT = new ArrayList<Shape>();
circlesT.add(new Ellipse2D.Float(197.0f, 352.0f, 10.0f, 10.0f));
circlesT.add(new Ellipse2D.Float(247.0f, 307.0f, 10.0f, 10.0f));
circlesT.add(new Ellipse2D.Float(152.0f, 303.0f, 10.0f, 10.0f));
circlesT.add(new Ellipse2D.Float(172.0f, 372.0f, 10.0f, 10.0f));
circlesT.add(new Ellipse2D.Float(223.0f, 378.0f, 10.0f, 10.0f));
circlesT.add(new Ellipse2D.Float(273.0f, 285.0f, 10.0f, 10.0f));
circlesT.add(new Ellipse2D.Float(130.0f, 281.0f, 10.0f, 10.0f));
circlesT.add(new Ellipse2D.Float(148.0f, 393.0f, 10.0f, 10.0f));
circlesT.add(new Ellipse2D.Float(246.0f, 403.0f, 10.0f, 10.0f));
circlesT.add(new Ellipse2D.Float(297.0f, 264.0f, 10.0f, 10.0f));
}
public void paintComponent(Graphics g) {
drawShapes(g, circlesT);
}
public void drawShapes(Graphics g, final ArrayList<Shape> circlesT) {
final Graphics2D ga = (Graphics2D) g;
ga.drawImage(newImage, 0, 0, null);
for (int i = 0; i < circlesT.size(); i++) {
ga.draw(circlesT.get(i));
ga.setPaint(Color.white);
ga.fill(circlesT.get(i));
}
Timer timer = new Timer();
TimerTask t;
t = new TimerTask() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
if (read.temp.get(i) < 31 && read.temp.get(i) > 30) {
ga.draw(circlesT.get(i));
ga.setPaint(Color.green);
ga.fill(circlesT.get(i));
} else if (read.temp.get(i) < 32 && read.temp.get(i) > 31) {
ga.draw(circlesT.get(i));
ga.setPaint(Color.red);
ga.fill(circlesT.get(i));
} else if (read.temp.get(i) < 33 && read.temp.get(i) > 32) {
ga.draw(circlesT.get(i));
ga.setPaint(Color.yellow);
ga.fill(circlesT.get(i));
}
}
}
};
repaint();
timer.schedule(t, 0, 5000);
}
抱歉,但这是您造成的恐惧:在paintComponent()
您将创建一个new Timer
,一个new TimerTask
并最终调用repaint()
。
paintComponent()
:您要做的只是绘画操作(在Graphics
上绘制图像,填充圆,绘制线,绘制文本,...)。 那就是你应该做的。 repaint()
最终将触发paintComponent()
再次被调用->重新创建计时器,计时器任务并调用repaint()-> paintComponent()-> repaint()-> ... ,您刚刚创建了一个无限循环,耗尽了您的资源 Reader
类做什么以及它拥有什么数据。 我可以看到有两点需要更改: temp
应该是private
并且可以使用getter或其他某种访问方法正确地进行访问。 循环中的条件非常严格,您确定所有值都将匹配3个条件之一(顺便说一句,如果read.temp.get(i)
返回int
或Integer
,则条件均为false
)。 for-loop
查找中直接添加圆圈的颜色,并立即正确绘制它们。 如果要更新显示,则可以调用repaint()
TimerTask
不在EDT(事件调度线程)上运行,但是您仍然可以从其中访问与UI相关的内容。 这违反了所有与UI相关的任务都应在EDT上执行的事实(使用Swing Timer
或SwingUtilities.invokeLater()
)。 TimerTask
您可以访问Graphics2D ga
,它与paintComponent()
提供的Graphics g
相同:您不能在paintComponent
方法的范围之外访问该Graphics
对象。 Graphics
是创建和处理的,因此不应在其范围之外使用。 通常,您永远不应保留对Graphics
对象的引用(也不要使用getGraphics()
方法,该方法可能很吸引人,但会引起各种严重的麻烦)。 您对Swing中的绘画工作有基本的误解。 没什么大不了的,每个人都必须从某个地方开始。
您似乎想制作动画。 因此,您的paintComponent方法应该在特定的时间点绘制对象的状态。 任何控制油漆时间的计时器都应该属于另一类。
对于简单的动画,TimerTask很好。 如果您想制作游戏动画或需要良好性能的游戏,我建议安德鲁·戴维森(Andrew Davison)在《 Killer Game Programming in Java》一书的第2章中介绍动画类。 您实际上可以在Amazon的Look Inside功能中阅读第2章。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.