任务倒计时App

news2024/11/16 21:35:54

设计背景

在某一阶段可能需要给自己设置长期任务,比如找工作、考研等,需要一个单纯的任务计时工具,设置完任务的目标时间后,每次打开App时都能直接看到最新的剩余时间

设计步骤

1. 写java源码

由于需要界面显示,需要用到swing库等,以下是源码

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.List;

public class CountdownTimer extends JFrame {
    private JTextField taskNameField;
    private JTextField dateTimeField;
    private JLabel messageLabel;
    private static final String FILE_PATH = "tasks.txt";
    private DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private List<Task> tasks = new ArrayList<>();
    private JPanel tasksPanel;

    public CountdownTimer() {
        setTitle("倒计时器");
        setSize(600, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        // 创建输入框和按钮
        taskNameField = new JTextField(10);
        dateTimeField = new JTextField(20);
        messageLabel = new JLabel("输入任务名和目标时间 (yyyy-MM-dd HH:mm:ss)", SwingConstants.CENTER);
        JButton addButton = new JButton("添加任务");

        // 添加事件监听器
        addButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                addTask();
            }
        });

        // 布局
        setLayout(new BorderLayout());
        JPanel inputPanel = new JPanel();
        inputPanel.add(new JLabel("任务名:"));
        inputPanel.add(taskNameField);
        inputPanel.add(new JLabel("目标时间:"));
        inputPanel.add(dateTimeField);
        inputPanel.add(addButton);

        tasksPanel = new JPanel();
        tasksPanel.setLayout(new BoxLayout(tasksPanel, BoxLayout.Y_AXIS));

        add(inputPanel, BorderLayout.NORTH);
        add(new JScrollPane(tasksPanel), BorderLayout.CENTER);
        add(messageLabel, BorderLayout.SOUTH);

        // 读取并启动倒计时
        loadTasks();
    }

    private void addTask() {
        String taskName = taskNameField.getText();
        String targetDateTimeStr = dateTimeField.getText();

        try {
            LocalDateTime targetDateTime = LocalDateTime.parse(targetDateTimeStr, formatter);
            Task task = new Task(taskName, targetDateTime);
            tasks.add(task);
            saveTasks();
            displayTasks();
            taskNameField.setText("");
            dateTimeField.setText("");
            messageLabel.setText("任务添加成功!");
        } catch (Exception ex) {
            messageLabel.setText("请输入正确的日期时间格式: yyyy-MM-dd HH:mm:ss");
        }
    }

    private void displayTasks() {
        tasksPanel.removeAll();
        for (Task task : tasks) {
            JPanel taskPanel = new JPanel(new BorderLayout());
            JLabel taskLabel = new JLabel();
            taskPanel.add(taskLabel, BorderLayout.CENTER);
            JButton deleteButton = new JButton("删除");
            deleteButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    tasks.remove(task);
                    saveTasks();
                    displayTasks();
                }
            });
            taskPanel.add(deleteButton, BorderLayout.EAST);
            tasksPanel.add(taskPanel);
            startTimer(task, taskLabel);
        }
        tasksPanel.revalidate();
        tasksPanel.repaint();
    }

    private void startTimer(Task task, JLabel taskLabel) {
        java.util.Timer timer = new java.util.Timer();
        timer.scheduleAtFixedRate(new java.util.TimerTask() {
            @Override
            public void run() {
                LocalDateTime now = LocalDateTime.now();
                long seconds = ChronoUnit.SECONDS.between(now, task.getTargetDateTime());

                if (seconds <= 0) {
                    taskLabel.setText("<html>" + task.getName() + ": <font size='5'>时间到了!</font></html>");
                    timer.cancel();
                } else {
                    long years = ChronoUnit.YEARS.between(now, task.getTargetDateTime());
                    now = now.plusYears(years);
                    long months = ChronoUnit.MONTHS.between(now, task.getTargetDateTime());
                    now = now.plusMonths(months);
                    long days = ChronoUnit.DAYS.between(now, task.getTargetDateTime());
                    now = now.plusDays(days);
                    long hours = ChronoUnit.HOURS.between(now, task.getTargetDateTime());
                    now = now.plusHours(hours);
                    long minutes = ChronoUnit.MINUTES.between(now, task.getTargetDateTime());
                    now = now.plusMinutes(minutes);
                    long secs = ChronoUnit.SECONDS.between(now, task.getTargetDateTime());

                    String timeText = String.format("%d年 %d月 %d天 %02d小时 %02d分 %02d秒",
                            years, months, days, hours, minutes, secs);

                    // Pad numbers with zeros to ensure stable layout
                    String paddedTimeText = timeText.replaceAll("\\b(\\d)\\b", "0$1");

                    // Format the time text with HTML tags to set different font sizes
                    String formattedText = "<html>" + task.getName() + ": ";
                    formattedText += "<font size='5'>" + paddedTimeText + "</font></html>";

                    taskLabel.setText(formattedText);
                }
            }
        }, 0, 1000);
    }





    private void saveTasks() {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(FILE_PATH))) {
            for (Task task : tasks) {
                writer.write(task.getName() + ";" + task.getTargetDateTime().format(formatter));
                writer.newLine();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void loadTasks() {
        tasks.clear();
        try (BufferedReader reader = new BufferedReader(new FileReader(FILE_PATH))) {
            String line;
            while ((line = reader.readLine()) != null) {
                String[] parts = line.split(";");
                if (parts.length == 2) {
                    String taskName = parts[0];
                    LocalDateTime targetDateTime = LocalDateTime.parse(parts[1], formatter);
                    tasks.add(new Task(taskName, targetDateTime));
                }
            }
            displayTasks();
        } catch (IOException e) {
            messageLabel.setText("尚未设置任务。");
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new CountdownTimer().setVisible(true);
            }
        });
    }
}

