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

如何在AWS SDK版本2中获取进度详情并集成Swing自定义进度条

实现S3上传进度在Swing进度条中展示

核心思路

  • 自定义TransferListener替代默认的LoggingTransferListener,捕获上传进度事件
  • 在进度回调中,使用Swing的EDT线程安全更新进度条组件,避免UI线程阻塞或异常

实现步骤与代码

1. 自定义TransferListener

创建监听类,实现TransferListener接口,在transferProgressChanged方法中获取进度数据,并触发UI更新:

import software.amazon.awssdk.transfer.s3.progress.TransferProgress;
import software.amazon.awssdk.transfer.s3.progress.TransferListener;
import javax.swing.JProgressBar;
import java.awt.EventQueue;

public class SwingTransferListener implements TransferListener {
    private final JProgressBar progressBar;

    public SwingTransferListener(JProgressBar progressBar) {
        this.progressBar = progressBar;
    }

    @Override
    public void transferInitiated(Context context) {
        // 上传初始化时设置进度条最小值
        EventQueue.invokeLater(() -> progressBar.setMinimum(0));
    }

    @Override
    public void transferProgressChanged(Context context) {
        TransferProgress progress = context.progress();
        long bytesTransferred = progress.bytesTransferred();
        long totalBytes = progress.totalBytesToTransfer();
        
        // 计算百分比,避免除零
        int percentage = totalBytes > 0 ? (int) ((bytesTransferred * 100) / totalBytes) : 0;
        
        // 必须在EDT线程更新UI
        EventQueue.invokeLater(() -> {
            progressBar.setMaximum(100);
            progressBar.setValue(percentage);
            progressBar.setString(percentage + "%");
            progressBar.setStringPainted(true);
        });
    }

    @Override
    public void transferCompleted(Context context) {
        // 上传完成后设置进度为100%
        EventQueue.invokeLater(() -> {
            progressBar.setValue(100);
            progressBar.setString("上传完成");
        });
    }

    @Override
    public void transferFailed(Context context) {
        // 上传失败时更新提示
        EventQueue.invokeLater(() -> progressBar.setString("上传失败"));
    }
}

2. 整合Swing界面与S3上传逻辑

在Swing窗口中初始化进度条,并将自定义监听器传入S3TransferManager的上传配置:

import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3ClientConfiguration;
import software.amazon.awssdk.transfer.s3.S3TransferManager;
import software.amazon.awssdk.transfer.s3.FileUpload;
import javax.swing.*;
import java.nio.file.Paths;

public class S3UploadUI extends JFrame {
    private JProgressBar uploadProgressBar;

    public S3UploadUI() {
        initUI();
    }

    private void initUI() {
        setTitle("S3文件上传");
        setSize(400, 150);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        uploadProgressBar = new JProgressBar();
        add(uploadProgressBar);

        // 启动上传线程,避免阻塞UI线程
        new Thread(this::startUpload).start();
    }

    private void startUpload() {
        String region = "your-region";
        AwsCredentialsProvider awsCredentialsProvider = // 初始化你的凭证提供者
                // 示例:DefaultCredentialsProvider.create();
                null;

        S3TransferManager s3TransferManager = S3TransferManager
                .builder()
                .s3ClientConfiguration(S3ClientConfiguration.builder()
                        .region(Region.of(region))
                        .credentialsProvider(awsCredentialsProvider)
                        .build())
                .build();

        FileUpload upload = s3TransferManager.uploadFile(u -> u
                .source(Paths.get("file1.txt"))
                .putObjectRequest(p -> p.bucket("bucket").key("file1.txt"))
                .overrideConfiguration(o -> o.addListener(new SwingTransferListener(uploadProgressBar))));

        try {
            upload.completionFuture().join();
        } catch (Exception e) {
            // 处理上传异常
            EventQueue.invokeLater(() -> JOptionPane.showMessageDialog(this, "上传出错: " + e.getMessage()));
        } finally {
            s3TransferManager.close();
        }
    }

    public static void main(String[] args) {
        // 在EDT线程启动Swing界面
        EventQueue.invokeLater(() -> {
            S3UploadUI ui = new S3UploadUI();
            ui.setVisible(true);
        });
    }
}

关键注意事项

  • 线程安全:所有UI操作必须通过EventQueue.invokeLater(或SwingUtilities.invokeLater)在EDT线程执行,否则会导致Swing线程安全问题
  • 进度计算:通过TransferProgress的bytesTransferred和totalBytesToTransfer计算百分比,注意处理totalBytes为0的边界情况(比如空文件)
  • 资源释放:上传完成后务必关闭S3TransferManager,避免资源泄漏
  • 异常处理:在completionFuture().join()处捕获异常,并用UI提示用户上传失败信息

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 16:18:34