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 ...
随机推荐
- Linux_vsftpd服务配置
首先安装Linux 企业版第一张光盘中的vsftpd-2.0.1-5.i386.rpm#rpm –ivh /media/cdrom/RedHat/RPMS/vsftpd-3.0.1-5.i386.rp ...
- 嵌入式:指针的指针、链表、UCOS 的 OSMemCreate 。
初看,UCOS 的 OSMemCreate 代码,感觉有点怪怪的,比如,把 指针指向的地址 强制转换成 指针的指针的指向地址 ?那转换后 指针的指针 又是什么? void OSMemCreate (O ...
- zTree的核心处理逻辑
zTree 是一个前端树形结构的插件. 使用起来很简单,我们重点关注一下插件的核心代码. 首先,zTree需要如下的数据结构: let areaData = [ { "id": & ...
- 洛谷P2052 [NOI2011]道路修建(树形DP)
题目描述 在 W 星球上有 n 个国家.为了各自国家的经济发展,他们决定在各个国家 之间建设双向道路使得国家之间连通.但是每个国家的国王都很吝啬,他们只愿 意修建恰好 n – 1 条双向道路. 每条道 ...
- 根据坐标计算距离(mysql函数)
CREATE DEFINER=`root`@`localhost` FUNCTION `getDistance`(lng1 ) BEGIN DECLARE result double; DECLARE ...
- yum仓库客户端搭建和NTP时间同步客户端配置
一.yum仓库客户端搭建 yum源仓库搭建分为服务器端和客户端. 服务端主要提供软件(rpm包)和yumlist.也就是提供yum源的位置.一般是通过http或者ftp提供位置. 客户端的配置:yum ...
- emlog博客插件分享openSug
emlog博客插件百度搜索下拉提示框openSug.js发布上线啦: 下载:https://www.opensug.org/faq/.../opensug.emlog_v1.0.0.zip[~4KB]
- 【JDBC】一、JDBC连接数据库
package com.jdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLExce ...
- 阿里云mysql连接不上
轻量级服务器管理 - 防火墙 - 添加规则 防火墙 mysql 3306 注意IPtables 与 firewalld 状态! 啃爹的防火墙,找了一天
- Python | 用Pyinstaller打包发布exe应用
参考:https://jingyan.baidu.com/article/a378c960b47034b3282830bb.html https://ask.csdn.net/questions/72 ...