简单的倒计时器

一、项目简介

功能描述:该计时器应用程序允许用户输入一个计时器的名称和倒计时时间,并启动、停止和重置计时器。当用户启动计时器时,程序会启动一个单独的线程来执行倒计时功能,并在文本框中显示剩余时间。当时间减少到0时,计时器将停止,并且所有按钮将被设置为可用状态,以便用户重新设置计时器。此外,该应用程序还包括一些逻辑,用于验证用户输入的时间格式,并在需要时显示错误消息。总之,该计时器应用程序提供了一个简单但实用的计时器,可以用于各种计时需求。

个人负责任务

  1. 设计和实现了计时器应用程序的功能,包括用户界面、计时器线程、事件处理程序和计算器逻辑。
  2. 使用Java编程语言和Swing GUI库来创建用户界面和实现计时器功能。
  3. 实现了一个简单但实用的计时器应用程序,可以用于各种计时需求。

二、功能架构图

三、个人任务简述

1. 完成的任务与功能

简单描述将自己完成的有特色的地方、重难点地方。

序号

完成功能与任务

描述

1

倒计时功能

线程、事件处理程序和计算器逻辑完成了基本的倒计时功能。

2

面向对象设计

使用了面向对象技术设计系统。

3

记录功能

创建了一个JTextArea用于记录倒计时的基本信息。

四、本人负责功能详解

1.用户界面模块:

该模块负责创建用户界面,包括一个文本框用于输入倒计时时间、一个标签用于显示计时器名称、一个按钮用于启动计时器、一个按钮用于停止计时器以及一个按钮用于重置计时器。用户可以在文本框中输入倒计时时间,然后单击“Start”按钮启动计时器,或单击“Stop”按钮停止计时器,或单击“Reset”按钮重置计时器。该模块使用Swing GUI库来创建用户界面。

2.计时器模块:

该模块负责实现计时器功能,包括启动、停止和重置计时器。当用户单击“Start”按钮时,该模块会启动一个单独的线程来执行倒计时功能,每秒钟减少一秒的时间,并将剩余时间显示在文本框中。当时间减少到0时,计时器将停止,并将所有按钮设置为可用状态,以便用户重新设置计时器。当用户单击“Stop”按钮时,计时器将被停止。当用户单击“Reset”按钮时,计时器将被重置为最初的时间,并将所有按钮设置为可用状态。

3.事件处理模块:

 

该模块负责处理用户的事件,包括单击“Start”按钮、单击“Stop”按钮和单击“Reset”按钮等事件。当用户单击“Start”按钮时,事件处理程序将启动计时器模块,并根据用户输入的时间来启动计时器线程。当用户单击“Stop”按钮时,事件处理程序将停止计时器模块。当用户单击“Reset”按钮时,事件处理程序将重置计时器模块并将所有按钮设置为可用状态。

4.计算逻辑模块:

该模块负责验证用户输入的时间格式,并在需要时显示错误消息。它还包括一些逻辑,用于将计时器线程的状态设置为运行、停止或重置。

五、课程设计感想

这个计时器核心的计时算法有三个版本,第一个版本使用System.currentTimeMillis()方法直接调取系统时间,换算后进行显示、计时等等操作,但这个版本完全没有技术含量,所以放弃了。第二个版本则创建了两个线程tCh与t1,tCh同样调用System.currentTimeMillis()方法进行毫秒的计算,当tCh完成了1000毫秒计时后,给t1线程内一个布尔变量设为true,t1再进行秒、分钟等等计算,但由于多线程未做好同步,第二个版本便放弃

六、展望

1.不足:目前对于线程同步还是不熟悉,并且这个版本的计时器仍有一些小bug,需要学习的东西还有很多。

2.展望:第二个版本只要能够做好数据同步的话其实是最好的,因此未来当然打算继续学习一些多线程、数据同步相关的知识,把第二个版本完善好。

