执行一次后如何停止计时器任务

时间:2019-01-13 22:02:42

标签: java timer timertask

此代码有2个问题 1)我在while语句内的代码中看到错误“从内部类引用的局部变量必须是最终的或实际上是最终的”。 2)虽然我已经使用了timer.cancel()我无法停止计时器。它一直在工作。简而言之,每当我创建另一个对象(椭圆形)时,它都会到达先前的终点。

private void JButton3ActionPerformed(java.awt.event.ActionEvent evt) 
    {                                         
        Timer timer = new Timer(); 

        Graphics g = JPanel1.getGraphics();
        int x1 = P.objectXCoordinate + P.OvalWidth/2;
        int y1 = P.objectYCoordinate + P.OvalHeight/2;
        int x2 = P.endPointX;
        int y2 = P.endPointY;
        int dx = Math.abs(x2 - x1);
        int dy = Math.abs(y2 - y1);
        int xn = x1;
        int yn = y1;
        //Special step variables
        int xs;
        int ys;
        int pn;
        // Dicreasing xn/yn solution
        if (x2 < x1){
            xs = -1;
        }
        else{
            xs = 1;
        }
        if (y2 < y1){
            ys = -1;
        }
        else{
            ys = 1;
        }
        //Bresenham algorithm (main)
        //dx > dy
        DrawObject();
        if (dx >= dy)
        {
            pn = 2*dy - dx;
             TimerTask task = new TimerTask()
    {
        public void run()
        {
            while(xn != x2)
            {
                xn = xn + xs;
                if (pn>0)
                {
                    yn = yn + ys;
                    pn = pn + 2*dy-2*dx;
                }
                else
                {
                    pn = pn + 2*dy;
                }
                g.setColor(Color.black);
                P.objectXCoordinate = xn;
                P.objectYCoordinate = yn;
                DrawPanel();
                DrawObject();
//            g.drawLine(xn, yn, xn, yn);
            }
        }
    };
             timer.scheduleAtFixedRate(task, 0, 5000);
             task.cancel();
             task=null;

        }    
        //dy > dx
        else if (dy >=dx)
        {
            pn = 2*dx - dy;
            TimerTask task = new TimerTask()
         {
                   public void run()
           {
            while(yn != y2)
                {
                yn = yn + ys;
                if (pn>0)
                {
                    xn = xn + xs;
                    pn = pn + 2*dx-2*dy;
                }
                else
                {
                    pn = pn + 2*dx;
                }
                g.setColor(Color.black);
                P.objectXCoordinate = xn;
                P.objectYCoordinate = yn;
                DrawPanel();
                DrawObject();
//            g.drawLine(xn, yn, xn, yn);

        }

                }
         };
            timer.scheduleAtFixedRate(task, 0, 5000);
           task.cancel();
           task=null;
        }


            }

1 个答案:

答案 0 :(得分:1)

摆动Timer不是TimerTask,相反,您只需简单地stop Timer ...话虽如此,关于您的代码有很多事情只是吓到我了,这并不好笑。

首先,查看How to Use Swing TimersJavaDocs for Swing Timer。您要寻找的方法是stop。要调用它,您将需要引用Timer本身。

一种方法是从注册到Timer的{​​{1}}的{​​{1}}的{​​{1}}中提取ActionEvent引用

ActionListener

自从您进入Swing后,您需要停止使用Timer,因此Swing不是线程安全的,并且您不应该尝试从事件调度线程的上下文外部更新UI-看一下{{ 3}}。

Timer timer = (Timer)evt.getSource();

这既危险又不明智。 TimerTask可以返回Graphics g = JPanel1.getGraphics(); ,充其量只是最后一个绘制周期的快照。您尝试绘画的任何内容都将在下一个绘画周期中删除。

停下来,继续阅读Concurrency in SwingPerforming Custom Painting,以更好地了解Swing中的绘画工作原理以及应该如何使用它。

您似乎只是徒劳地尝试将尽可能多的代码插入问题中,而不是了解可以使用的API以及如何实际使用它们。您可能需要将问题分解成小块,您可以将其分解为一个小块,并尝试单独解决,并且一旦了解了它们的工作原理,便可以将它们组合成一个更大的解决方案