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

Java实现一周倒计时GUI:解决界面更新与时间转换难题

问题解决与代码修正

初始需求问题解决

1. 总秒数转「天:时:分:秒」格式

利用TimeUnit工具类分步拆解总秒数,结合格式化补零实现统一格式:

private static String formatSeconds(long totalSeconds) {
    long days = TimeUnit.SECONDS.toDays(totalSeconds);
    totalSeconds -= TimeUnit.DAYS.toSeconds(days);
    
    long hours = TimeUnit.SECONDS.toHours(totalSeconds);
    totalSeconds -= TimeUnit.HOURS.toSeconds(hours);
    
    long minutes = TimeUnit.SECONDS.toMinutes(totalSeconds);
    totalSeconds -= TimeUnit.MINUTES.toSeconds(minutes);
    
    long seconds = totalSeconds;
    // 补零保证格式统一,如1天2小时3分4秒显示为01:02:03:04
    return String.format("%02d:%02d:%02d:%02d", days, hours, minutes, seconds);
}

2. 关联JLabel更新GUI

Swing组件必须在**事件调度线程(EDT)**中修改,需通过SwingUtilities.invokeLater()将更新操作提交到EDT执行,避免线程安全问题。


后续GUI更新问题修正

你当前代码的核心问题:多线程拆分时间逻辑导致不同步、每秒新建GUI实例而非更新现有界面、静态变量引发线程风险。以下是修正后的完整代码:

import java.util.concurrent.*;
import javax.swing.*;
import static java.util.concurrent.TimeUnit.SECONDS;

public class Countdown {
    private static final long TOTAL_SECONDS = 7 * 24 * 60 * 60; // 1周总秒数
    private long remainingSeconds = TOTAL_SECONDS;
    private final JLabel timerLabel;

    public Countdown() {
        // 初始化GUI
        JFrame frame = new JFrame("Countdown Timer");
        timerLabel = new JLabel(formatSeconds(remainingSeconds));
        timerLabel.setFont(timerLabel.getFont().deriveFont(24f)); // 放大字体提升可读性

        JPanel panel = new JPanel();
        panel.add(timerLabel);
        
        frame.add(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null); // 窗口居中显示
        frame.setVisible(true);

        // 启动倒计时任务
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
        scheduler.scheduleAtFixedRate(this::updateTimer, 0, 1, SECONDS);
    }

    private void updateTimer() {
        remainingSeconds--;
        // 倒计时结束自动重置
        if (remainingSeconds < 0) {
            remainingSeconds = TOTAL_SECONDS;
        }
        final String timeText = formatSeconds(remainingSeconds);
        // 在EDT中安全更新GUI文本
        SwingUtilities.invokeLater(() -> timerLabel.setText(timeText));
    }

    private static String formatSeconds(long totalSeconds) {
        long days = SECONDS.toDays(totalSeconds);
        totalSeconds -= TimeUnit.DAYS.toSeconds(days);
        
        long hours = SECONDS.toHours(totalSeconds);
        totalSeconds -= TimeUnit.HOURS.toSeconds(hours);
        
        long minutes = SECONDS.toMinutes(totalSeconds);
        totalSeconds -= TimeUnit.MINUTES.toSeconds(minutes);
        
        long seconds = totalSeconds;
        return String.format("%02d:%02d:%02d:%02d", days, hours, minutes, seconds);
    }

    public static void main(String[] args) {
        // 在EDT中启动GUI,符合Swing线程规则
        SwingUtilities.invokeLater(Countdown::new);
    }
}

关键改进说明

  • 单一倒计时逻辑:用单个任务处理时间计算,避免多线程不同步
  • EDT安全更新:所有GUI操作通过SwingUtilities.invokeLater()提交到EDT
  • 避免重复实例:仅初始化一次GUI,每次更新仅修改JLabel文本
  • 自动循环重置:倒计时结束后自动恢复为1周时长
  • 格式统一:通过格式化补零保证时间显示美观规范

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 10:48:12