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

Java 如何在执行一次后停止计时器任务,java,timer,timertask,Java,Timer,Timertask,这个代码有两个问题 1) 我在while语句中的代码中看到错误“从内部类引用的局部变量必须是final或实际上是final”。 2) 虽然我使用了timer.cancel(),但我无法停止计时器。它一直在工作。换句话说,每当我创建另一个对象(椭圆形)时,它都会转到前面的端点 private void JButton3ActionPerformed(java.awt.event.ActionEvent evt) {

这个代码有两个问题 1) 我在while语句中的代码中看到错误“从内部类引用的局部变量必须是final或实际上是final”。 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;
        }


            }
private void JButton3ActionPerformed(java.awt.event.ActionEvent evt)
{                                         
定时器=新定时器();
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=数学绝对值(x2-x1);
int dy=数学绝对值(y2-y1);
int xn=x1;
int-yn=y1;
//特殊步长变量
int-xs;
int ys;
int-pn;
//切割xn/yn溶液
if(x2dy
DrawObject();
如果(dx>=dy)
{
pn=2*dy-dx;
TimerTask任务=新的TimerTask()
{
公开募捐
{
while(xn!=x2)
{
xn=xn+xs;
如果(pn>0)
{
yn=yn+ys;
pn=pn+2*dy-2*dx;
}
其他的
{
pn=pn+2*dy;
}
g、 设置颜色(颜色为黑色);
P.objectXCoordinate=xn;
P.objectYCoordinate=yn;
DrawPanel();
DrawObject();
//g.抽绳(xn,yn,xn,yn);
}
}
};
timer.scheduleAtFixedRate(任务,0,5000);
task.cancel();
task=null;
}    
//dy>dx
如果(dy>=dx),则为else
{
pn=2*dx-dy;
TimerTask任务=新的TimerTask()
{
公开募捐
{
while(yn!=y2)
{
yn=yn+ys;
如果(pn>0)
{
xn=xn+xs;
pn=pn+2*dx-2*dy;
}
其他的
{
pn=pn+2*dx;
}
g、 设置颜色(颜色为黑色);
P.objectXCoordinate=xn;
P.objectYCoordinate=yn;
DrawPanel();
DrawObject();
//g.抽绳(xn,yn,xn,yn);
}
}
};
timer.scheduleAtFixedRate(任务,0,5000);
task.cancel();
task=null;
}
}

Swing
计时器
不是
计时器任务
,相反,您只需停止
计时器
。。。话虽如此,你的代码中有太多让我害怕的东西,一点也不好笑

首先,看一看和。您正在寻找的方法是。要调用它,需要引用
计时器本身

一种方法是从注册到
计时器的
ActionListener
ActionEvent
中提取
Timer
引用

Timer timer = (Timer)evt.getSource();
由于您在Swing中,您需要停止使用
TimerTask
,Swing不是线程安全的,您不应该尝试从事件调度线程的外部上下文更新UI-查看更多详细信息

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

停下来,读一读,更好地理解Swing中的绘画是如何工作的,以及你应该如何使用它


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

如果有人想查看完整的代码,请给我发电子邮件priteshsoni263@gmail.com