我已经使用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个条件之一(顺便说一句,如果false
返回read.temp.get(i)
或int
,则条件均为Integer
)。
要解决所有这些问题,请放下Timer,放下TimerTask,并在第一个for-loop
查找中直接找到圆圈的颜色,并立即正确绘制它们。如果要更新显示,则可以致电repaint()
顺便说一句,您的TimerTask
不在EDT(事件调度线程)上运行,但是您仍然可以从其中访问与UI相关的内容。这违反了所有与UI相关的任务都应在EDT上执行的事实(使用Swing Timer
或SwingUtilities.invokeLater()
)
在您的TimerTask
中,您访问的Graphics2D ga
与Graphics g
提供的paintComponent()
相同:您不能在Graphics
方法范围之外访问该paintComponent
对象。 Graphics
是创建和处置的,因此不应在其范围之外使用。通常,您永远不应保留对Graphics
对象的引用(也不要使用方法getGraphics()
可能很诱人,但会引起各种严重的头痛)。
关于java - TImerTask在paintComponent上,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15088820/