You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java带GUI定时关机/重启/休眠程序:定时器实现求助

实现Java GUI程序的定时器功能方案

嘿,很高兴看到你已经搞定了GUI界面和核心的系统操作逻辑!针对定时器的需求,我给你分享两种非常适合Swing GUI场景的实现方案,你可以根据自己的需求选:

方案一:使用Swing专属的javax.swing.Timer(推荐)

这个工具是专门为Swing GUI设计的,它会在**事件调度线程(EDT)**中执行任务,不会阻塞你的界面,非常适合简单的延迟执行场景。

实现步骤:

  1. 先把用户输入的等待时长转换成毫秒(比如用户输入的是分钟,就乘以60*1000)
  2. 创建Timer实例,指定延迟时间和触发时要执行的任务
  3. 在任务里调用你已经写好的关机/重启/休眠方法
  4. 启动定时器

代码示例(结合你的现有类):

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ContactEditorUI extends javax.swing.JFrame {
    private Timer countdownTimer; // 定义定时器实例

    public ContactEditorUI() {
        initComponents();
        // 可以在这里给"开始执行"按钮绑定点击事件
        jStartButton.addActionListener(e -> startScheduledOperation());
    }

    // 处理定时器启动逻辑
    private void startScheduledOperation() {
        // 1. 获取并校验用户输入的时长(示例为分钟)
        String input = jDurationInput.getText();
        int minutes;
        try {
            minutes = Integer.parseInt(input);
            if (minutes <= 0) {
                javax.swing.JOptionPane.showMessageDialog(this, "请输入大于0的时长!");
                return;
            }
        } catch (NumberFormatException e) {
            javax.swing.JOptionPane.showMessageDialog(this, "请输入有效的数字!");
            return;
        }
        long delayMillis = minutes * 60 * 1000; // 转换成毫秒

        // 2. 创建定时器执行的任务
        ActionListener task = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                executeSystemOperation();
                countdownTimer.stop(); // 任务执行完后停止定时器
            }
        };

        // 3. 初始化并启动定时器
        countdownTimer = new Timer((int) delayMillis, task);
        countdownTimer.setRepeats(false); // 只执行一次
        countdownTimer.start();

        javax.swing.JOptionPane.showMessageDialog(this, "定时器已启动,将在" + minutes + "分钟后执行操作!");
    }

    // 你已实现的系统操作方法(示例)
    private void executeSystemOperation() {
        String command = "";
        // 根据用户选择的操作(比如单选框)确定命令
        if (jShutdownRadio.isSelected()) {
            command = "shutdown /s /t 0"; // Windows关机命令,跨平台需调整
        } else if (jRestartRadio.isSelected()) {
            command = "shutdown /r /t 0";
        } else if (jSleepRadio.isSelected()) {
            command = "rundll32.exe powrprof.dll,SetSuspendState 0,1,0";
        }

        try {
            Runtime.getRuntime().exec(command);
        } catch (IOException ex) {
            Logger.getLogger(ContactEditorUI.class.getName()).log(Level.SEVERE, null, ex);
            javax.swing.JOptionPane.showMessageDialog(this, "执行操作失败:" + ex.getMessage());
        }
    }

    // 取消定时器的方法(绑定给"取消"按钮)
    private void cancelTimer() {
        if (countdownTimer != null && countdownTimer.isRunning()) {
            countdownTimer.stop();
            javax.swing.JOptionPane.showMessageDialog(this, "定时器已取消!");
        }
    }

    // 你的initComponents()方法和其他现有代码...
    private void initComponents() {
        // 这里是你自动生成的GUI组件代码
        jDurationInput = new javax.swing.JTextField();
        jStartButton = new javax.swing.JButton();
        jShutdownRadio = new javax.swing.JRadioButton();
        jRestartRadio = new javax.swing.JRadioButton();
        jSleepRadio = new javax.swing.JRadioButton();
        // ...其余组件初始化代码
    }

    // 声明GUI组件
    private javax.swing.JTextField jDurationInput;
    private javax.swing.JButton jStartButton;
    private javax.swing.JRadioButton jShutdownRadio;
    private javax.swing.JRadioButton jRestartRadio;
    private javax.swing.JRadioButton jSleepRadio;
}

方案二:使用ScheduledExecutorService(更灵活)

如果你的需求更复杂(比如需要周期性执行任务,或者不想依赖Swing的Timer),可以用Java并发包中的这个工具。它基于线程池调度,功能更强大。

实现步骤:

  1. 创建ScheduledExecutorService实例
  2. 计算延迟时间
  3. 提交一个Runnable任务,执行系统操作
  4. 程序关闭时记得关闭调度器,避免资源泄漏

代码示例:

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ScheduledFuture;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ContactEditorUI extends javax.swing.JFrame {
    private ScheduledExecutorService scheduler;
    private ScheduledFuture<?> scheduledTask; // 用于取消任务

    public ContactEditorUI() {
        initComponents();
        scheduler = Executors.newSingleThreadScheduledExecutor(); // 创建单线程调度器
        jStartButton.addActionListener(e -> startScheduledOperation());
        jCancelButton.addActionListener(e -> cancelTimer());
    }

    private void startScheduledOperation() {
        // 同样先处理用户输入的时长
        String input = jDurationInput.getText();
        int minutes;
        try {
            minutes = Integer.parseInt(input);
            if (minutes <= 0) {
                javax.swing.JOptionPane.showMessageDialog(this, "请输入大于0的时长!");
                return;
            }
        } catch (NumberFormatException e) {
            javax.swing.JOptionPane.showMessageDialog(this, "请输入有效的数字!");
            return;
        }

        // 提交延迟任务
        scheduledTask = scheduler.schedule(() -> {
            executeSystemOperation();
        }, minutes, TimeUnit.MINUTES);

        javax.swing.JOptionPane.showMessageDialog(this, "定时器已启动,将在" + minutes + "分钟后执行操作!");
    }

    private void cancelTimer() {
        if (scheduledTask != null && !scheduledTask.isDone()) {
            scheduledTask.cancel(false);
            javax.swing.JOptionPane.showMessageDialog(this, "定时器已取消!");
        }
    }

    // 窗口关闭时关闭调度器
    @Override
    protected void processWindowEvent(java.awt.event.WindowEvent e) {
        super.processWindowEvent(e);
        if (e.getID() == java.awt.event.WindowEvent.WINDOW_CLOSING) {
            scheduler.shutdown();
        }
    }

    // 你的executeSystemOperation()和其他现有代码...
    private void executeSystemOperation() {
        // 这里是你已实现的系统命令执行逻辑
    }

    // 你的initComponents()和组件声明...
}

额外提醒:

  • 一定要做用户输入的合法性校验,避免非法输入导致程序崩溃
  • 如果是跨平台程序,要注意不同操作系统的关机/重启命令差异(比如Linux用shutdown -h now,macOS用pmset sleepnow)
  • 方案一中的Swing Timer必须在EDT线程中操作,在组件的事件监听方法里调用是安全的

内容的提问来源于stack exchange,提问作者Steve

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:44:31