如何延迟一会儿循环?

时间:2019-01-30 12:59:08

标签: java loops while-loop

我尝试过Tread.sleep,但是它会延迟整个程序,而不仅仅是循环。我想在SFrame中画一条线,但我希望它慢慢画线。

 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++;

        }

    } 

1 个答案:

答案 0 :(得分:4)

您误解了Graphics的工作方式。您不能简单地通过稍后绘图来“延迟”渲染。这将延迟您的渲染线程,或者根本无法在屏幕上渲染。

这样做的原因是,在完成渲染之前,所有重新绘制的组件的绘制都需要完成。但是,如果您逐渐画线,则整个过程将等待,直到循环终止,程序才能继续(并显示该线)。将绘制方法想像成相机的快门。您可以快速拍照,而不是视频。因此,要“移动”或缓慢绘制某些内容,您需要依次放置很多图片,例如在电影中。

您真正想要的是定期重新绘制面板(您需要帧速率)。 因此,例如,如果您想以每秒接近30帧的速度进行渲染,则可以执行以下操作:

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

但是我建议使生产线的增长基于时间:

    ...

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