class Task {
    private String name;
    private LocalDateTime targetDateTime;

    public Task(String name, LocalDateTime targetDateTime) {
        this.name = name;
        this.targetDateTime = targetDateTime;
    }

    public String getName() {
        return name;
    }

    public LocalDateTime getTargetDateTime() {
        return targetDateTime;
    }
}

2. 将java源码转为jar文件

  JAR文件是一种软件包文件格式,通常用于聚合大量的Java类文件、相关的元数据和资源(文本、图片等)文件到一个文件,以便开发Java平台应用软件或库。
  将源码转为jar文件具体可参考这篇博客:如何将.java文件转为.jar

3. 使用launch4j工具将jar文件转为exe可执行文件

具体步骤可参考这篇博客:luanch4j转exe

App展示

这是App的界面演示
在这里插入图片描述
App自取链接:https://pan.baidu.com/s/1C5Nc5ZsdFsSVU3-SEEsdVA
提取码:dddd

开机自启动

若是想开机直接能看到程序启动,
1.记好转好的jar文件地址
2. 用记事本写一个文件,内容为: java -jar “jar文件的地址” ,随后将文件后缀改为.bat
3. win+R打开运行窗口,输入shell:startup,打开开机自启动文件夹,将前面得到的.bat文件放入这个文件夹中即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1812569.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pycharm下载和配置Anaconda环境

文章目录 一、 pycharm安装二、 安装 一、 pycharm安装 官网下载&#xff1a; https://www.jetbrains.com/pycharm/download/#sectionwindows Pycharm community Edition是免费的 二、 安装 安装目录有需要的可以自己更改。 三、创建项目 打开pycharm->继续->不发送。…

【UE数字孪生学习笔记】 虚幻日志系统

声明&#xff1a;部分内容来自于b站&#xff0c;知乎&#xff0c;慕课&#xff0c;公开课等的课件&#xff0c;仅供学习使用。如有问题&#xff0c;请联系删除。 部分内容来自UE官方文档&#xff0c;博客等 虚幻日志系统 1. 日志是一种非常实用的调试工具&#xff0c;可以详细…

AI赋能银行国际结算审单:合合信息抽取技术的实践与应用

官.网地址&#xff1a;合合TextIn - 合合信息旗下OCR云服务产品 时下&#xff0c;银行国际业务是金融体系的重要组成部分&#xff0c;涵盖了外汇交易、国际结算、贸易融资、跨境投资等领域&#xff0c;这些业务对于国际贸易和全球经济发展具有重要作用。国际业务部门单据、凭证…

renren-fast-vue在mac上的运行

被这个折磨好久了&#xff0c;终于成功了。。 版本号-node-14 需要提前执行的命令&#xff0c;希望可以帮助到大家。分别是解决版本在mac m1架构上的不兼容问题&#xff0c;另外解决没有验证码的问题&#xff0c;要注意数据库的配置&#xff0c;账号密码是否正确。 npm inst…

C语言中指针的说明

什么是指针&#xff1f; 在C语言当中&#xff0c;我们可以将指针理解为内存当中存储的地址&#xff0c;就像生活当中&#xff0c;一个小区里面&#xff0c;在小区里面有很单元&#xff0c;每一栋单元&#xff0c;单元内的房间有着不同的房间号&#xff0c;我们可以同过几栋几单…

JAVA开发 PDF文件生成表格,表格根据内容自动调整高度

1、展示效果 2、相关功能实现 JAVA开发 使用Apache PDFBox库生成PDF文件&#xff0c;绘制表格 3、实现代码 import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.ap…

Nginx+Tomcat负载均衡、动静分离原理

目录 一.Nginx负载均衡 1.负载均衡概念 2.负载均衡原理 3.Nginx反向代理 3.1.反向代理概念 3.2.Nginx实现负载均衡的主要配置项 二.Nginx动静分离 1.什么是动静分离 2.动态页面与静态页面区别 3.动静分离原理 三.NginxTomcat负载均衡的实验设计 1.部署nginx负载均衡…

