本文将通过一个完整的Java项目实例,演示如何开发一款跨平台的定时关机小工具。该工具支持Windows/Linux/macOS系统,具备可视化界面、倒计时显示、任务取消等核心功能,适合Java初学者学习系统交互和GUI开发。
一、功能需求分析
核心功能
设置定时关机时间(支持秒/分/时单位)
实时倒计时显示
任务取消功能
跨平台兼容(Windows/Linux/macOS)
技术选型
GUI框架:Swing(轻量级,无需额外依赖)
定时任务:
ScheduledExecutorService(JDK自带,线程池管理)系统交互:
ProcessBuilder(跨平台命令执行)
二、系统命令研究
不同操作系统关机命令差异较大,需做兼容处理:
| 操作系统 | 关机命令 | 取消关机命令 |
|---|---|---|
| Windows | shutdown -s -t 秒数 | shutdown -a |
| Linux | shutdown -h +分钟数 | shutdown -c |
| macOS | shutdown -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);
});
}四、功能增强建议
权限处理:
在Linux/macOS中,关机命令需要root权限,可添加sudo支持:
pb = new ProcessBuilder("sudo", "shutdown", "-h", "+1");需要处理密码输入(可通过
sudo配置免密码)持久化存储:
添加配置保存功能(使用
PreferencesAPI):Preferences prefs = Preferences.userNodeForPackage(ShutdownTimer.class); prefs.put("last_time", timeField.getText());系统托盘支持:
使用
SystemTray类实现最小化到托盘功能

五、常见问题解决
Q1: Linux下执行关机命令失败
检查用户是否有sudo权限
确认
/sbin/shutdown路径是否在PATH环境变量中
Q2: 取消关机功能无效
Windows系统需要确保取消命令在关机倒计时内执行
Linux/macOS需检查shutdown进程是否存在
Q3: 跨平台时间单位转换错误
使用
TimeUnit进行标准化转换:long delay = TimeUnit.SECONDS.convert(time, unit);
六、项目打包与分发
生成可执行JAR:
jar cvfe ShutdownTimer.jar ShutdownTimer *.class
Windows平台打包:
使用Launch4j生成EXE文件
添加manifest文件请求管理员权限:
<requestExecutionLevel admin="required"/>
Linux平台打包:
转换为DEB/RPM包(使用fpm工具):
fpm -s dir -t deb -n shutdown-timer -v 1.0 /path/to/app=/usr/local/bin
七、总结
本文通过一个完整的定时关机工具开发实例,演示了:
Swing GUI开发的核心技巧
跨平台系统命令调用方法
定时任务调度最佳实践
异常处理与用户反馈机制
该工具可作为学习Java系统交互开发的入门项目,读者可在此基础上扩展以下功能:
添加计划任务列表
实现远程关机控制
集成邮件/短信提醒功能
开发Web版本(使用Spring Boot)
通过这个项目实践,开发者可以深入理解Java在系统级应用开发中的潜力,为后续开发更复杂的系统管理工具打下基础。
本文由@战地网 原创发布。
该文章观点仅代表作者本人,不代表本站立场。本站不承担相关法律责任。
如若转载,请注明出处:https://www.zhanid.com/biancheng/4321.html




















