`
thinkingmt
  • 浏览: 23705 次
  • 性别: Icon_minigender_1
  • 来自: 桂林
社区版块
存档分类
最新评论

About"Timer" & "Calendar"

阅读更多

这个星期做了一个简单的计时器,这个计时器可以获得当前的系统时间,并计时。

 

主要用到了java.util.Calendar 和 java.util.Timer 这两个类,这两个类非常实用,计时器这个程序也可以应用的很广,比如很多游戏需要计时(扫雷),测试也需要计时。

 

第一个类代码如下:

 

/**
 * The NumberDisplay class represents a digital number display that can hold
 * values from zero to a given limit. The limit can be specified when creating
 * the display. The values range from zero (inclusive) to limit-1. If used,
 * for example, for the seconds on a digital clock, the limit would be 60, 
 * resulting in display values from 0 to 59. When incremented, the display 
 * automatically rolls over to zero when reaching the limit.
 * 
 * @author Michael Kolling and David J. Barnes
 * @version 2006.03.30
 */
public class NumberDisplay
{
    private int limit;
    private int value;

    /**
     * Constructor for objects of class NumberDisplay.
     * Set the limit at which the display rolls over.
     */
    public NumberDisplay(int rollOverLimit)
    {
        limit = rollOverLimit;
        value = 0;
    }

    /**
     * Return the current value.
     */
    public int getValue()
    {
        return value;
    }

    /**
     * Return the display value (that is, the current value as a two-digit
     * String. If the value is less than ten, it will be padded with a leading
     * zero).
     */
    public String getDisplayValue()
    {
        if(value < 10) {
            return "0" + value;
        }
        else {
            return "" + value;
        }
    }

    /**
     * Set the value of the display to the new specified value. If the new
     * value is less than zero or over the limit, do nothing.
     */
    public void setValue(int replacementValue)
    {
        if((replacementValue >= 0) && (replacementValue < limit)) {
            value = replacementValue;
        }
    }

    /**
     * Increment the display value by one, rolling over to zero if the
     * limit is reached.
     */
    public void increment()
    {
        value = (value + 1) % limit;
    }
}

 

 

这个类中,对于我来说比较难想到的是 increment()这个方法,value = (value + 1) % limit; 能够很好的利用limit(区间)去判断时间是否需要进为0。

 

另外一个类:

 

import java.util.Calendar;
/**
 * The ClockDisplay class implements a digital clock display for a
 * European-style 24 hour clock. The clock shows hours and minutes. The 
 * range of the clock is 00:00 (midnight) to 23:59 (one minute before 
 * midnight).
 * 
 * The clock display receives "ticks" (via the timeTick method) every minute
 * and reacts by incrementing the display. This is done in the usual clock
 * fashion: the hour increments when the minutes roll over to zero.
 * 
 * @author Michael Kolling and David J. Barnes
 * @version 2006.03.30
 */
public class ClockDisplay
{
    private NumberDisplay hours;
    private NumberDisplay minutes;
    private NumberDisplay seconds;
    private String displayString;    // simulates the actual display
    
    /**
     * Constructor for ClockDisplay objects. This constructor 
     * creates a new clock set at 00:00.
     */
    public ClockDisplay()
    {
        hours = new NumberDisplay(24);
        minutes = new NumberDisplay(60);
        seconds = new NumberDisplay(60);
        updateDisplay();
    }

    /**
     * Constructor for ClockDisplay objects. This constructor
     * creates a new clock set at the time specified by the 
     * parameters.
     */
    public ClockDisplay(int hour, int minute,int second)
    {
        hours = new NumberDisplay(24);
        minutes = new NumberDisplay(60);
        seconds = new NumberDisplay(60);
        setTime(hour, minute, second);
    }

    /**
     * This method should get called once every minute - it makes
     * the clock display go one minute forward.
     */
    public void timeTick()
    {
        seconds.increment();
        if(seconds.getValue()==0)
        {
            minutes.increment();
        if(minutes.getValue() == 0) 
        {// it just rolled over!
            hours.increment();
        }
        }
         updateDisplay();
    }

    /**
     * Set the time of the display to the specified hour and
     * minute.
     */
    public void setTime(int hour, int minute, int second)
    {
        hours.setValue(hour);
        minutes.setValue(minute);
        seconds.setValue(second);
        updateDisplay();
    }

    /**
     * Return the current time of this display in the format HH:MM.
     */
    public String getTime()
    {
        return displayString;
    }
    
    /**
     * Update the internal string that represents the display.
     */
    private void updateDisplay()
    {
        displayString = hours.getDisplayValue() + ":" + 
                        minutes.getDisplayValue()+":"+seconds.getDisplayValue();
    }
    
    public void getCurrentTime()
    {
        Calendar rightNow = Calendar.getInstance();
        int hour=rightNow.get(Calendar.HOUR_OF_DAY);
        int minute=rightNow.get(Calendar.MINUTE);
        int second=rightNow.get(Calendar.SECOND);
        
        setTime(hour,minute,second);
    }
}

 

这个类中运用了Calendar的对象rightNow来获得当前系统时间。

 

Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEARMONTHDAY_OF_MONTHHOUR日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。瞬间可用毫秒值来表示,它是距历元(即格林威治标准时间 1970 年 1 月 1 日的 00:00:00.000,格里高利历)的偏移量。

 

与其他语言环境敏感类一样,Calendar 提供了一个类方法 getInstance,以获得此类型的一个通用的对象。CalendargetInstance 方法返回一个 Calendar 对象,其日历字段已由当前日期和时间初始化:

     Calendar rightNow = Calendar.getInstance();

 

 

还有最后一个gui的类:

 

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class ShowTime extends JFrame
{
    private JButton start = new JButton("Start");
    private JButton stop = new JButton("Stop");
    private JLabel show= new JLabel();
    private ClockDisplay ck= new ClockDisplay();
    private java.util.Timer time;
    
    public ShowTime()
    {
        makeFrame();
        makeFunction();
    }
    
    private void makeFrame()
    {
        Container con= getContentPane();
        con.setLayout(new BorderLayout());
        
        JPanel center= new JPanel();
        center.add(show);
        con.add(center,BorderLayout.CENTER);
        ck.getCurrentTime();
        show.setText(ck.getTime());
        
        JPanel south= new JPanel();
        south.setLayout(new FlowLayout());
        south.add(start);
        south.add(stop);
        con.add(south,BorderLayout.SOUTH);
        
        setSize(300,200);
        setVisible(true);
    }
    
    private void makeFunction()
    {
        start.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e)
            {
                if(time ==null)
                {
                    time = new java.util.Timer();
                    time.schedule(new MyTimerTask(),1000,1000);
                }
               
            }
        });
        
       stop.addActionListener(new ActionListener(){
           public void actionPerformed(ActionEvent e)
            {
                if(time!=null)
                {
                    time.cancel();
                    time=null;
                }
            }
        });
    }
    
    private class MyTimerTask extends TimerTask
    {
        public void run()
        {
            ck.timeTick();
            show.setText(ck.getTime());
        }
    }
}

 

 

Timer:一种工具,线程用其安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。

 

 void schedule(TimerTask task, long delay, long period)
          安排指定的任务从指定的延迟后开始进行重复的固定延迟执行

 

TimerTask是一个抽象类,所以需要自己写一个TimerTask的子类:MyTimerTask,其中run()是抽象的,所以这个方法需要重写,这个方法中运行的,也就是我们所期望的重复地按固定延迟推进时间,其实也就是:每隔一秒钟,执行以下代码:

 

ck.timeTick();//ck是ClockDisplay的对象。
show.setText(ck.getTime());

 

 

运行效果如下:

 

 

与系统时间: 是一致的。

 

但在初期,Start的actionPerformed()中如果不对time进行判断,会造成连续点击Start计时加速的问题,而且不能通过点击相同次数的Stop来停止。

 

利用JButton的setEnabled(boolean b)来对Start,Stop的点击进行限制而避免此问题,或者:如我的代码中一样,通过if的判断来保证只有一个time在执行任务(这不是singleton)。

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics