views:

111

answers:

5

I am working on a Java program which contains a lot of animations as part of the UI. Each animation requires a repaint method to be called in order to make the animation happen. I was just wondering if it was good programing to use a separate thread for each animation, which would each call their respective repaint methods.

+1  A: 

No, because the overhead of all those threads would make the process inefficient.

Steven Sudit
+1  A: 

I am assuming you're using Swing? I'm not certain though.

I would suggest reading http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html , and searching for more information about threads in Swing. In general, the only thread that should update the GUI should be the Event Dispatch thread, though there are a few exceptions.

I think using threads is fine, just ask the Event Dispatch thread to update your UI,

i.e

    java.awt.EventQueue.invokeLater(new Runnable()
    {

        public void run()
        {
            //this codes runs on the event dispatch thread
        }
    });
Andy Pryor
Note: `SwingUtilities` has its own `invokeLater` command. I assume it just forwards to the `EventQueue` version, but I'm not positive... but it allows you to use it without having to type out `EventQueue`'s package or import it even if it doesn't, since you're likely importing javax.swing already.
R. Bemrose
+2  A: 

No. Or yes, depending on what you are doing.

In general only the SwingEvent thread should draw to the screen, usually in response to a repaint(). However it may be OK to have a different thread for each animation to calculate the bitmap that should be drawn for each animation, but not draw it, and then trigger the SwingEvent thread to actually draw it. That doesn't make sense if the animations are all synchronous with each other, or if the amount of calculation involved is trivial.

If you have a LOT of threads there is going to be a performance penalty. I don't know what that penalty is going to be for your application - you'll have to experiment if you really want to know.

Remember that multiple threads will be more complicated to program (compared with having one thread do the work sequentially) and that having more threads (above the number of cores your CPU has) almost never allows more work to done in a given time.

DJClayworth
This is a good answer. Sounds like it might make sense to have a single thread cranking away in the background to generate frames in advance of their display.
Steven Sudit
A: 

For swing it would be best to use one (or more) javax.swing.Timer(s). Let the timer call repaint on all your components needing an update (animation). You could make one custom timer that let's you add/remove components. But be careful with all the involved threads. (You don't want deadlock/synchronization issues.) All the timers use the same thread for waiting and run the code on the event dispatching thread.

Ishtar
A: 

I know I've seen some frameworks which do this exact thing, check out JGoodies animation library; I think that's where I saw it.

Generally the idea is to minimize the number of threads (assuming animation updates are quick, like switching to an already loaded picture), you could create an animation client interface which a single animation thread invokes an update method on the EDT for all clients needing it:

public interface AnimatedComponent {
 public int getInterval(); // how many milliseconds between frames
 public long getLastUpdateTime();
 public void updateAnimation(); // invoked within the swing EDT 
}

Whenever you add an animated component you should register it with a central animation thread which walks the list of AnimatedComponent(s), invoking updateAnimation when needed.

public void updateAllAnimations() {
 long nowTime = System.currentTimeMillis();
 for (AnimatedComponent c : someList) {
  if (c.getLastUpdateTime() - nowTime >= c.getInterval()) {
   c.updateAnimation();
   c.repaint();
  }
 }
}

You should schedule this on the swing EDT from a timer thread periodically (2-3 times per second, depending on how rapidly your animation is expected to update).

Justin