[英]I want to add timer in my applet
我制作了CountDown.java文件,并尝试将我的Word-trouble.java文件(它是主小程序)添加为CountDown ct = new CountDown();
但是它没有在主小程序中显示计时器。
这是编码:
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);
}
}
我看到很多程序员在犯一个错误:您将经过时间的计算与刷新时间的计算混淆了。 如果由于线程争用而使睡眠时间长于一秒钟,那么您的计时器将漂移。
只需记录开始时间,而不是跟踪每秒钟递增的计数器:
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! 如果您的系统运行良好,则这将非常接近1000ms,但比考虑到(1)可能由线程争用引起的线程启动延迟以及(2)此循环的处理时间(即相当小)。 无论如何,以这种方式计算睡眠时间将防止计时器漂移,并确保您的显示值随着秒值的变化而更新。
请参阅我的网站上有关计时器常见误解的扩展讨论。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.