Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: Safe Animations with Swing

I am creating a program that uses JFrame, JPanel, JLabel and all other sorts of swing components.

What I want to do is create a 2D animation on a separate JPanel that is dedicated to this animation. So I will be overriding the paintComponent (Graphics g) method.

I have experience making animations with for loops + Threads, but I am hearing that threads are not safe with swing.

Due to this, is it safe for me to make an animation with the use of the Runnable interface? If not what shall I use (e.g. Timer) and please give a small example on how to best use it (or a link to a web page).

EDIT:

Thanks to Jeff, I will be using Timer to create the animation. For future viewers of this question, here is a quick program I coded in about 5 minutes, excuse the dirty code.

I have also added some quick comments.

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


class JFrameAnimation extends JFrame implements ActionListener
{

    JPanel panel;
    Timer timer;
    int x, y;

    public JFrameAnimation ()
    {
        super ();
        setDefaultCloseOperation (EXIT_ON_CLOSE);
        timer = new Timer (15, this); //@ First param is the delay (in milliseconds) therefore this animation is updated every 15 ms. The shorter the delay, the faster the animation.
        //This class iplements ActionListener, and that is where the animation variables are updated. Timer passes an ActionEvent after each 15 ms.

    }


    public void run ()
    {

        panel = new JPanel ()
        {
            public void paintComponent (Graphics g)  //The JPanel paint method we are overriding.
            {
                g.setColor (Color.white);
                g.fillRect (0, 0, 500, 500); //Setting panel background (white in this case);
                //g.fillRect (-1 + x, -1 + y, 50, 50);  //This is to erase the black remains of the animation. (not used because the background is always redrawn.
                g.setColor (Color.black);
                g.fillRect (0 + x, 0 + y, 50, 50); //This is the animation.

            }

        }
        ;
        panel.setPreferredSize (new Dimension (500, 500)); //Setting the panel size

        getContentPane ().add (panel); //Adding panel to frame.
        pack ();
        setVisible (true);
        timer.start (); //This starts the animation.
    }


    public void actionPerformed (ActionEvent e)
    {
        x++;
        y++;
        if (x == 250)
            timer.stop (); //This stops the animation once it reaches a certain distance.
        panel.repaint ();  //This is what paints the animation again (IMPORTANT: won't work without this).
        panel.revalidate (); //This isn't necessary, I like having it just in case.

    }


    public static void main (String[] args)
    {
        new JFrameAnimation ().run (); //Start our new application.
    }
}
like image 479
Jimmy Huch Avatar asked Jun 08 '11 02:06

Jimmy Huch


People also ask

How do you animate in Java Swing?

Java Swing does not by default have any built in animation tools available, leaving it up to the programmer to implement any sort of animation themselves. While animation of custom graphics can be quite case specific, animation of the Swing Components themselves * can be generalized into a simple animation framework.

How to create an animation in Java?

The JFrame class from the Java Swing library can be used to create different graphics and animations in Java. Until JDK 8 applet was used to create animations, but later it was deleted, and JAVA swing was added. This tutorial will discuss and demonstrate creating an animation using Java.

What makes a good swing animation framework?

A framework should be general enough to allow for many types of animation - fades, size changes, etc... - of all types of Swing Components. The framework I built is generalized via the simple implementation of an interface. At its core is a Swing Timer and callback system.

Which applet is used to create animations in Java?

Until JDK 8 applet was used to create animations, but later it was deleted, and JAVA swing was added. This tutorial will discuss and demonstrate creating an animation using Java.


2 Answers

Jimmy, I think you are misunderstanding how threads work in Swing. You must use a specific thread called the Event Dispatch Thread to do any updating on swing components (with a few specific exceptions I won't discuss here). You can use a swing timer to set a recurring task to run on the event dispatch thread. See this example of how to use Swing timers. http://download.oracle.com/javase/tutorial/uiswing/misc/timer.html

You should also read up on the Event Dispatch Thread so you understand its place in Swing http://download.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html

Java also provides a variety of methods for working with Swing in the SwingUtilities class, notably invokeLater and invokeAndWait which will run code on the event dispatch thread.

like image 177
Jeff Storey Avatar answered Oct 18 '22 12:10

Jeff Storey


While is good to understand the EDT and SwingUtilities (everybody doing Swing should do so) if you're going to be doing a lot of animation I would recommend to use the TimingFramework. This will allow you to concentrate a little more on design and will give you a better control on "rate". Inherently the timing framework uses a Swing timer so the callbacks are on the EDT. Part of the Filthy-rich clients collection, the author made the chapter available.

Have fun!

like image 30
Windust Avatar answered Oct 18 '22 12:10

Windust