我尝试过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++;
}
}
答案 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();
}
}
}