昨天刚转载了《实现自己的事件》一文,由于源代码生成了一个窗口,为了简化理解,我就试图修改程序,不让生成窗口,直接在控制台输出时间,结果遇到了麻烦,程序没有显示就终止了。经过仔细分析javax.swing.Timer类,终于找出了原因。
Timer的构造函数 public Timer(int delay, ActionListener listener)
构造 Timer
时要指定一个延迟参数delay和一个 ActionListener
。延迟参数用于设置初始延迟和事件触发之间的延迟(以毫秒为单位)。启动了计时器后,它将在向已注册侦听器触发第一个 ActionEvent
之前等待初始延迟。第一个事件之后,每次超过事件间延迟时它都继续触发事件,直到被停止。红字部分说明第一次监听之前会有延迟,因此代码中我加了一句 Thread.currentThread().sleep(1200),这里参数建议大于1100。
下面是修改后的代码:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import java.util.Iterator;
import java.util.Vector;
import javax.swing.Timer;
/**
* 定时器事件,属性可以保存有用的信息,包括事件源
* @author Administrator
*/
class TimerEvent{
private TimerEventSource source;//事件源
private String time;//当前时间
public TimerEvent(TimerEventSource source,String time){
this.source=source;
this.time=time;
}
public Object getSource(){
return this.source;
}
public String getTime(){
return this.time;
}
}
/**
* 定时器事件源接口,可以添加、删除定时器事件监听器
* @author Administrator
*/
interface TimerEventSource {
public void addTimerListener(TimerListener tl);
public void removeTimerListener(TimerListener tl);
}
/**
* 定时器事件源具体的实现类。当时间到时激活监听器,调用所有监听器的回调方法回调方法
* @author Administrator
*/
class ConcretEventSource implements TimerEventSource{
private Timer timer;
//监听器队列,保存所有注册的监听器
private Vector<TimerListener> eventQueue=new Vector();
public ConcretEventSource(int timeGap){
timer=new Timer(timeGap,new ActionListener(){
public void actionPerformed(ActionEvent e) {
//当时间到时,激活监听器
fireTimeUp();
}
});
timer.start();
}
public void addTimerListener(TimerListener tl) {
eventQueue.add(tl);
}
public void removeTimerListener(TimerListener tl) {
eventQueue.remove(tl);
}
private void fireTimeUp(){
Iterator<TimerListener> iter=eventQueue.iterator();
TimerListener tl;
/*System.out.println(eventQueue.size()); 其实这里eventQueue.size()始终是1*/
while(iter.hasNext()){
tl=iter.next();
//回调监听器的方法,进行时间处理
tl.timeUp(new TimerEvent(this,new Date().toString()));
}
}
}
/**
* 定时器事件监听接口
* @author Administrator
*/
interface TimerListener {
//当时间到时,进行处理
public void timeUp(TimerEvent e);
}
/**
*
* @author Administrator
*/
public class Test implements TimerListener{
public Test(){
}
public void timeUp(TimerEvent e) {
System.out.println(e.getTime());
}
public static void main(String[] args) throws InterruptedException {
// TODO code application logic here
ConcretEventSource s=new ConcretEventSource(1000);
Thread.currentThread().sleep(1200);
s.addTimerListener(new TimerListener(){
public void timeUp(TimerEvent e) {
System.out.println(e.getTime());
}
});
}
}