package TimerSe;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class TimerSec extends JFrame implements ActionListener {
    private JTextField nameField, timeField;
    private JTextArea logArea;
    private JButton startButton, stopButton, resetButton;
    private int minutes = 0, seconds = 0, mminutes = 0, mseconds = 0;
    private boolean running = false;

    public TimerSec() {
        setTitle("Timer");
        setSize(400, 300);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocation((1920 - 800) / 2, (1080 - 600) / 2);

        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(5, 2));

        JLabel nameLabel = new JLabel("Name:");
        nameField = new JTextField();
        JLabel timeLabel = new JLabel("Time (mm:ss):");
        timeField = new JTextField();
        logArea = new JTextArea(5, 20);
        logArea.setEditable(false);
        startButton = new JButton("Start");
        startButton.addActionListener(this);
        stopButton = new JButton("Stop");
        stopButton.addActionListener(this);
        resetButton = new JButton("Reset");
        resetButton.addActionListener(this);

        panel.add(nameLabel);
        panel.add(nameField);
        panel.add(timeLabel);
        panel.add(timeField);
        panel.add(new JLabel());
        panel.add(new JLabel());
        panel.add(startButton);
        panel.add(stopButton);
        panel.add(resetButton);
        panel.add(new JLabel());

        getContentPane().add(panel, BorderLayout.NORTH);
        getContentPane().add(new JScrollPane(logArea), BorderLayout.CENTER);
    }

    public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();
        if (source == startButton) {
            if (!running) {
                try {
                    minutes = Integer.parseInt(timeField.getText().split(":")[0]);
                    seconds = Integer.parseInt(timeField.getText().split(":")[1]);
                    mminutes = minutes;
                    mseconds = seconds;
                } catch (Exception ex) {
                    JOptionPane.showMessageDialog(null, "Invalid time format. Please enter mm:ss.");
                    return;
                }
                if (minutes < 0 || seconds < 0 || seconds >= 60) {
                    JOptionPane.showMessageDialog(null, "Invalid time format. Please enter mm:ss.");
                    return;
                }
                running = true;
                startButton.setEnabled(false);
                stopButton.setEnabled(true);
                resetButton.setEnabled(false);
                nameField.setEditable(false);
                timeField.setEditable(false);
                logArea.append(nameField.getText() + ": " + minutes + " minutes " + seconds + " seconds\n");

                Thread t1 = new Thread(new Runnable() {
                    public void run() {
                        
                        while (running && minutes >= 0 && seconds >= 0) {
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            if (seconds == 0) {
                                
                                if (minutes == 0) {
                                    running = false;
                                    startButton.setEnabled(true);
                                    stopButton.setEnabled(false);
                                    resetButton.setEnabled(true);
                                    nameField.setEditable(true);
                                    timeField.setEditable(true);
                                    break;
                                } else {
                                    minutes--;
                                    seconds = 59;
                                }
                            } else {
                                seconds--;
                            }
                            timeField.setText(String.format("%02d:%02d", minutes, seconds));
                        }
                    }
                });
                t1.start();
            }
        } else if (source == stopButton) {
            running = false;
            startButton.setEnabled(true);
            stopButton.setEnabled(false);
            resetButton.setEnabled(true);
            nameField.setEditable(true);
            timeField.setEditable(true);
        } else if (source == resetButton) {
            running = false;
            minutes = mminutes;
            seconds = mseconds;
            timeField.setText(String.format("%02d:%02d", minutes, seconds));
            startButton.setEnabled(true);
            stopButton.setEnabled(false);
            resetButton.setEnabled(false);
            nameField.setEditable(true);
            timeField.setEditable(true);
        }
    }

}
package TimerSe;

public class Run {
    public static void main(String[] args) {
        TimerSec TimerSec = new TimerSec();
        TimerSec.setVisible(true);
    }
}

