基于Java开发定时关机小工具实例代码详解

原创 2025-05-21 10:32:03编程技术
661

本文将通过一个完整的Java项目实例,演示如何开发一款跨平台的定时关机小工具。该工具支持Windows/Linux/macOS系统,具备可视化界面、倒计时显示、任务取消等核心功能,适合Java初学者学习系统交互和GUI开发。

一、功能需求分析

  1. 核心功能

    • 设置定时关机时间(支持秒/分/时单位)

    • 实时倒计时显示

    • 任务取消功能

    • 跨平台兼容(Windows/Linux/macOS)

  2. 技术选型

    • GUI框架:Swing(轻量级,无需额外依赖)

    • 定时任务ScheduledExecutorService(JDK自带,线程池管理)

    • 系统交互ProcessBuilder(跨平台命令执行)

二、系统命令研究

不同操作系统关机命令差异较大,需做兼容处理:

操作系统 关机命令 取消关机命令
Windowsshutdown -s -t 秒数shutdown -a
Linuxshutdown -h +分钟数shutdown -c
macOSshutdown -h +分钟数shutdown -c

三、项目代码实现

3.1 创建GUI界面

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ShutdownTimer {
    private JFrame frame;
    private JTextField timeField;
    private JComboBox<String> unitCombo;
    private JLabel countdownLabel;
    private ScheduledExecutorService scheduler;
    private long remainingTime;

    public ShutdownTimer() {
        initializeUI();
        setupEventHandlers();
    }

    private void initializeUI() {
        frame = new JFrame("定时关机工具");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new GridLayout(4, 1));

        // 时间输入面板
        JPanel timePanel = new JPanel();
        timePanel.add(new JLabel("时间:"));
        timeField = new JTextField(5);
        unitCombo = new JComboBox<>(new String[]{"秒", "分", "时"});
        timePanel.add(timeField);
        timePanel.add(unitCombo);

        // 按钮面板
        JPanel buttonPanel = new JPanel();
        JButton startButton = new JButton("开始");
        JButton cancelButton = new JButton("取消");
        buttonPanel.add(startButton);
        buttonPanel.add(cancelButton);

        // 倒计时显示
        countdownLabel = new JLabel("剩余时间: 00:00:00");
        countdownLabel.setHorizontalAlignment(SwingConstants.CENTER);

        frame.add(timePanel);
        frame.add(buttonPanel);
        frame.add(countdownLabel);
        frame.pack();
        frame.setLocationRelativeTo(null);
    }

    // 事件处理...
}

3.2 实现定时关机逻辑

private void setupEventHandlers() {
    // 开始按钮事件
    JButton startButton = (JButton) ((JPanel) frame.getContentPane().getComponent(1)).getComponent(0);
    startButton.addActionListener(e -> {
        try {
            long time = Long.parseLong(timeField.getText());
            String unit = (String) unitCombo.getSelectedItem();
            
            // 时间单位转换
            switch (unit) {
                case "分": time *= 60; break;
                case "时": time *= 3600; break;
            }

            if(time <= 0) throw new NumberFormatException();
            
            startShutdownTimer(time);
        } catch (NumberFormatException ex) {
            JOptionPane.showMessageDialog(frame, "请输入有效数字", "错误", JOptionPane.ERROR_MESSAGE);
        }
    });

    // 取消按钮事件
    JButton cancelButton = (JButton) ((JPanel) frame.getContentPane().getComponent(1)).getComponent(1);
    cancelButton.addActionListener(e -> cancelShutdown());
}

private void startShutdownTimer(long delaySeconds) {
    remainingTime = delaySeconds;
    
    // 初始化线程池
    scheduler = Executors.newSingleThreadScheduledExecutor();
    
    // 执行关机命令
    scheduler.schedule(() -> {
        try {
            executeShutdownCommand();
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(frame, "关机命令执行失败: " + ex.getMessage(), 
                "错误", JOptionPane.ERROR_MESSAGE);
        }
    }, delaySeconds, TimeUnit.SECONDS);

    // 更新倒计时显示
    scheduler.scheduleAtFixedRate(() -> {
        remainingTime--;
        updateCountdownDisplay();
        
        if(remainingTime <= 0) {
            scheduler.shutdown();
            countdownLabel.setText("关机执行中...");
        }
    }, 0, 1, TimeUnit.SECONDS);
}

private void executeShutdownCommand() throws Exception {
    String os = System.getProperty("os.name").toLowerCase();
    ProcessBuilder pb;

    if(os.contains("win")) {
        pb = new ProcessBuilder("shutdown", "-s", "-t", "0");
    } else {
        pb = new ProcessBuilder("shutdown", "-h", "+1");
        // Linux/macOS需要立即生效需特殊处理
    }

    Process process = pb.start();
    int exitCode = process.waitFor();
    
    if(exitCode != 0) {
        throw new Exception("系统返回错误码: " + exitCode);
    }
}

3.3 实现倒计时显示

private void updateCountdownDisplay() {
    long hours = remainingTime / 3600;
    long minutes = (remainingTime % 3600) / 60;
    long seconds = remainingTime % 60;

    String timeStr = String.format("%02d:%02d:%02d", hours, minutes, seconds);
    countdownLabel.setText("剩余时间: " + timeStr);
}

