Как остановить задание таймера после однократного выполнения - PullRequest
0 голосов
/ 14 января 2019

У меня 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 голосов
/ 14 января 2019

Swing Timer НЕ является TimerTask, вместо этого вам нужно просто stop Timer ... сказав, что в вашем коде есть так много вещей, которые просто пугают меня, это не смешно.

Сначала рассмотрим Как использовать Swing Timers и JavaDocs для Swing Timer. Метод, который вы ищете, это stop. Чтобы позвонить, вам понадобится ссылка на саму Timer.

Один из способов сделать это - извлечь ссылку Timer из ActionEvent из ActionListener, зарегистрированного в Timer

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

Поскольку вы находитесь в Swing, вам необходимо прекратить использование TimerTask, Swing НЕ является потокобезопасным, и вам не следует пытаться обновлять пользовательский интерфейс вне контекста потока диспетчеризации событий - посмотрите на Параллельность в Swing для более подробной информации.

Graphics g = JPanel1.getGraphics();

Это одновременно опасно и плохо. getGraphics может вернуть null, и в лучшем случае это просто снимок последнего цикла рисования. Все, что вы пытаетесь нарисовать, будет стерто в следующем цикле рисования.

Остановись, иди и прочитай Выполнение пользовательской рисования и Рисование в AWT и Swing , чтобы лучше понять, как работает рисование в Swing и как с ним работать.

Кажется, вы просто подключаете столько кода к своей проблеме в какой-то тщетной попытке ее решить, а скорее понимаете доступные вам API и то, как вы должны их использовать. Возможно, вам придется разбить вашу проблему на небольшие куски, с которыми вы можете поиграть и попытаться решить их изолированно, и, как только вы поймете, как они работают, объедините их в более масштабное решение

...