Java 实现一个带提醒的定时器
定时闹钟预览版EXE下载链接:https://files.cnblogs.com/files/rekent/ReadytoRelax_jar.zip
功能说明:
实现了一个休息提醒器,用户首先设定一个倒计时时间(HH:MM:SS),每走完这个时间便会弹出提醒,让用户停止工作,起身休息。
休息回来工作时只需点击弹窗上的继续工作便可以继续以当前时间继续开始倒计时。
涉及技术:
使用类似Timer的定时器来推迟提醒线程的执行便可完成程序的主体部分,再辅以JavaFX、AWT来构建GUI界面即可。
此处使用ScheduledThreadPoolExecutor(点击此处获取该线程池的具体用法)这个线程池来实现延时执行的功能。
当前涉及的问题:
点击开始计时后,无法停止计时(无法获取到线程池中的线程并终止它);
线程池的进程不会因为JavaFX程序的关闭而结束,两者这件没有相互约束的关系;
源代码(一):(点击事件)
@FXML private TextField AlarmSecond;
@FXML private TextField AlarmMiunte;
@FXML private TextField AlarmHour;
@FXML private javafx.scene.control.Button begin; @FXML public void beginCountDown(ActionEvent event) throws AWTException, InterruptedException {
ScheduledThreadPoolExecutor threadPool=new ScheduledThreadPoolExecutor(10);
//01.对TextField中数字的判断
List<Integer> valueList=new ArrayList<>();
String second=AlarmSecond.getText();
String miunte=AlarmMiunte.getText();
String hour=AlarmHour.getText();
if(second==null){
second="0";
}
if(miunte==null){
miunte="0";
}
if(hour==null){
hour="0";
}
if(!((second.matches("[0-9]*"))&&(miunte.matches("[0-9]*"))&&(hour.matches("[0-9]*")))){
Alert alert=new Alert(Alert.AlertType.ERROR);
alert.showAndWait();
return;
}
int int_second=Integer.parseInt(second);
int int_miunte=Integer.parseInt(miunte);
int int_hour=Integer.parseInt(hour);
if(int_hour+int_miunte+int_second<=0){
Alert alert=new Alert(Alert.AlertType.ERROR);
alert.showAndWait();
return;
}
valueList.add(int_second);
valueList.add(int_miunte);
valueList.add(int_hour);
//02.计算Long时间类型,单位为MILLISECONDS
long workingTime=new SpinnerUtil().Time2Millseconds(valueList.get(2),valueList.get(1),valueList.get(0));
String button_show=begin.getText();
if(button_show.equals("开始计时")){
begin.setText("停止计时");
System.out.println("倒计时时长:"+ valueList.get(2) +"H "+valueList.get(1)+"M "+valueList.get(0)+"S");
//03.创建一个对话框提醒线程
Runnable CountingAndShow=new Runnable() {
@Override
public void run() {
begin.setText("开始计时");
System.out.println("Counting Over,Have a rest!");
Object[] options = {"继续工作","下班啦"};
int response= JOptionPane.showOptionDialog(new JFrame(), "休息一下吧~","",JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
if(response==0){
try {
beginCountDown(event);
} catch (AWTException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
} }
};
//04.创建一个JavaFX Task任务,并将线程加入线程池中
Task countingTimer=new Task() {
@Override
protected Object call() throws Exception {
threadPool.schedule(CountingAndShow,workingTime,TimeUnit.MILLISECONDS);
return null;
} };
countingTimer.run();
}
else {
//此处代码并没有效果
System.out.println("Stop Current Counting");
threadPool.shutdownNow();
begin.setText("开始计时");
}
}
源代码(二)以及BUG修复理念
采用Timer来实现停止功能,在Controller中建立一个私有的Timer对象,这样使每次点击都能是同一个Timer对象。
停止计时--->调用Timer的Cancel()函数,即可关闭整个Timer(也会结束这个Timer线程),此时再重新实例化一个Timer即可。
private Timer timer;
//新需要保证暂停和开始调用的为同一个Timer对象,所以在前面调用一个私有的对象,在后面在对其实例化
public Controller() {
timer=new Timer();
}
@FXML public void beginCountDown(ActionEvent event) throws AWTException, InterruptedException {
//01.对TextField中数字的判断
String second=AlarmSecond.getText();
String miunte=AlarmMiunte.getText();
String hour=AlarmHour.getText();
//02.添加对为空时的自主处理方式
if(second==null){
second="0";
}
if(miunte==null){
miunte="0";
}
if(hour==null){
hour="0";
}
//03.添加对输入模式的限制
if(!((second.matches("[0-9]*"))&&(miunte.matches("[0-9]*"))&&(hour.matches("[0-9]*")))){
Alert alert=new Alert(Alert.AlertType.ERROR);
alert.showAndWait();
return;
}
int int_second=Integer.parseInt(second);
int int_miunte=Integer.parseInt(miunte);
int int_hour=Integer.parseInt(hour);
if(int_hour<0||int_miunte<0||int_second<0||(int_hour+int_miunte+int_second<=0)){
Alert alert=new Alert(Alert.AlertType.ERROR);
alert.showAndWait();
return;
}
//02.计算Long时间类型,单位为MILLISECONDS
long workingTime=new SpinnerUtil().Time2Millseconds(int_hour,int_miunte,int_second);
String button_show=begin.getText();
if(button_show.equals("开始计时")){
begin.setText("停止计时");
System.out.println("倒计时时长:"+ int_hour +"H "+int_miunte+"M "+int_second+"S");
//03.创建一个对话框提醒线程
TimerTask timerTask=new TimerTask() {
@Override
public void run() {
System.out.println("run timeTask");
Platform.runLater(() -> {
begin.setText("开始计时");
System.out.println("Counting Over,Have a rest!");
Object[] options = {"继续工作", "下班啦"};
int response = JOptionPane.showOptionDialog(new JFrame(), "休息一下吧~", "", JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
if (response == 0) {
try {
beginCountDown(event);
} catch (AWTException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
};
//04.创建一个JavaFX Task任务,并将线程加入线程池中
Task countingTimer=new Task() {
@Override
protected Object call() throws Exception {
timer.schedule(timerTask,workingTime);
return null;
}
};
countingTimer.run();
System.out.println("run timer");
}
else {
System.out.println("Stop Current Counting");
timer.cancel();
begin.setText("开始计时");
timer=new Timer();
}
}
Java 实现一个带提醒的定时器的更多相关文章
- 用java构造一个带层次的文件目录遍历器
import java.util.List; import java.io.File; import java.util.ArrayList; public class IteratorUtil { ...
- DIY一个高大上带提醒的计时器,简单实用,你还在等什么
小编心语:锵锵锵!小编我又来了!昨天发了一篇比较实用的<Python聊天室>,鉴于反响还不错,SO ,小编也想给大家多分享点有用的干货,让大家边学边用.好了,闲话不多说,今天要给各位看官们 ...
- Java基础---Java---IO流-----File 类、递归、删除一个带内容的目录、列出指定目录下文件夹、FilenameFilte
File 类 用来将文件或者文件夹封装成对象 方便对文件与文件夹进行操作. File对象可以作为参数传递给流的构造函数 流只用操作数据,而封装数据的文件只能用File类 File类常见方法: 1.创建 ...
- java中不带package和带package的编译运行方式
Java中不带package的程序和带package的程序编译的方式是不同的. 一.不带package的程序建立个HelloWorld.java的文件,放入C:\,内容如下:public class ...
- 使用Java编写一个简单的Web的监控系统cpu利用率,cpu温度,总内存大小
原文:http://www.jb51.net/article/75002.htm 这篇文章主要介绍了使用Java编写一个简单的Web的监控系统的例子,并且将重要信息转为XML通过网页前端显示,非常之实 ...
- Java线程池带图详解
线程池作为Java中一个重要的知识点,看了很多文章,在此以Java自带的线程池为例,记录分析一下.本文参考了Java并发编程:线程池的使用.Java线程池---addWorker方法解析.线程池.Th ...
- 面试:用 Java 实现一个 Singleton 模式
面试:用 Java 实现一个 Singleton 模式 面试系列更新后,终于迎来了我们的第一期,我们也将贴近<剑指 Offer>的题目给大家带来 Java 的讲解,个人还是非常推荐< ...
- File类_删除一个带内容的目录_练习
需求:删除一个带内容的目录 原理:必须从最里面往外删除需要深度遍历 import java.io.File; public class RemoveDirTest { public static vo ...
- Java发邮件带附件测试通过
package cn.bric.crm.util; import java.util.Date; import java.util.Enumeration; import java.util.Prop ...
随机推荐
- Oracle oerr工具介绍
(1)什么是oerr oerr是Oracle提供的在UNIX/Linux上查看Oracle错误的小工具,使用起来非常方便. (2)如何使用 oerr工具位于ORACLE_HOME下面,可以使用whic ...
- iOS开发- 获取本地视频文件
下面具体介绍下实现过程.先看效果图.图1. 未实现功能前, iTunes截图 图2. 实现功能后, iTunes截图 图3. 实现功能后, 运行截图 好了, 通过图片, 我们可以看到实现的效果.功能包 ...
- 在Closing事件中,将e.Cancle设置成true,则Windows无法关机和重启系统的解决办法
最近在设计一个WinForm程序的时候遇到一个bug,就是From1窗体的关闭事件中设置了e.Cancle设置成true,导致系统无法关机重启,windows7 和windows xp都是这样. 我这 ...
- Ubuntu 16.04 Server 版安装过程图文详解
进入系统安装的第一个界面,开始系统的安装操作.每一步的操作,左下角都会提示操作方式!! 1.选择系统语言-English 2.选择操作-Install Ubuntu Server 3.选择安装过程和系 ...
- Docker 运行MySQL 5.7
#在opt新建挂载目录 cd /opt #-v 显示创建的目录名 mkdir -vp docker_cfg/mysql/data docker_cfg/mysql/logs docker_cfg/my ...
- dom4j解析器sax解析xml文件
1.使用dom4j解析器解析xml ***解析器dom4j是由dom4j组织提供的,针对xml进行解析.dom4j不是Javase的一部分,使用时需要导入dom4j的jar包(官网下载) 在eclip ...
- 【mvrp多协议vlan注册协议给予三种注册方式的验证】
MVRP 多vlan注册协议给予三种注册模式的配置 一:根据项目需求搭建好拓扑图如下 二:配置: 首先对项目做理论分析,sw1,sw2,sw3所组成的直连网络中,为使不同的PC之间进行通信,按vlan ...
- 吐血分享:QQ群霸屏技术(初级篇)
QQ群,仿似一个冷宫;But,你真摒弃不起. 某人,坐拥2000多个2000人群,月收入10w+,此类人数少,皆因多年的沉淀,以形成完全的壁垒,难以企及的层次. 流量的分散,QQ群相对比较优质的地带, ...
- Python的matplotlib模块的使用-Github仓库
import matplotlib.pyplot as plt import numpy as np import requests url='https://api.github.com/searc ...
- python数据类型及其特有方法
一.运算符 in方法 "hello" in "abcdefghijklmnopqrstuvwxyz" "li" in ["gg&q ...