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 ...
随机推荐
- 菜鸟笔记 -- Chapter 6.2 类的构成
在前面我们讲过高级开发语言大多由7种语法构成,但这是一个很空泛的概述,下,面我们仅就针对Java程序来说一下构成一个Java程序的几大部分,其中类是最小的基本元素.类是封装对象属性和行为的载体,而在J ...
- 工具类(为控件设置圆角) - iOS
为了便于日常开发效率,因此创建了一些小的工具类便于使用.具体 code 如下:声明: /* 为控件添加边框样式_工具类 */ #import <UIKit/UIKit.h> typedef ...
- 【2017 ICPC亚洲区域赛沈阳站 K】Rabbits(思维)
Problem Description Here N (N ≥ 3) rabbits are playing by the river. They are playing on a number li ...
- centos7 openvpn代理搭建
系统环境:centos7.1 拨号ip地址:125.112.194.40(公网) server端部署 一.准备工作 1.检查SELinux状态,关闭 sed -i 's/enforcing/disab ...
- iptables应用
192.168.4.119 为本机的ip地址:每条链的规则是由上至下进行匹配,因此我们需要把范围小的规则放在上面以防被覆盖. 1)清空iptables默认规则,并自定义规则 [root@iptable ...
- grafana使用Prometheus数据源监控mongo数据库
数据库改用mongo后,监控需求就需要整合进grafana里,由于一直在坚持docker化部署,那么此次也不例外. 1. 安装Prometheus: What is Prometheus? Prome ...
- laravel路由组+中间件
在rotues中的web.php
- Idea 2017 激活方法
http://www.cnblogs.com/suiyueqiannian/p/6754091.html
- flask钩子
请求钩子 从请求到响应的过程中,设置了一些方法来实现某些功能 before_first_request 在处理第一个请求前运行 before_request 在每次请求前运行 after_re ...
- asp.net core mvc简介
MVC 通常而言,我们使用.NET Core MVC 构建网页应用与 API,MVC是使用模型-视图-控制器(Model-View-Controller)设计模式. 创建项目 使用如下命令创建一个名称 ...