简体   繁体   English

我想在小程序中添加计时器

[英]I want to add timer in my applet

I made CountDown.java file and try to add in my Word-trouble.java file (which is main applet) as CountDown ct = new CountDown(); 我制作了CountDown.java文件,并尝试将我的Word-trouble.java文件(它是主小程序)添加为CountDown ct = new CountDown(); but it is not showing timer in main applet. 但是它没有在主小程序中显示计时器。

Here is coding: 这是编码:

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

}

}

You are making a mistake that I see a lot of programmers make: you are mixing up the calculation of elapsed time, with the calculation of the refresh time. 我看到很多程序员在犯一个错误:您将经过时间的计算与刷新时间的计算混淆了。 If the duration of sleep takes long than a second because of thread contention, your timer will drift. 如果由于线程争用而使睡眠时间长于一秒钟,那么您的计时器将漂移。

Instead of tracking a counter that increments every second, just record the start time: 只需记录开始时间,而不是跟踪每秒钟递增的计数器:

long startTime = System.currentTimeMillis();

Then later, your paint method becomes: 然后,您的绘制方法变为:

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

This method can be called as often, and as many times as you like, and it will always display the correct elapsed seconds. 您可以根据需要多次调用此方法,并且可以始终显示正确的经过的秒数。 There is no need to increment anything at any specified time. 无需在任何指定时间增加任何内容。

The only other thing you have to do is to arrange that the screen gets refreshed. 您唯一要做的另一件事就是安排屏幕刷新。 (I like to say that you only have to refresh the screen when the user looks at it :-) but since we don't know that we need to refresh more often). (我想说的是,您只需要在用户查看屏幕时刷新屏幕即可:-),但是由于我们不知道我们需要更频繁地刷新屏幕)。 The mechanism for this may depend upon the graphic library. 其机制可能取决于图形库。 One lazy idea is to refresh ten times a second and the screen will be right most of the time. 一个懒惰的想法是每秒刷新十次,并且在大多数情况下屏幕都是正确的。

If you do want to have a thread that sends repaint events, you should have those events sent just at the time that timer clicks over to a new value, and thereby send only one per second. 如果确实希望有一个线程发送重绘事件,则应在计时器单击新值时发送这些事件,从而每秒仅发送一个。 This is done with: 这是通过以下方式完成的:

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

Note that you do not sleep 1000ms! 请注意,您不要睡1000ms! If your system is performing well, this will be very close to 1000ms, but slightly less than that to account for (1) the thread startup delay, possibly caused by thread contention, and (2) the processing time for this loop (which is quite small). 如果您的系统运行良好,则这将非常接近1000ms,但比考虑到(1)可能由线程争用引起的线程启动延迟以及(2)此循环的处理时间(即相当小)。 In any case, calculating the sleep in this way will prevent timer drift, and assure that your display updates just as the seconds value changes. 无论如何,以这种方式计算睡眠时间将防止计时器漂移,并确保您的显示值随着秒值的变化而更新。

See an extended discussion of Common Misunderstandings of Timers on my website. 请参阅我的网站上有关计时器常见误解的扩展讨论。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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