简体   繁体   中英

How do I delay just an while loop?

I have tried Tread.sleep but it delays the whole program and not just the loop. I want to draw a line in an SFrame, but I want it to draw the line slowly.

 public class Panel extends javax.swing.JPanel  
{  
    int a=0;
    int b=0;
    public void paint(java.awt.Graphics g) 
    {     
        g.setColor(Color.GREEN);  
        g.fillRect(0,0,500,500); 
        g.setColor(Color.BLACK);  

        while( a<=500&&b<=500){
            g.fillRect(a,b,5,5);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ie) {}               
            a++;
            b++;

        }

    } 

You misinterpret the way Graphics works. You cannot simply 'delay' the rendering by drawing something later. That would either delay your rendering thread, or not be rendered on the screen at all.

The reason for this is that the drawing of all your repainted components needs to be complete, before the rendering is done. However, if you incrementally draw the line, the entire process will wait until the loop is terminated for the program to continue (and the line to be shown). Think of the draw method as the shutter of a camera. You make a quick picture, not a video. So for something to 'move' or draw slowly, you need to put a lot of pictures in sequence, like in a movie.

What you actually want is to redraw your Panel periodically (you need a frame-rate). So for instance, if you wanted to render with something close to 30 frames a second, you could do:

public class AutoUpdatedPanel extends javax.swing.JPanel {
    Thread t;
    float linePercent = 0f;

    public AutoUpdatedPanel () {
        t = new AutoUpdateThread();
        t.start();
    }

    public void paint(java.awt.Graphics g) {     
        g.setColor(Color.GREEN);  
        g.fillRect(0, 0, 500, 500); 
        g.setColor(Color.BLACK);  

        int linePos = (int) 5 * linePercent;
        g.fillRect(linePos, linePos, 5, 5);
    }

    public class AutoUpdateThread extends java.lang.Thread {
        public void run() {
            while (!isInterrupted()) {
                try {
                    Thread.sleep(33);
                } catch (InterruptedException e) {
                    // silent.
                }
                linePercent += .5f;
                linePercent = math.min(linePercent, 100f);
                AutoUpdatedPanel.this.repaint();
            }
        }
    }
}

However I would advice to make the growth of the line time-based:

    ...

    public class AutoUpdateThread extends java.lang.Thread {
        public void run() {
            while (!isInterrupted()) {
                try {
                    Thread.sleep(33);
                } catch (InterruptedException e) {
                    // silent.
                }

                nowMillis = Calendar.newInstance().getTimeInMillis();
                long timeOffset = nowMillis - start;
                linePercent = (float) (.002d * timeOffset);
                linePercent = math.min(linePercent, 100f);
                AutoUpdatedPanel.this.repaint();
            }
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM