I am very new to animation in Swing, and I'm having a problem understanding the best way to implement a pause button.
I have implemented a class which extends JPanel and which uses a Timer to do some animation. When the Timer calls actionPerformed(), a call to repaint() is made. In the paintComponent() method I am simply drawing random shapes which change each time, so the whole panel animates.
I have placed an instance of the animated JPanel into a JFrame, alongside a JButton which can be used to pause the animation. The pause button has an ActionListener registered to it - the actionPerformed() method of which will call a pause() method on the animation panel which looks like this:
This works fine...unless the animation is running with a very fast small ms delay. When this happens the pause button will not respond all the time - the faster the animation runs, the less chance you have to actually get the pause button to do anything. Am I correct to presume this is to do with both the animation repainting and the pause action running on the EDT, so the user never gets enough time to actually cause the button's actionPerformed() to be called?
I have read about the concept of the worker thread, which seems like something I might use for the animation so that the pause button will be responsive, but I don't understand how to get a non EDT thread to actually drive the animation - i.e. how can I get another thread to repaint() the panel? Or is there a proper way to do this with the Timer?
Does anyone have any pointers, or links to tutorials which might set me off on the right track please?
What timer are you using? - is it the one in the swing package or the util package.
I assume by that fact you have mentioned an actionPerformed() method it's the swing package Timer. This timer uses the EDT to run the actionPerformed code which calls repaint() which causes an event to be placed on the event queue to repaint the GUI. This event is run on the EDT which makes the call to paintComponent(). If this cycle takes longer than the timer's time delay then your GUI is going to become very unresponsive.
If the actionPerformed method does any time consuming computation then you may get a little benefit by switching to a java.util.Timer (any thread can call repaint()).
If you can reduce the time taken to redraw the panel eg by pre-compute some of the image drawing etc that will also help but whatever you do the GUI is going to become increasingly unresponsive as the redraw time approaches the time delay.
Can you show your paintComponent() method so we can see what it is doing.