In this tutorial, I will show you how to animate Images in terms of direction in Java using the Swing Timer. For those that are perhaps novice to what is animation, animation is the process whereby a Image seemingly moves across the screen. In the programming world, the Image is being updated to a new position so fast that it fakes regular movement.
What is a timer and what is its use?

A timer is generally used as a way of checking data at regular intervals. If we apply this to a game, it can be very useful. Certain elements of a game generally have to be constantly checked and certain tasks generally have to be constantly done such as collision detection and drawing the units to the screen.
A swing timer can be used to schedule tasks as described above at regular or arbitrary intervals with a single thread. It is a class part of the javax.swing libraries.. The Swing Timer schedules actions via actionPerformed @ specific intervals as will be shown soon. This is generally perfect for Animation and GUI Related tasks.

Timer Logic:
As it is with most that are new to a concept, some questions come to mind. Some of the most common are:

How Do I Implement a Swing Timer:
The simplified steps of this would be:
1) Create a new action or class that instantiates the Timer Class.
2) Code functionality into the action or class
3) Call the timer

Where do I call my Swing Timer:
It really depends on the situation, however if it used for something like updating an Image that is immediately drawn
to the screen upon start up of the Swing application. I would suggest calling it in the constructor of your Swing Application.

How many times per second should I call it?:
Again this depends on what you are doing, if you are checking collision detection or painting something to a screen. Generally you want the timer to update many times a second, something like 15 millisecond intervals should be okay and will equate to around 66 Frames Per Second (FPS).

Now lets get into the code. There are three parts to our Ball Animation Project:

Ball - used to create features of a ball on screen, namely X and Y PositionsMainFrame - JFrame used to display our MainPanel JPanel so we do not have to use an applet.MainPanel - JPanel that is used for drawing and animating of the "ball", Swing Timer is in here.

Now here is our code, I have purposely left out explanatory comments here here so that I can dissect the program with you afterwards however some self-documenting comments are in the listings below and a fully commented version of this program will be available at the end of the tutorial :
Ball.java:

The class simply contains two private integers namely x and y that are used to store the ball's position on screen and that have accessors/mutators or GETTERS/SETTERS to access and change the information as this will be necessary when redrawing the ball Image.

Well that was simple enough... Now for MainFrame.java:

Our MainFrame.java class contains the main method and this is the class that is called first. We simply add our MainPanel (JPanel Component) to our JFrame container via:

MainPanel mPanel = new MainPanel();

and then set some mundane information about the JFrame namely (note the comments if you are unsure of what the methods do):

The next statement is very important if you are drawing loads of things at once and I included this as it is necessary knowledge:

setDoubleBuffered(true);

Application will use buffers this is efficient as in this case the drawing is done in memory and then
copied to the screen which can speed up our program although once again due to today's hardware features most Computer Systems will not lag running a program like this however this method is essential when you are drawing and animating many things at once especially to avoid flickering. For more on buffers, see this Link.

Next we create a Swing Timer that will perform the action we describe later in the program and how often we call it:

new Timer(15, paintTimer).start();

Here is a breakdown of the parameters/methods used:

new Timer(:
create Timer, call it in constructor of MainPanel().

15,:
15 = time between next call, measured in milliseconds. Decreasing this value can smooth
animation but means your application requires more memory and processing to constantly paint, generally not a big issue today however. A interval of 15 milliseconds equates to 66 or so fps when drawing the image(s) which is more than acceptable for most applications.

paintTimer):
paintTimer refers to the action method that we are going to call

.start();:
start() obviously starts our Timer

Hence the final statement is: create Timer(15, paintTimer).start();

Now onto the paint method, this is overridden from the java.awt.component and is called every time we use repaint(). The comments explain the relevant code:

public void paint(Graphics g) {
super.paint(g); //we repaint the JPanel and clear old images otherwise the previous image and new image would overlap
Graphics2D g2d = (Graphics2D)g; //creates a Graphics2D element which we use for drawing
g2d.drawImage(ballImage, currentBall.getX(), currentBall.getY(), this);//paint ballImage @ currentBall's X and Y position
Toolkit.getDefaultToolkit().sync(); //This if for linux systems, it synchronizes the painting otherwise it would not be smooth.
g.dispose();
}

