Java: safe animations with Swing

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

What I want to do is create a 2D animation on a separate JPanel, which is designed for this animation. Therefore, I will override the paintComponent (Graphics g) method.

I have experience creating animations with loops + Threads, but I hear that threads are not safe with swings.

Because of this, is it safe for me to make animations using the Runnable interface? If not, what should I use (e.g. Timer) and please give a small example of how best to use it (or a link to a web page).

EDIT:

Thanks Jeff, I will use a timer to create animations. For future viewers of this question, here is a short program that I encoded in about 5 minutes, sorry dirty code.

I 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. } } 
+4
source share
2 answers

Jimmy, I think you don’t understand how the threads in Swing work. You should use a specific thread called Thread Dispatch Thread for any update to swing components (with some specific exceptions, which I will not discuss here). You can use the swing timer to set a recurring task to run in the event dispatch thread. See an example of using Swing timers. http://download.oracle.com/javase/tutorial/uiswing/misc/timer.html

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

Java also provides many methods for working with Swing in the SwingUtilities class, in particular invokeLater and invokeAndWait , which will run code in the event dispatch stream.

+8
source

So far, it's good to understand EDT and SwingUtilities (everyone does that Swing should do this), if you are going to do a lot of animation, I would recommend using TimingFramework . This will allow you to concentrate a little on the design and give you better control over the β€œspeed”. By default, the temporary structure uses a Swing timer, so callbacks are on the EDT. As part of a collection of clients rich in dirty, the author made a chapter.

Good luck

+1
source

All Articles