Time Delay using Thread.sleep() for paintComponent(Graphics g) not working as expected
event-dispatch-thread, java, paintcomponent, progress-bar, swing
Solution
Don't block the EDT (Event Dispatch Thread) - the GUI will 'freeze' when that happens. Instead of calling `Thread.sleep(n)` implement a Swing `Timer` for repeated tasks. See Concurrency in Swing for more details. Also be sure to check the progress bar tutorial linked by @Brian. It contains working examples.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class DrawPanel extends JPanel
{
int i = 0;
public DrawPanel() {
ActionListener animate = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
repaint();
}
};
Timer timer = new Timer(50,animate);
timer.start();
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(new Color(71,12,3));
g.fillRect(35,30,410,90);
Color c = new Color (12*i/2,8*i/2,2*i/2);
g.setColor(c);
g.fillRect( 30+10*i,35,20,80);
i+=2;
if (i>40) i = 0;
}
}
class ProgressBar
{
public static void main (String []args)
{
DrawPanel panel = new DrawPanel();
JFrame app = new JFrame();
app.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
app.add(panel);
app.setSize(500,200);
app.setVisible(true);
}
}
Problem
I am making an Animated ProgressBar, in which i used multiple `fillRect()` method of class `javax.swing.Graphics`. To put a delay after each rectangle is painted, I am using `Thread.sleep(500)` method for making a delay, (Suggested by many Forums, for making a delay). The Problem is, instead of making a delay of 0.5sec after each Rectangle box is displayed, it takes the whole delay required by all the rectangles, in the start, and then displays the final image, thats the Progress Bar. Question 1 TO make a delay for every single bar, i put the delay "`Thread.sleep(500)`" along with the bars "`fillRect()`" in a single `for() loop`, i would like to know, Why does it takes all the delay in the beginning and then dislplays the completed ProgressBar. Question 2 How can i change my code, so that the delay can occur simultaneously with each rectangle bar, so when i run the program it should generate an Animated Progress Bar. Code: ``` import javax.swing.JOptionPane; import java.awt.Graphics; import javax.swing.JFrame; import javax.swing.JPanel; import java.awt.Color; class DrawPanel extends JPanel { public paintComponent(Graphics g) { super.paintComponent(g); g.setColor(new Color(71,12,3)); g.fillRect(35,30,410,90); for ( int i=1; i<=40; i+=2) { Color c = new Color (12*i/2,8*i/2,2*i/2); g.setColor(c); g.fillRect( 30+10*i,35,20,80); try { Thread.sleep(500); } catch(InterruptedException ex) { Thread.currentThread().interrupt(); } } } } class ProgressBar { public static void main (String []args) { DrawPanel panel = new DrawPanel(); JFrame app = new JFrame(); app.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); app.add(panel); app.setSize(500,200); app.setVisible(true); } } ``` Your help is highly appreciated, Thankyou.