Таймер свинга не работает должным образом

Мне предложили не использовать sleep для приостановки цели и вместо использования swingtimer но все равно он не работает. Анимация, которую я хочу достичь, - это шар, движущийся от левого верхнего угла по диагонали к низу.

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

class Show_starter {

    int x, y;
    JFrame window = new JFrame("Graphic_show");
    Graphic_panel jp = new Graphic_panel();

    public static void main(String[] args) {
        Show_starter start = new Show_starter();
        start.go();
    }

    private void go() {
        window.getContentPane().add(BorderLayout.CENTER, jp);
        window.setSize(600,800);
        window.setVisible(true);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    class Graphic_panel extends JPanel {

        public void paintComponent(Graphics g) {

            for ( int i = 0; i < 100; ++i) {
                g.setColor(Color.white);
                g.fillRect(0, 0, this.getWidth(), this.getHeight());
                g.setColor(Color.green);
                g.fillOval(x, y, 40, 40);

                x++;
                y++;

                try {

                    Timer tmr = new Timer(1000, new TimerListener()); //This fires an event after every 1 sec after it has started by start().
                   //But The ball travels too much fast and stops at a point and again travels very fast.
                    tmr.serRepeats(false); // even this is not working.
                    tmr.start();
                    //should i use repaint here or in Listener for this timer?
                } catch (Exception e){}
            }
        }

        class TimerListener implements ActionListener {

            public void actionPerformed(ActionEvent e) {
                jp.repaint();
            }
        }
    }
}

Поведение, которое он демонстрирует, очень странное, мяч сначала движется с очень высокой скоростью, на мгновение останавливается в точке и снова движется с той же скоростью.

Я также пытался изменить время для timer событие, чтобы выстрелить, но происходит то же самое.

Даже внутри цикла, где я начал timer последующий вызов функции не работает

setRepeats(false);

2 ответа

Решение

Не создавайте новые таймеры всегда достаточно одного таймера.decrees временной интервал немного больше.1 секунда слишком медленная для анимации. вам не нужен цикл и не увеличивайте x и y внутри paintcomponet() метод, потому что этот метод вызывается по какой-то причине, например, когда вы изменяете размер, минимизируете, максимизируете.

неожиданное поведение связано с вашим циклом и созданием новых таймеров (). например, в xy начинаются с нуля, но в первую секунду xy увеличивается до 100,100, в следующей краске вы видите их в позиции 100,100. Это похоже на быстрое движение и затем останавливается...

пример кода (отредактировано)

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class Show_starter {

    private Timer tmr;

    int x, y;
    JFrame window = new JFrame("Graphic_show");
    Graphic_panel jp = new Graphic_panel();

    public static void main(String[] args) {

        Show_starter start = new Show_starter();
        start.go();

    }

    private void go() {

        window.getContentPane().add(BorderLayout.CENTER, jp);
        window.setSize(600, 800);
        window.setVisible(true);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        tmr = new Timer(10, new ActionListener() { // time gap in millisecond

            @Override
            public void actionPerformed(ActionEvent ae) {

                jp.increse();
                jp.repaint();
            }
        });
        tmr.start();

    }

    class Graphic_panel extends JPanel {

        public void increse() {
            x++;
            y++;
            if (x > 100) { // stop animation at x>100
                tmr.stop();
            }
        }

        public void paintComponent(Graphics g) {

            g.setColor(Color.white);
            g.fillRect(0, 0, this.getWidth(), this.getHeight());
            g.setColor(Color.green);
            g.fillOval(x, y, 40, 40);

        }

    }
}

вывод (ровнее)

введите описание изображения здесь

Во-первых, вы не должны использовать loop внутри paint component,

public void paintComponent(Graphics g){
            g.setColor(Color.white);
            g.fillRect(0, 0, this.getWidth(), this.getHeight());
            g.setColor(Color.green);
            g.fillOval(x, y, 40, 40);
}

Просто нарисуйте его и сделайте x а также y публика в классе, так что вы можете легко получить доступ извне

Теперь запустите runnable (консультации invokelater а также swingUtilities) или создайте новый Thread

внутри public void run() делать любые анимации, которые вы хотите сделать. Вы можете использовать цикл, но добавить Thread.sleep(//in miliseconds) а также repaint() в каждой итерации.

примечание: вам нужно изменить x а также y а также repaint() так что это нарисовано в новой позиции. И sleep() необходим для замедления выполнения, иначе он не будет виден зрителю.

Другие вопросы по тегам