Time Delay using Thread.sleep() for paintComponent(Graphics g) not working as expected

情到浓时终转凉″ 提交于 2020-11-29 02:11:12

问题


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.


回答1:


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);
    }
}



回答2:


I really wouldn't do this. The Swing refresh thread isn't supposed to be used like this. You're much better off using another thread (perhaps using a TimerTask) and redrawing rectangles upon demand.

Check out the Oracle ProgressBar tutorial for more info, code etc.



来源:https://stackoverflow.com/questions/13414164/time-delay-using-thread-sleep-for-paintcomponentgraphics-g-not-working-as-ex

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!