zoukankan      html  css  js  c++  java
  • java swing中Timer类的学习

    最近在完成学校课程的java平时作业,要实现一个计时器,包含开始、暂停以及重置三个功能。由于老师规定要用这个timer类,也就去学习了一下,顺便记录一下。

    首先呢去查了一下java手册上的东西,发现timer的构造函数是这么解释的(拿翻译机翻译了)

    public class Timer
          extends 
          Object
         
          implements 
          Serializable
         

    在指定时间间隔触发一个或多个 ActionEvent。一个示例用法是动画对象,它将 Timer 用作绘制其帧的触发器。

    设置计时器的过程包括创建一个 Timer 对象,在该对象上注册一个或多个动作侦听器,以及使用 start 方法启动该计时器。例如,以下代码创建并启动一个每秒(该时间由 Timer 构造方法的第一个参数指定)触发一次动作事件的计时器。Timer 构造方法的第二个参数指定接收计时器动作事件的侦听器。

    int delay = 1000; //milliseconds
      ActionListener taskPerformer = new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
              //...Perform a task...
          }
      };
      new Timer(delay, taskPerformer).start();

    构造 Timer 时要指定一个延迟参数和一个 ActionListener。延迟参数用于设置初始延迟和事件触发之间的延迟(以毫秒为单位)。启动了计时器后,它将在向已注册侦听器触发第一个 ActionEvent 之前等待初始延迟。第一个事件之后,每次超过事件间延迟时它都继续触发事件,直到被停止。

    构造之后,可以单独更改初始延迟和事件间延迟,并且可以添加其他 ActionListener

    如果希望计时器只在第一次时触发然后停止,可以对计时器调用 setRepeats(false)

    尽管所有 Timer 都使用一个共享线程(由第一个执行操作的 Timer 对象创建)执行等待,但是 Timer 的动作事件处理程序还会在其他线程(事件指派线程上)执行。这意味着 Timer 的操作处理程序可以安全地在 Swing 组件上执行操作。但是,它也意味着处理程序必须快速执行以保证 GUI 作出响应。

    在 1.3 版本中,向 Java 平台添加了另一个 Timer 类:java.util.Timer。该类和 javax.swing.Timer 的基本功能相同,但是 java.util.Timer 更常用,功能更多。javax.swing.Timer 有两个特征,它们可以让使用 GUI 更方便。首先,其事件处理程序都是 GUI 程序员所熟悉的,并且可以更简单地处理事件指派线程。第二,其自动线程共享意味着不必采取特殊步骤来避免生成过多线程。相反,计时器使用同一个线程让光标闪烁、使工具提示显示等等。

    通过查看 The Java Tutorial 中的 How to Use Timers 一节,可以找到使用计时器的更详细的文档和几个示例。有关在此 Timer 类和 java.util.Timer 之间进行选择的更多示例和帮助信息,请参阅 The Swing Connection 中的 Using Timers in Swing Applications 一文。

    警告:此类的序列化对象与以后的 Swing 版本不兼容。当前序列化支持适用于短期存储,或适用于在运行相同 Swing 版本的应用程序之间进行 RMI(Remote Method Invocation,远程方法调用)。从 1.4 版本开始,已在 java.beans 包中添加了支持所有 JavaBeansTM 长期存储的功能。请参阅 XMLEncoder

    另请参见:
    java.util.Timer

    从上面实例+解释可以很容易学会timer的调用。

    看完上面的,也有了一个初步的了解,当注册一个timer对象以后,如果开发者令其start,那么这个定时器就会每隔设定的delay去调用开发者写的actionPerformed方法。也就是说,这个计时器本身就是一个线程,这个线程每隔一定时间去调用监听函数。利用这一性质,就可以很容易的写出这个计时器了。感觉自己在看文档的时候,遇到了一些问题,调用了timer类还在不停的想着用循环来实现这个秒表计时器的计时功能,背道而驰了,导致出现了一些列的资源占用等问题

    。最后附上题目以及鄙人写的代码:

    题目

    实现代码如下:

     1 /*
     2  * #MainFrame.java文档
     3  */
     4 
     5 import javax.swing.*;
     6 
     7 public class MainFrame{
     8     public static void main(String[] args){
     9         JFrame frame = new JFrame("秒表");
    10         frame.getContentPane().add(new Time());
    11         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    12         frame.setVisible(true);
    13         frame.pack();
    14     }
    15 }
    View Code
      1 /*
      2  * #Time.java文档
      3  */
      4 import java.awt.*;
      5 import javax.swing.*;
      6 import javax.swing.Timer;
      7 import java.awt.event.*;
      8 
      9 public class Time extends JPanel implements ActionListener{
     10     /**
     11      * 反序列化
     12      */
     13     private static final long serialVersionUID = 1L;
     14     
     15     //定义三个按钮
     16     private JButton start, stop, reset;
     17     
     18     //定义一个标签用于显示
     19     private JLabel label;
     20     
     21     //定义一个timer用于计时
     22     private Timer timer;
     23     
     24     //flag变量,用于记录
     25     private int flag = 0;
     26     
     27     //时间参数
     28     private int hour = 0;
     29     private int minute = 0;
     30     private int second = 0;
     31     
     32     /*
     33      * 构造方法,用于创建计时器对象
     34      */
     35     public Time(){
     36         
     37         setBackground(Color.LIGHT_GRAY);
     38         setPreferredSize(new Dimension(800,600));
     39         setLayout(null);
     40          
     41         //数字显示
     42         label = new JLabel("00:00:00");
     43         label.setBounds(240, 120, 400, 80);
     44         label.setFont(new java.awt.Font("Dialog", 1, 72));
     45         add(label);
     46         
     47         JPanel p1 = new JPanel();
     48         p1.setBackground(Color.LIGHT_GRAY);
     49         p1.setBounds(240, 240, 300, 60);
     50         add(p1);
     51         
     52         start = new JButton("Start");
     53         start.setFont(new Font("SAN_SERIF",Font.BOLD,24));
     54         start.setBackground(Color.green);
     55         stop = new JButton("Stop");
     56         stop.setFont(new Font("SAN_SERIF",Font.BOLD,24));
     57         stop.setBackground(Color.red);
     58         reset = new JButton("Reset");
     59         reset.setFont(new Font("SAN_SERIF",Font.BOLD,24));
     60         reset.setBackground(Color.yellow);
     61         
     62         start.addActionListener(this);
     63         stop.addActionListener(this);
     64         reset.addActionListener(this);
     65         
     66         p1.add(start);
     67         p1.add(stop);
     68         p1.add(reset);
     69         
     70         timer = new Timer(1000, this);
     71         timer.start();
     72     }
     73     
     74     @Override
     75     public void actionPerformed(ActionEvent e) {
     76         // TODO Auto-generated method stub
     77         if(e.getSource() == reset){// 清除标签内容
     78             timer.stop();
     79             flag = 0;
     80             label.setText(resetTime());
     81             System.out.println(hour + ":" + minute + ":" + second);
     82         }
     83         else if(e.getSource() == start){
     84             flag = 1;
     85             label.setText(countTime());
     86             System.out.println(hour + ":" + minute + ":" + second);
     87             timer.restart();
     88         }
     89         else if(e.getSource() == stop){
     90             timer.stop();
     91             flag = 0;
     92             label.setText(stopTime());
     93             System.out.println(hour + ":" + minute + ":" + second);
     94         }
     95         else if(flag==1 && timer.isRunning()){
     96             label.setText(countTime());
     97             System.out.println(hour + ":" + minute + ":" + second);
     98         }
     99         else if(flag==0 && !timer.isRunning()){
    100             label.setText(stopTime());
    101             System.out.println(hour + ":" + minute + ":" + second);
    102         }
    103         
    104     }
    105     
    106     /*
    107      * 计时方法
    108      */
    109     public String countTime(){
    110         this.second += 1;
    111         if(this.second == 60){
    112             this.minute += 1;
    113             this.second = 0;
    114         }
    115         if(this.minute == 60){
    116             this.minute = 0;
    117             this.hour += 1;
    118         }
    119         
    120         String str = this.toString(this.hour, this.minute, this.second);
    121         return str;
    122     }
    123     
    124     /*
    125      * 暂停计时方法
    126      */
    127     public String stopTime(){
    128         String str = this.toString(this.hour, this.minute, this.second);
    129         return str;
    130     }
    131     
    132     /*
    133      * 重置计时方法
    134      */
    135     public String resetTime(){
    136         this.hour=0;
    137         this.minute=0;
    138         this.second=0;
    139         String str = this.toString(this.hour, this.minute, this.second);
    140         return str;
    141     }
    142     
    143     /*
    144      * 显示时间方法
    145      */
    146     public String toString(int hour, int minute, int second){
    147         String str1 = String.format("%02d", this.hour);
    148         String str2 = String.format("%02d", this.minute);
    149         String str3 = String.format("%02d", this.second);
    150         return (str1 + ":" + str2 + ":" + str3);
    151     }
    152     
    153 }
    View Code
  • 相关阅读:
    leecode 91. 解码方法
    leecode 166. 分数到小数
    剑指 Offer 31. 栈的压入、弹出序列
    leecode 386. 字典序排数
    LeetCode 311 稀疏矩阵的乘法
    leecode 89. 格雷编码
    leecode 79. 单词搜索
    leecode 207. 课程表
    QT -- 解决:Error: Could not decode "*.cpp" with "UTF-8"
    VS+QT -- 没有PRO文件的问题
  • 原文地址:https://www.cnblogs.com/sgatbl/p/7747572.html
Copyright © 2011-2022 走看看