Never use Thread.sleep() when code is executing on the Event Dispatch Thread.
Instead you should use a Swing Timer to schedule your animation.
See the sections from the Swing tutorial on:
- Concurrency in Swing
- How to Use Timers
Or if you don’t want to use a Timer, then you can use a SwingWorker (as described in the tutorial on concurrency) and then just publish() the image after you change it. Then you can use a Thread.sleep() since the SwingWorker doesn’t execute on the EDT.
Simple Timer example:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;
public class TimerTime extends JPanel implements ActionListener
{
private JLabel timeLabel;
private int count = 0;
public TimerTime()
{
timeLabel = new JLabel( new Date().toString() );
add( timeLabel );
Timer timer = new Timer(1000, this);
timer.setInitialDelay(1);
timer.start();
}
@Override
public void actionPerformed(ActionEvent e)
{
// Update the time
timeLabel.setText( new Date().toString() );
count++;
// Stop after 10 events have been generated
if (count == 10)
{
Timer timer = (Timer)e.getSource();
timer.stop();
System.out.println( "Timer stopped" );
}
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("TimerTime");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new TimerTime() );
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater( () -> createAndShowGUI() );
}
}