Now for the action method. This is the functionality of our Swing Timer, without this method. There would be no point to the timer. The method is actually really simplistic and simply increases the Ball's X and Y values and then repaints the JPanel whenever it is called:

Action paintTimer = new AbstractAction() {
public void actionPerformed(ActionEvent e) {//functionality of our timer:
//set X and Y co-ordinates that will then be fetched when drawing the ball Image on the JPanel.
currentBall.setX(currentBall.getX() + 5);
currentBall.setY(currentBall.getY() +5);
repaint();
}
};

Here is an example of what will be displayed on the screen:

I hope you have enjoyed this tutorial, It simply animates a image across a screen but can be extended to do much more such as move a player across a screen. The full commented code listing of MainPanel.java can be found below, this was the only class I removed essential comments out of for explanation.

MainPanel.java With comments:

//required libraries:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class MainPanel extends JPanel {
Image ballImage;
Ball currentBall = new Ball(); // instantiate our ball class
public MainPanel() {
ImageIcon ball_IMG_ICON = new ImageIcon("ball.png");
ballImage = ball_IMG_ICON.getImage(); // get ImageIcon ball_IMG_ICON and
// store it in Image ballImage
prepareImage(ballImage, this);
currentBall.setX(10);
currentBall.setY(10); // set currentBall's X and Y Position
setDoubleBuffered(true);
/*
* Application will use buffers this is efficient as in this case the
* drawing is done in memory and then copied to the screen which can
* speed up our program although once again due to today's hardware
* features most Computer Systems will not lag running a program like
* this however this method is essential when you are drawing and
* animating many things at once.
*/
new Timer(15, paintTimer).start();
/*
* create Timer, call it in constructor of MainPanel() 15 = time between
* next call, measured in milliseconds. Decreasing this value can smooth
* animation but means your application requires more memory and
* processing to constantly paint, generally not a big issue today
* however. 15 millisecond interval equates to around 66 fps. paintTimer
* refers to the action method that we are going to call start()
* obviously starts our Timer
*/
// call paintTimer's action every 15 milliseconds
}
public void paint(Graphics g) {
super.paint(g); // we repaint the JPanel and clear old images otherwise
// the previous image and new image would overlap
Graphics2D g2d = (Graphics2D) g; // creates a Graphics2D element which
// we use for drawing
g2d.drawImage(ballImage, currentBall.getX(), currentBall.getY(), this);// paint
// ballImage
// @
// currentBall's
// X
// and
// Y
// position
Toolkit.getDefaultToolkit().sync(); // This is for linux systems, it
// synchronizes the painting
// otherwise it would not be smooth.
g.dispose();
}
Action paintTimer = new AbstractAction() {
public void actionPerformed(ActionEvent e) {// functionality of our
// timer:
// set X and Y co-ordinates that will then be fetched when drawing
// the ball Image on the JPanel.
currentBall.setX(currentBall.getX() + 5);
currentBall.setY(currentBall.getY() + 5);
repaint();
}
};
}

Replies To: Animating an Image in Swing utilizing the Swing Timer

i just tried out this code but my image is not loading in the frame even though i put it in the same directory.I use netbeans to code.what seems to be the problem?can i do it like this: add a panel to the frame in the design part and write the "MainPanel.java" code in that only?will it work.im into trying this but please reply why the image isnt loading.

This article is well written, but I'm afraid it doesn't help my program. My program is about clicking a destination and having an image move to the destination. I have the algorithm figured out and I have implemented it, but it takes two clicks(two on the dest. two on the image) to make the image move, and after that, if you try moving it, it glitches. I'm not sure if this is a timer problem or what, but could you please take a look at it.

One more thing, I've tried this animating with a thread and thread.sleep before, and that worked fine, but I had a bug I had to fix, so I thought it would be easier to use this. Before, I used for loops inside the if statements.

i just tried out this code but my image is not loading in the frame even though i put it in the same directory.I use netbeans to code.what seems to be the problem?can i do it like this: add a panel to the frame in the design part and write the "MainPanel.java" code in that only?will it work.im into trying this but please reply why the image isnt loading.

I am having the same problem and first I thought it was because I did not have ball.png, but after adding an image to my source package that did not help it. Does anyone has any ideas?