周二A股走势分化,半导体板块逆势上涨,有色、航运等周期股下跌,贵州茅台跌3%

内容提要 午后创业板翻红&#xff0c;科创50大涨2.4%&#xff0c;半导体板块逆势上扬&#xff0c;中芯国际涨超3% 。 贵金属、航运板块跌幅居前&#xff0c;中远海控跌停。港股黄金、航运及地产板块也走弱&#xff0c;招金矿业跌超10%&#xff0c;中远海控大跌12%。 周二股市行…

品牌具象化:从经济到市场的深度解析

在当今日益激烈的市场竞争中&#xff0c;无论是传统行业还是电商行业&#xff0c;都面临着前所未有的挑战与机遇。越来越多的企业家开始意识到&#xff0c;单纯的产品竞争已经难以支撑企业的长远发展&#xff0c;而品牌的力量正逐渐凸显其重要性之一。本文将深入探讨品牌具象化…

HCIE认证,这些误区要避开

追求HCIE认证是许多网络工程师提升职业水平的选择之一。 然而&#xff0c;在这条备考之路上&#xff0c;存在不少误解可能会误导你的学习方向或影响你的备考效率。 了解并避开这些常见误区&#xff0c;将帮助你更有效地准备HCIE认证考试。 01 误区一&#xff1a;过分依赖题库 …

数据通信中的同步方式

同步指的是什么呢&#xff1f; 百度百科&#xff1a; 同步指两个或两个以上随时间变化的量在变化过程中保持一定的相对关系。 本意是指某人或某事同时进行&#xff1b;同时产生&#xff0c;比如音画同步、动作同步等。 同步&#xff08;英语&#xff1a;Synchronization&am…

第二十七章HTML.CSS综合案例(三)

5.小米侧边栏 效果如下&#xff1a; 代码图如下&#xff1a; <style>*{margin: 0;padding: 0;}ul{list-style: none;}a{text-decoration: none;}.box{width: 100%;height: 100%;position: absolute;background-image: linear-gradient(to right, #a07ad0, #c39340);}.…

喜讯 | 爱洁丽攸信技术uMOM制造运营系统项目启动会圆满成功!

2024年6月4日&#xff0c;厦门攸信信息技术有限公司&#xff08;以下简称“攸信技术”&#xff09;与福建爱洁丽日化有限公司&#xff08;以下简称“爱洁丽”&#xff09;uMOM制造运营系统项目启动会圆满成功 01合作客户介绍 Introduction of cooperative customers 福建爱洁…

问题:一般在管理工作复杂、面广且管理分工比较细致的单位,常采用()组织形式。 #媒体#媒体

问题&#xff1a;一般在管理工作复杂、面广且管理分工比较细致的单位&#xff0c;常采用()组织形式。 A&#xff0e;直线式 B&#xff0e;职能式 C&#xff0e;矩阵式 D&#xff0e;团队式 参考答案如图所示

使用MySQL

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 1 下载安装MySQL MySQL是一款开源的数据库软件&#xff0c;由于其免费特性得到了全世界用户的喜爱&#xff0c;是目前使用人数最多的数据库。下面将…

v-for循环出来的图片如何替换图片路径

滑过改变图片的路径 <div v-for"(item,index) in serverlist2" :key"index" class"serverlistitem serverlistitem2" mouseover"item.hover true"mouseleave"item.hover false"><div><img:src"item.…

论文阅读U-KAN Makes Strong Backbone for MedicalImage Segmentation and Generation

作为一种非常有潜力的代替MLP的模型&#xff0c;KAN最终获得了学术界极大的关注。在我昨天的博客里&#xff0c;解读了最近的热门模型KAN&#xff1a; 论文阅读KAN: Kolmogorov–Arnold Networks-CSDN博客 KAN的原文作者提到了很多不足。本文算是对其中两个现有不足的回应&am…

基于蚁群算法的二维路径规划算法(matlab)

微♥关注“电击小子程高兴的MATLAB小屋”获得资料 一、理论基础 1、路径规划算法 路径规划算法是指在有障碍物的工作环境中寻找一条从起点到终点、无碰撞地绕过所有障碍物的运动路径。路径规划算法较多&#xff0c;大体上可分为全局路径规划算法和局部路径规划算法两大类。其…

java之IO流和集合框架的笔记

1 File类的使用 1.1 概述 File类及本章下的各种流&#xff0c;都定义在java.io包下。 一个File对象代表硬盘或网络中可能存在的一个文件或者文件目录&#xff08;俗称文件夹&#xff09;&#xff0c;与平台无关。&#xff08;体会万事万物皆对象&#xff09; File 能新建、删…