private void cancelShutdown() {
    if(scheduler != null && !scheduler.isShutdown()) {
        scheduler.shutdownNow();
        try {
            // 执行取消关机命令
            String os = System.getProperty("os.name").toLowerCase();
            if(os.contains("win")) {
                Runtime.getRuntime().exec("shutdown -a");
            } else {
                Runtime.getRuntime().exec("shutdown -c");
            }
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(frame, "取消命令执行失败", "错误", JOptionPane.ERROR_MESSAGE);
        }
        countdownLabel.setText("任务已取消");
    }
}

3.4 程序入口

public static void main(String[] args) {
    SwingUtilities.invokeLater(() -> {
        new ShutdownTimer().frame.setVisible(true);
    });
}

四、功能增强建议

  1. 权限处理

    • 在Linux/macOS中,关机命令需要root权限,可添加sudo支持:

      pb = new ProcessBuilder("sudo", "shutdown", "-h", "+1");
    • 需要处理密码输入(可通过sudo配置免密码)

  2. 持久化存储

    • 添加配置保存功能(使用Preferences API):

      Preferences prefs = Preferences.userNodeForPackage(ShutdownTimer.class);
      prefs.put("last_time", timeField.getText());
  3. 系统托盘支持

    • 使用SystemTray类实现最小化到托盘功能

java.webp

五、常见问题解决

Q1: Linux下执行关机命令失败

  • 检查用户是否有sudo权限

  • 确认/sbin/shutdown路径是否在PATH环境变量中

Q2: 取消关机功能无效

  • Windows系统需要确保取消命令在关机倒计时内执行

  • Linux/macOS需检查shutdown进程是否存在

Q3: 跨平台时间单位转换错误

  • 使用TimeUnit进行标准化转换:

    long delay = TimeUnit.SECONDS.convert(time, unit);

六、项目打包与分发

  1. 生成可执行JAR

    jar cvfe ShutdownTimer.jar ShutdownTimer *.class
  2. Windows平台打包

    • 使用Launch4j生成EXE文件

    • 添加manifest文件请求管理员权限:

      <requestExecutionLevel admin="required"/>
  3. Linux平台打包

    • 转换为DEB/RPM包(使用fpm工具):

      fpm -s dir -t deb -n shutdown-timer -v 1.0 /path/to/app=/usr/local/bin

七、总结

本文通过一个完整的定时关机工具开发实例,演示了:

  1. Swing GUI开发的核心技巧

  2. 跨平台系统命令调用方法

  3. 定时任务调度最佳实践

  4. 异常处理与用户反馈机制

该工具可作为学习Java系统交互开发的入门项目,读者可在此基础上扩展以下功能:

  • 添加计划任务列表

  • 实现远程关机控制

  • 集成邮件/短信提醒功能

  • 开发Web版本(使用Spring Boot)

通过这个项目实践,开发者可以深入理解Java在系统级应用开发中的潜力,为后续开发更复杂的系统管理工具打下基础。

Java 定时关机
THE END
战地网
频繁记录吧,生活的本意是开心

相关推荐

JavaDB怎么进不去了?3个常见原因和解决办法
问题出在哪?先查连接状态 JavaDB进不去,最常见的就是服务没跑起来。你看,JavaDB默认用1527端口监听。如果连不上,大概率是它没启动或者端口被占了。用这段代码快速检测:...
2026-04-02 新闻资讯
202

Java版连锁挖矿mod叫什么名字
主流连锁挖矿mod名字汇总 根据抖音和百度贴吧的玩家反馈,Java版《我的世界》连锁挖矿mod有好几个常用名字。最常被推荐的是FTB Ultimine。它在抖音多个视频里被提到,能一...
2026-04-02 新闻资讯
211

Java日志管理框架:Log4j、SLF4J、Logback对比与使用方法详解
java主流日志框架中,Log4j 1.x作为早期标准,Log4j 2.x通过重构实现性能飞跃,Logback作为Log4j的继承者以原生SLF4J支持成为主流选择,而SLF4J作为日志门面,通过抽象层实现...
2025-09-15 编程技术
947

Java 与 MySQL 性能优化:MySQL全文检索查询优化实践
本文聚焦Java与MySQL协同环境下的全文检索优化实践,从索引策略、查询调优、参数配置到Java层优化,深入解析如何释放全文检索的潜力,为高并发、大数据量场景提供稳定高效的搜...
2025-09-13 编程技术
927

JavaScript 中 instanceof 的作用及使用方法详解
在 JavaScript 的类型检查体系中,instanceof 是一个重要的操作符,用于判断一个对象是否属于某个构造函数的实例或其原型链上的类型。本文ZHANID工具网将系统讲解 instanceof...
2025-09-11 编程技术
999

Java与MySQL数据库连接实战:JDBC使用教程
JDBC(Java Database Connectivity)作为Java标准API,为开发者提供了统一的数据访问接口,使得Java程序能够无缝连接各类关系型数据库。本文ZHANID工具网将以MySQL数据库为例...
2025-09-11 编程技术
812