#include #define ulong unsigned long char tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xd8,0x80,0x90}; char tab_dp[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x58,0x00,0x10}; #define LED P0 //P0 为数码管的段选 #define WS P1 //P1 为数码管的位选 sbit time_shift=P3^0; //P3^0 为"移位"按键 sbit time_set=P3^1; //P3^1 为"修改"按键 sbit set_inc=P3^2; //P3^2 为"增加"按键 sbit time_run=P3^3; //P3^3 为"计时开始暂停"按键 sbit LIGHT=P2^0; sbit SPEAKER=P2^7; unsigned char sec,min,sec_ge,sec_shi,min_ge,min_shi,t; //定义秒,分,时,秒的个位,十位,分的个位,十位 int state; //秒表状态指示 0-计时暂停 1-正在倒计时 2-计时时间参数修改 int flag; //秒表修改数据指示 0-分钟十位 1-分钟个位 2-秒钟十位 3-秒钟个位 int blink; //-------------------------------------------------------------------- void init(); void display_run(); void display_pause(); void delay(int); void time_modify(); //-------------------------------------------------------------------- void main() { init(); state=0; flag=0; blink=1; t=0; LIGHT=1; SPEAKER=1; min=5; sec=0; sec_ge=0; //秒的个位和十位 sec_shi=0; min_ge=5; //分的个位和十位 min_shi=0; while(1) { if(time_set==0) //如果"调时"按键按下 { delay(5); //延时去抖 if(time_set==0) state=2; } if(state==0) { TR0=0; TR1=0; display_pause(); } if(state==1) { TR0=1; TR1=0; display_run(); } if(state==2) { TR1=1; time_modify(); } } } //-------------------------------------------------------------------- void init() { TMOD=0x11; EA=1; ET0=0; ET1=0; TH0=0x4d; TL0=oxfc; //开总中断 //定义定时器 0 工定时器 1 作与方式 1 //定时器 0 赋初值 TH1=15536/256; TL1=15536%256; //中断初始化 EX0=1; PX0=0; IT0=1; EX1=1; PX1=1; //定时器 1 赋初值 IT1=1; } //外中断 1 void INT_1() interrupt 2 using 0 { if( time_run==0)//表示按钮有按下 { delay(20); //延时 if(time_run==0) { state=(state+1)%2; LIGHT=1; SPEAKER=1; } } } //外中断 0 void INT_0() interrupt 0 using 1 { if( set_inc==0)//表示按钮有按下 { delay(20); //延时去抖 if(set_inc==0) { switch(flag) //分支结构,根据 flag 的值来判断哪一位加 1 { case 0: { min=(min+10)%60; break; } case 1: { min=(min+1)+min/10*10; break; } case 2: { sec=(sec+10)%60; break; } case 3: { sec=(sec+1)+sec/10*10; break; } default:break; } } } } //--------------------------------延时子函数----------------------------------- void delay(int x) { int i,j; for(i=x; i>0l; i--) for(j=255; j>0; j--) ; } //-------------------------------显示子函数-------------------------------------- void display_run() { if(TF0==1) //如果定时器溢出 { TF0=0; //清中断标志位 t++; if(t==20) { t=0; if(min==0&&sec==0) { min=60; } if(sec==0) { sec=59; min--; } else sec--; if(min==0&&sec>56) { SPEAKER=0; delay(20); SPEAKER=1; } if(min==0&&sec==0) { LIGHT=0; SPEAKER=0; delay(20); SPEAKER=1; delay(240); SPEAKER=0; delay(20); SPEAKER=1; delay(240); SPEAKER=0; delay(20); SPEAKER=1; delay(240); SPEAKER=0; delay(20); SPEAKER=1; delay(240); SPEAKER=0; delay(20); SPEAKER=1; state=4; min=5;//回归初始化 sec=0; sec_ge=0; //秒的个位和十位 sec_shi=0; min_ge=5; //分的个位和十位 min_shi=0; } } } sec_ge=sec; //秒的个位和十位 sec_shi=sec/10; min_ge=min; //分的个位和十位 min_shi=min/10; WS=0xfe; //循环扫描 LED=tab[sec_ge]; delay(1); WS=0xfd; LED=tab[sec_shi]; delay(1); WS=0xfb; LED=tab_dp[min_ge]; delay(1); WS=0xf7; LED=tab[min_shi]; delay(1); } void display_pause() { WS=0xfe; //循环扫描 LED=tab[sec_ge]; delay(1); WS=0xfd; LED=tab[sec_shi]; delay(1); WS=0xfb; LED=tab_dp[min_ge]; delay(1); WS=0xf7; LED=tab[min_shi]; delay(1); } void time_modify() { //修改位的闪烁状态 if(TF1==1) { TF1=0; blink=(blink+1)%2; } //修改具体哪个数码管指示 if(time_shift==0) { delay(60); if(time_shift==0) flag=(flag+1)%4; } // 修改状态下的数码管显示 switch(flag) //分支结构,根据 flag 的值来决定扫描状态 { case 0: { sec_ge=sec; //秒的个位和十位 sec_shi=sec/10; min_ge=min; //分的个位和十位 min_shi=min/10; WS=0xfe; //循环扫描 LED=tab[sec_ge]; delay(1); WS=0xfd; LED=tab[sec_shi]; delay(1); WS=0xfb; LED=tab_dp[min_ge]; delay(1); if(blink==1) { WS=0xf7; LED=tab[min_shi]; delay(1); } break; } case 1: { sec_ge=sec; //秒的个位和十位 sec_shi=sec/10; min_ge=min; //分的个位和十位 min_shi=min/10; WS=0xfe; //循环扫描 LED=tab[sec_ge]; delay(1); WS=0xfd; LED=tab[sec_shi]; delay(1); if(blink==1) { WS=0xfb; LED=tab_dp[min_ge]; delay(1); } WS=0xf7; LED=tab[min_shi]; delay(1); break; } case 2: { sec_ge=sec; //秒的个位和十位 sec_shi=sec/10; min_ge=min; //分的个位和十位 min_shi=min/10; WS=0xfe; //循环扫描 LED=tab[sec_ge]; delay(1); if(blink==1) { WS=0xfd; LED=tab[sec_shi]; delay(1); } WS=0xfb; LED=tab_dp[min_ge]; delay(1); WS=0xf7; LED=tab[min_shi]; delay(1); break; } case 3: { sec_ge=sec; //秒的个位和十位 sec_shi=sec/10; min_ge=min; //分的个位和十位 min_shi=min/10; if(blink==1) { WS=0xfe; //循环扫描 LED=tab[sec_ge]; delay(1); } WS=0xfd; LED=tab[sec_shi]; delay(1); WS=0xfb; LED=tab_dp[min_ge]; delay(1); WS=0xf7; LED=tab[min_shi]; delay(1); break; } default:break; } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值