我已经使用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 Timernew 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 TimerSwingUtilities.invokeLater()
在您的TimerTask中,您访问的Graphics2D gaGraphics g提供的paintComponent()相同:您不能在Graphics方法范围之外访问该paintComponent对象。 Graphics是创建和处置的,因此不应在其范围之外使用。通常,您永远不应保留对Graphics对象的引用(也不要使用方法getGraphics()可能很诱人,但会引起各种严重的头痛)。

关于java - TImerTask在paintComponent上,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15088820/

10-12 03:06