我想在我的applet中添加计时器

时间:2012-12-01 09:38:39

标签: java swing timer applet awt

我创建了CountDown.java文件并尝试将我的Word-trouble.java文件(主applet)添加为CountDown ct = new CountDown(); 但它没有在主applet中显示计时器。

以下是编码:

package pack.urdu;
import java.awt.*; //windows toolkit

import java.applet.*; //applet support

public class CountDown extends Applet implements Runnable{

int counter; Thread cd;

public void start() { // create thread

counter = 60; cd = new Thread(this); cd.start();

}

public void stop() { cd = null;}

public void run() {  // executed by Thread

while (counter>0 && cd!=null) {

try{Thread.sleep(1000);} catch (InterruptedException e){}

--counter; repaint(); //update screen

}

}

public void paint(Graphics g) {

g.drawString(String.valueOf(counter),25,75);

}

}

1 个答案:

答案 0 :(得分:0)

我犯了一个错误,我看到很多程序员犯了错误:你正在计算经过的时间,计算刷新时间。如果由于线程争用而导致睡眠持续时间超过一秒,则计时器将漂移。

不是跟踪每秒递增的计数器,而是记录开始时间:

long startTime = System.currentTimeMillis();

然后,您的绘画方法变为:

public void paint(Graphics g) {
    int elapsedSeconds = (int)(System.currentTimeMillis()-startTime)/1000
    g.drawString(String.valueOf(elapsedSeconds),25,75);
}

此方法可以经常调用,也可以根据需要多次调用,并且始终显示正确的经过秒数。无需在任何指定时间增加任何内容。

您唯一需要做的就是安排刷新屏幕。 (我想说你只需要在用户查看它时刷新屏幕:-)但是因为我们不知道我们需要更频繁地更新)。其机制可能取决于图形库。一个懒惰的想法是每秒刷新十次,屏幕大部分时间都是正确的。

如果您确实希望有一个发送重绘事件的线程,那么您应该在计时器点击一个新值时发送这些事件,从而每秒只发送一个。这完成了:

while (stillRunning) {
    long elapsedTime = System.currentTimeMillis() - startTime;
    long timeTillNextDisplayChange = 1000 - (elapsedTime % 1000);
    Thread.sleep(timeTillNextDisplayChange);
    repaint();
}

请注意,你不会睡1000ms!如果你的系统运行良好,这将非常接近1000毫秒,但略小于(1)线程启动延迟(可能由线程争用引起)和(2)此循环的处理时间(这是相当小)。在任何情况下,以这种方式计算睡眠将防止计时器漂移,并确保您的显示更新就像秒值更改一样。

请参阅我网站上对Common Misunderstandings of Timers的扩展讨论。