在Java Swing GUI开发中,实现实时更新的计时器与倒计时功能,核心是利用Swing自带的定时器类配合界面组件完成动态更新,避免手动创建线程导致界面卡顿或者更新异常的问题。

核心实现类介绍
实现这两个功能主要用到两个核心类:
- javax.swing.Timer:Swing提供的定时器类,会在指定间隔触发事件,并且事件处理在事件派发线程中执行,天然适配Swing组件的更新操作,不会出现跨线程更新界面的问题。
- JLabel:用于展示计时和倒计时的实时数值,通过定时器触发事件时更新其文本内容即可实现界面刷新。
实时计时器功能实现
实时计时器的逻辑是记录开始时间,每隔固定间隔计算当前时间与开始时间的差值,转换为时分秒格式后更新到界面上。
实现步骤
- 初始化计时器相关变量,记录开始时间戳。
- 创建Swing Timer实例,设置触发间隔为1000毫秒,即每秒更新一次。
- 在定时器的事件处理逻辑中计算时间差,格式化后更新JLabel的内容。
- 添加开始、暂停、重置按钮控制计时器的运行状态。
完整代码示例
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Date;
public class LiveTimerFrame extends JFrame {
// 计时开始时间戳
private long startTime = 0;
// 是否正在计时
private boolean isRunning = false;
// 显示计时的标签
private JLabel timerLabel;
// Swing定时器
private Timer swingTimer;
// 时间格式化
private SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
public LiveTimerFrame() {
setTitle("实时计时器");
setSize(400, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout(FlowLayout.CENTER, 20, 30));
// 初始化显示标签
timerLabel = new JLabel("00:00:00");
timerLabel.setFont(new Font("微软雅黑", Font.BOLD, 30));
add(timerLabel);
// 初始化定时器,间隔1000毫秒触发
swingTimer = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (isRunning) {
// 计算当前时间与开始时间的差值
long diff = System.currentTimeMillis() - startTime;
// 转换为时分秒格式
Date diffDate = new Date(diff);
timerLabel.setText(timeFormat.format(diffDate));
}
}
});
// 开始按钮
JButton startBtn = new JButton("开始");
startBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!isRunning) {
// 记录开始时间
startTime = System.currentTimeMillis();
isRunning = true;
swingTimer.start();
}
}
});
add(startBtn);
// 暂停按钮
JButton pauseBtn = new JButton("暂停");
pauseBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (isRunning) {
isRunning = false;
swingTimer.stop();
}
}
});
add(pauseBtn);
// 重置按钮
JButton resetBtn = new JButton("重置");
resetBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
isRunning = false;
swingTimer.stop();
timerLabel.setText("00:00:00");
startTime = 0;
}
});
add(resetBtn);
}
public static void main(String[] args) {
// 在事件派发线程中创建界面
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new LiveTimerFrame().setVisible(true);
}
});
}
}
倒计时功能实现
倒计时的逻辑是预先设置总时长,每隔固定间隔减少剩余时长,转换为时分秒格式更新界面,当剩余时长为0时停止定时器并提示。
实现步骤
- 提供输入倒计总时长的组件,比如输入框或者下拉选择。
- 初始化剩余时长变量,创建Swing Timer实例,间隔1000毫秒触发。
- 定时器事件中减少剩余时长,格式化后更新界面,剩余时长为0时停止定时器。
- 添加开始、暂停、重置按钮控制倒计时状态。
完整代码示例
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class CountdownFrame extends JFrame {
// 剩余时长,单位秒
private int remainSeconds = 0;
// 总时长,单位秒
private int totalSeconds = 0;
// 是否正在倒计时
private boolean isRunning = false;
// 显示倒计时的标签
private JLabel countdownLabel;
// 输入时长的输入框
private JTextField timeInputField;
// Swing定时器
private Timer swingTimer;
public CountdownFrame() {
setTitle("倒计时功能");
setSize(400, 250);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout(FlowLayout.CENTER, 20, 20));
// 输入提示
JLabel inputTip = new JLabel("请输入倒计时总时长(秒):");
add(inputTip);
// 输入框
timeInputField = new JTextField(10);
add(timeInputField);
// 显示倒计时的标签
countdownLabel = new JLabel("00:00:00");
countdownLabel.setFont(new Font("微软雅黑", Font.BOLD, 30));
add(countdownLabel);
// 初始化定时器,间隔1000毫秒触发
swingTimer = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (isRunning && remainSeconds > 0) {
remainSeconds--;
// 格式化剩余时长为时分秒
int hours = remainSeconds / 3600;
int minutes = (remainSeconds % 3600) / 60;
int seconds = remainSeconds % 60;
String timeStr = String.format("%02d:%02d:%02d", hours, minutes, seconds);
countdownLabel.setText(timeStr);
}
// 剩余时长为0时停止
if (remainSeconds == 0 && isRunning) {
isRunning = false;
swingTimer.stop();
JOptionPane.showMessageDialog(CountdownFrame.this, "倒计时结束!");
}
}
});
// 开始按钮
JButton startBtn = new JButton("开始");
startBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!isRunning) {
try {
// 获取输入的总时长
totalSeconds = Integer.parseInt(timeInputField.getText().trim());
if (totalSeconds <= 0) {
JOptionPane.showMessageDialog(CountdownFrame.this, "请输入大于0的时长!");
return;
}
remainSeconds = totalSeconds;
isRunning = true;
swingTimer.start();
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(CountdownFrame.this, "请输入有效的数字!");
}
}
}
});
add(startBtn);
// 暂停按钮
JButton pauseBtn = new JButton("暂停");
pauseBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (isRunning) {
isRunning = false;
swingTimer.stop();
}
}
});
add(pauseBtn);
// 重置按钮
JButton resetBtn = new JButton("重置");
resetBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
isRunning = false;
swingTimer.stop();
remainSeconds = 0;
countdownLabel.setText("00:00:00");
timeInputField.setText("");
}
});
add(resetBtn);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new CountdownFrame().setVisible(true);
}
});
}
}
功能整合与注意事项
如果需要在一个界面中同时实现计时器和倒计时功能,可以将两个功能的逻辑封装到不同的面板中,添加到同一个JFrame中即可。实现过程中需要注意以下几点:
- 不要使用
Thread.sleep()或者手动创建线程更新Swing组件,否则会导致界面卡顿甚至无响应,Swing Timer是官方推荐的定时更新方案。 - 所有Swing组件的创建和更新都需要在事件派发线程中执行,因此主方法中要使用
SwingUtilities.invokeLater。 - 时间格式化时需要注意SimpleDateFormat的线程安全问题,单线程场景下使用没有问题,多线程场景需要额外处理。
- 倒计时的输入需要做合法性校验,避免用户输入非数字或者负数导致功能异常。
使用Swing Timer实现定时更新功能,既能够保证界面更新的线程安全,又不需要开发者手动处理线程同步问题,是Java Swing GUI中实现实时更新功能的最优选择。
Java_SwingTimer计时器倒计时GUI修改时间:2026-06-14 02:12:49