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

将不确定状态JProgressBar加入JTable后动画停止的原因排查

问题原因与解决方案

核心问题

  1. 组件无法同时归属两个父容器:你把同一个JProgressBar实例(bar)既放在界面顶部,又作为表格单元格渲染器返回。Swing规则是每个组件只能有一个父容器,当渲染器第一次返回该实例时,它会被自动从顶部布局中移除,绑定到表格的渲染上下文,导致顶部进度条停止动画甚至消失。
  2. 表格渲染器的复用逻辑:表格渲染器返回的组件仅用于绘制单元格的“快照”,不会作为持久化子组件存在于表格中。不确定进度条的动画依赖Swing事件调度线程(EDT)持续更新UI,但渲染器组件不会被EDT持续追踪,因此动画会终止。

修复方案

修改表格单元格渲染器,每次返回独立的JProgressBar实例,确保每个渲染组件不被其他容器持有,且能触发正常动画:

@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    JProgressBar progressBar = new JProgressBar();
    progressBar.setIndeterminate(true);
    
    // 适配表格选中状态的样式
    if (isSelected) {
        progressBar.setBackground(table.getSelectionBackground());
        progressBar.setForeground(table.getSelectionForeground());
    } else {
        progressBar.setBackground(table.getBackground());
        progressBar.setForeground(table.getForeground());
    }
    
    return progressBar;
}

此时你可以保留原来的全局bar变量作为顶部示例进度条,因为渲染器返回的是全新实例,不会和顶部进度条产生冲突。

额外优化(可选)

如果担心频繁创建JProgressBar实例的性能问题,可以实现简单的对象池复用组件(大多数场景下直接创建新实例性能足够,对象池收益有限):

private List<JProgressBar> barPool = new ArrayList<>();

@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    JProgressBar progressBar;
    if (barPool.isEmpty()) {
        progressBar = new JProgressBar();
        progressBar.setIndeterminate(true);
    } else {
        progressBar = barPool.remove(0);
    }
    
    // 设置样式
    if (isSelected) {
        progressBar.setBackground(table.getSelectionBackground());
        progressBar.setForeground(table.getSelectionForeground());
    } else {
        progressBar.setBackground(table.getBackground());
        progressBar.setForeground(table.getForeground());
    }
    
    // 渲染完成后放回对象池
    EventQueue.invokeLater(() -> barPool.add(progressBar));
    
    return progressBar;
}

验证效果

修改后,顶部进度条会持续正常动画,表格中新增行的不确定进度条也会正常播放动画,不会出现互相干扰的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 23:53:17