如何在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
相关产品推荐
相关产品推荐

