Search code examples
javaswinganimationtimerpaintcomponent

Problems With Timer Animations


What I Want To Do: Animate the rectangles so that they go from the right of the screen to the left side of the screen. Here's the code for painting:

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JPanel;
import javax.swing.Timer;

public class graphics extends JPanel{

    public static Timer a;

    public static int animation = 0;

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        this.setBackground(new Color(40,40,40));

        g.setColor(new Color(197,255,172));
        g.fillRect(animation, 0, 800, 35);

        g.setColor(new Color(141,229,123));
        g.fillRect(animation, 35, 800, 35);

        g.setColor(new Color(112,183,98));
        g.fillRect(animation, 70, 800, 35);

        g.setColor(new Color(84,137,73));
        g.fillRect(animation, 105, 800, 35);

        g.setColor(new Color(42,68,36));
        g.fillRect(animation, 140, 800, 35);

        g.setFont(new Font("Dekar Light", Font.PLAIN, 30));
        g.setColor(Color.WHITE);
        g.drawString("Graphics Test", 326, 300);

        a = new Timer(1000, new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                repaint();
                int velx = 5;

                animation = animation - velx;
                System.out.println(animation);
            }

        });

        a.start();
    }
}

And here is the frame: enter image description here

My Problem: As you can see, it seems that the rectangles move double the distance than what they last moved.

My Question: What am I doing wrong? I need to know if it's something with either the timer or the equation I'm using.


Solution

  • I need to know if it's something with either the timer

    A painting method should only ever do painting!

    It should NOT start the Timer. Every time you paint the component you start another Timer so you end up generating multiple repaint() requests. The RepaintManager will then combine multiple requests into a single repaint of the component.

    The Timer should be started in the constructor of the class or you should create a startAnimation() method method and add it to your panel. Then that method can be invoked after the frame is made visible (or as required).

    Also, class names should ALWAYS start with an upper case character. However you should NOT use "Graphics" since there is already a Java class with that name. Make your class name more descriptive.