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

Java Swing GUI倒计时实现求助:界面无法实时刷新

Java Swing 倒计时实时刷新问题解决方案

问题核心

Swing的UI组件必须在**事件调度线程(EDT)**中更新,普通线程的Sleep()会阻塞EDT,直接修改UI也可能因为不在EDT中导致界面不刷新。使用Swing自带的javax.swing.Timer是最佳方案,它的任务会自动在EDT中执行,既不会阻塞UI,又能保证实时刷新。

修正后的完整代码

CurrentTime类(保留原逻辑)

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class CurrentTime {
    public String SystemDate(){
        // 获取系统默认时区当前时间
        LocalDateTime now_time = LocalDateTime.now();
        // 对时间进行格式化
        DateTimeFormatter ofPattern = DateTimeFormatter.ofPattern("yyyy年MM月dd日  hh时mm分ss秒");
        // 返回格式化后的时间字符串
        return now_time.format(ofPattern);
    }
}

MainGUI类(核心修改,加入Swing Timer实现实时刷新)

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class MainGUI {
    public void showGUI(){
        JFrame frame = new JFrame("目标倒计时");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600,400);
        frame.setLocation(500,150);

        JPanel jpanel = new JPanel(new BorderLayout()); // 指定BorderLayout,确保布局参数生效

        CurrentTime currentTime = new CurrentTime();
        JLabel showLabel = new JLabel(currentTime.SystemDate());
        showLabel.setFont(new Font("宋体",0,20));
        jpanel.add(showLabel, BorderLayout.PAGE_START);

        // 创建Swing Timer,每隔1000毫秒(1秒)触发一次更新
        Timer timer = new Timer(1000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // 在EDT中更新UI文本,自动触发界面刷新
                showLabel.setText(currentTime.SystemDate());
            }
        });
        timer.start(); // 启动定时器

        frame.add(jpanel);
        frame.setVisible(true); // 最后设置窗口可见,确保组件加载完成
    }
}

Main类(保留原逻辑)

import javax.swing.*;

public class Main {
    public static void main(String[] args) {
        MainGUI mainGUI = new MainGUI();
        SwingUtilities.invokeLater(mainGUI::showGUI);
    }
}

关键改动说明

  1. 组件布局修正:给JPanel指定BorderLayout,原代码未指定布局导致BorderLayout.PAGE_START参数无效。
  2. 使用Swing Timer:代替普通线程+Sleep,Timer的任务自动在EDT中执行,避免UI阻塞和刷新异常。
  3. 窗口可见时机调整:将frame.setVisible(true)放在组件添加完成后,确保所有组件加载完毕再显示窗口。
  4. 实时更新逻辑:在Timer的actionPerformed方法中直接调用showLabel.setText(),Swing会自动处理界面刷新。

如果要实现倒计时功能(而非当前时间刷新),可修改Timer任务逻辑:

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

// 预设目标时间(比如10分钟后)
LocalDateTime targetTime = LocalDateTime.now().plusMinutes(10);

Timer timer = new Timer(1000, new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        LocalDateTime now = LocalDateTime.now();
        long seconds = ChronoUnit.SECONDS.between(now, targetTime);
        if (seconds <= 0) {
            showLabel.setText("倒计时结束!");
            ((Timer)e.getSource()).stop(); // 停止定时器
            return;
        }
        // 格式化倒计时为 时:分:秒
        long hours = seconds / 3600;
        long minutes = (seconds % 3600) / 60;
        long secs = seconds % 60;
        showLabel.setText(String.format("剩余时间:%02d:%02d:%02d", hours, minutes, secs));
    }
});
timer.start();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 11:35:39