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

Java 我想在小程序中添加计时器,java,swing,timer,applet,awt,Java,Swing,Timer,Applet,Awt,我制作了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 imple

我制作了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();
}
请注意,您不睡眠1000毫秒!如果您的系统运行良好,这将非常接近1000ms,但略小于1000ms,以说明(1)线程启动延迟(可能由线程争用引起)和(2)此循环的处理时间(非常小)。在任何情况下,以这种方式计算睡眠将防止计时器漂移,并确保您的显示会随着秒值的变化而更新


请参阅我的网站上的扩展讨论。

1)不要尝试将小程序添加到其他小程序。这是可以做到的,但不是最好的方法,在这里完全没有必要。相反,将其更改为
公共类倒计时扩展JPanel
2)…这让我想到了。对于第三个千年的GUI,使用Swing而不是AWT组件。3) 在
JPanel
中,覆盖
paintComponent(Graphics)
,而不是
paint(Graphics)
。4) 不要阻止EDT(事件调度线程)-发生这种情况时,GUI将“冻结”。不要调用
Thread.sleep(n)
实现一个Swing
计时器来重复任务。对于挥杆初学者来说,See是一个鲜为人知的概念。希望它是java中GUI 101的一部分。请编辑你的问题并格式化代码,使其可读。考虑<代码> javax。Swing。