开发者

Java: Safe Animations with Swing

开发者 https://www.devze.com 2023-03-11 08:16 出处:网络
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.

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, th开发者_运维百科e 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.
    }
}


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.


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!

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号