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

多速度JProgressBar开发问题:指定进度处仅暂停当前进度条而非整个应用

解决Swing进度条暂停时UI卡死的问题

嘿,我懂你遇到的麻烦了——你在Swing的事件派发线程(EDT)里调用Thread.sleep(),直接把整个UI给卡死了对吧?这很正常,因为EDT负责处理所有的界面渲染和用户交互,你把它堵住的话,整个程序就完全没反应了。

问题根源

你的当前代码里,Timer的ActionListener是在EDT上执行的,当你调用Thread.sleep(1000)时,EDT被阻塞,所有UI更新和用户操作都停了,自然整个窗口僵住。

解决方案:用Swing Timer实现非阻塞暂停

我们可以用第二个Timer来处理暂停逻辑:当进度条到达指定值时,停止主进度更新的Timer,启动一个延时2秒的Timer,时间到了再重启主Timer。这样EDT不会被阻塞,UI依然能响应。

另外,如果你需要多个不同速度的进度条,每个进度条应该有独立的状态(计数器、步长)和Timer,这样它们的速度和暂停逻辑可以分开控制。

示例代码:单Timer控制多进度条(同速度)

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

// 假设这是你的Sim1类的部分代码
public class Sim1 {
    private JProgressBar jjProgressBar;
    private JProgressBar jjProgressBar2;
    private JProgressBar jjProgressBar3;
    private JRadioButton jRadioButton1;

    public void initProgressBars() {
        Timer mainTimer;
        Timer pauseTimer;

        // 初始化暂停Timer:只执行一次,2秒后重启主Timer
        pauseTimer = new Timer(2000, e -> {
            mainTimer.start();
            pauseTimer.stop();
        });
        pauseTimer.setRepeats(false);

        // 主进度更新Timer的监听器
        ActionListener mainListener = new ActionListener() {
            int counter = 0;
            int delta = 1;
            final int min = 0;
            final int max = 100;

            @Override
            public void actionPerformed(ActionEvent ae) {
                if (!jRadioButton1.isSelected()) {
                    return; // 单选按钮未选中时不更新
                }

                counter += delta;
                // 处理进度条往返逻辑
                if (counter < min || counter > max) {
                    delta *= -1;
                }
                counter = Math.min(max, Math.max(min, counter));

                // 更新所有进度条
                jjProgressBar.setValue(counter);
                jjProgressBar2.setValue(counter);
                jjProgressBar3.setValue(counter);

                // 检查是否需要暂停(25/50/75时)
                if (counter == 25 || counter == 50 || counter == 75) {
                    mainTimer.stop();
                    pauseTimer.start();
                }
            }
        };

        mainTimer = new Timer(100, mainListener);
        mainTimer.start();
    }
}

示例代码:多Timer控制独立进度条(不同速度)

如果要让每个进度条有不同的速度,给每个进度条单独创建Timer即可:

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

public class Sim1 {
    private JProgressBar jjProgressBar;
    private JProgressBar jjProgressBar2;
    private JProgressBar jjProgressBar3;
    private JRadioButton jRadioButton1;

    public void initProgressBars() {
        // 进度条1:速度快(100ms间隔)
        setupProgressBar(jjProgressBar, 100);
        // 进度条2:速度中等(200ms间隔)
        setupProgressBar(jjProgressBar2, 200);
        // 进度条3:速度慢(300ms间隔)
        setupProgressBar(jjProgressBar3, 300);
    }

    private void setupProgressBar(JProgressBar bar, int delay) {
        Timer barTimer = new Timer(delay, new ActionListener() {
            int counter = 0;
            int delta = 1;
            final int min = 0;
            final int max = 100;

            @Override
            public void actionPerformed(ActionEvent e) {
                if (!jRadioButton1.isSelected()) {
                    return;
                }

                counter += delta;
                if (counter < min || counter > max) {
                    delta *= -1;
                }
                counter = Math.min(max, Math.max(min, counter));
                bar.setValue(counter);

                // 触发暂停逻辑
                if (counter == 25 || counter == 50 || counter == 75) {
                    barTimer.stop();
                    // 2秒后重启当前进度条的Timer
                    new Timer(2000, pauseEvt -> barTimer.start()).start();
                }
            }
        });
        barTimer.start();
    }
}

关键要点

  • 永远不要阻塞EDT:Thread.sleep()、wait()等阻塞操作绝对不能在EDT里执行,这是Swing开发的核心原则。
  • 用Swing Timer处理定时任务:Swing Timer的事件在EDT上执行,但启动/停止操作不会阻塞线程,是Swing中处理定时UI更新的正确方式。
  • 独立状态管理:多个进度条需要各自的计数器、步长和Timer,才能实现不同速度的独立控制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:26:04