First of all here are some code snippets:
public void startThread() { this.animationThread = new Thread(this); this.animationThread.start(); try { this.animationThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public void run() { pirateMainAnimation.animate(); } public void animate() { for (int j = 0; j < 9; j++) { try { Thread.sleep(250); } catch (InterruptedException e) { break; } PirateAnimationPanel.getInstance().setCurrent(j); PirateAnimationPanel.getInstance().repaint(); } } I'm trying to animate some images. The thing is that I want the main thread to wait for the animation thread to finish and then to continue. I searched around, read a little bit and decided to use the join() method. It perfectly waits for the thread to finish but I doesn't animate correctly. The repaint() method gets called 2 times instead of nine. I think maybe the problem is because I used singletons. Here is the singleton implementation.
import java.awt.Graphics; import java.awt.MediaTracker; import javax.swing.JPanel; import uk.ac.aber.dcs.piratehangman.animation.PirateMainAnimation; import uk.ac.aber.dcs.piratehangman.utilityclasses.AnimationThread; @SuppressWarnings("serial") public class PirateAnimationPanel extends JPanel { private int current; private MediaTracker mTracker; private PirateMainAnimation pirateMainAnimation; private AnimationThread animationThread; private PirateAnimationPanel() { this.current = 0; this.pirateMainAnimation = new PirateMainAnimation(); mTracker = new MediaTracker(this); this.animationThread = new AnimationThread(); setMediaTracker(); repaint(); } private void setMediaTracker() { for (int i = 0; i < 9; i++) { mTracker.addImage( this.pirateMainAnimation.getImagesForAnimation()[i], this.pirateMainAnimation.getImagesForAnimationID()[i]); try { mTracker.waitForID(this.pirateMainAnimation .getImagesForAnimationID()[i]); } catch (InterruptedException e) { System.out.println("Error loading image: " + i); } } } public void playAnimation() { this.animationThread.startThread(); } public void paintComponent(Graphics g) { super.paintComponents(g); System.out.println("called"); g.drawImage(this.pirateMainAnimation.getImagesForAnimation()[current], 0, 0, this); } private static class PirateAnimationPanelHolder { private static final PirateAnimationPanel pirateAnimationPanel = new PirateAnimationPanel(); }; public static PirateAnimationPanel getInstance() { return PirateAnimationPanelHolder.pirateAnimationPanel; } public void setCurrent(int current) { this.current = current; } public int getCurrent() { return current; } }