在TableView JavaFX中实现ProgressIndicator的S3 ProgressListener
我正在创建一个桌面软件,根据用户配置的调度程序定期备份用户数据。它还具有手动上传文件的功能。我在在TableView JavaFX中实现ProgressIndicator的S3 ProgressListener,java,javafx,amazon-s3,aws-sdk,progress-indicator,Java,Javafx,Amazon S3,Aws Sdk,Progress Indicator,我正在创建一个桌面软件,根据用户配置的调度程序定期备份用户数据。它还具有手动上传文件的功能。我在表格单元格中使用ProgressIndicator来指示上载状态 问题是: 如果我只上传一个文件并等待上传过程完成,ProgressIndicator工作正常 但是,如果在第一个文件完全上载之前尝试上载另一个文件,则ProgressIndicator将重置为0%,并开始上载这两个文件。 这是我的工作代码(我根据SO上的不同示例编译) Directory.java import java.util.O
表格单元格中使用ProgressIndicator
来指示上载状态
问题是:
如果我只上传一个文件并等待上传过程完成,ProgressIndicator
工作正常
但是,如果在第一个文件完全上载之前尝试上载另一个文件,则ProgressIndicator
将重置为0%,并开始上载这两个文件。
这是我的工作代码(我根据SO上的不同示例编译)
Directory.java
import java.util.Objects;
import javafx.beans.Observable;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.scene.control.Button;
import javafx.util.Callback;
public class Directory {
private String filename;
private String fileLocation;
private String datetime;
private String filePath;
private String lastUpdated;
private String userdir_id;
private String userid;
private String directory;
private String device_id;
private String devicetype;
private DoubleProperty progressIndicator;
private String fileType;
Button addSchedular;
public Directory() {
}
public Directory(String fileName, String fileLocation, String date, String filePath, String fileType, double progressValue) {
this.filename = fileName;
this.fileLocation = fileLocation;
this.datetime = date;
this.filePath = filePath;
this.fileType = fileType;
this.progressIndicator = new SimpleDoubleProperty(progressValue);
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public String getFileLocation() {
return fileLocation;
}
public void setFileLocation(String fileLocation) {
this.fileLocation = fileLocation;
}
public String getDatetime() {
return datetime;
}
public void setDatetime(String datetime) {
this.datetime = datetime;
}
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public String getLastUpdated() {
return lastUpdated;
}
public void setLastUpdated(String lastUpdated) {
this.lastUpdated = lastUpdated;
}
public String getUserdir_id() {
return userdir_id;
}
public void setUserdir_id(String userdir_id) {
this.userdir_id = userdir_id;
}
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
public String getDirectory() {
return directory;
}
public void setDirectory(String directory) {
this.directory = directory;
}
public String getDevice_id() {
return device_id;
}
public void setDevice_id(String device_id) {
this.device_id = device_id;
}
public String getDevicetype() {
return devicetype;
}
public void setDevicetype(String devicetype) {
this.devicetype = devicetype;
}
public double getProgressIndicator() {
return progressIndicator.get();
}
public DoubleProperty getProgressIndicatorProperty() {
return progressIndicator;
}
public void setProgressIndicator(double progressIndicator) {
this.progressIndicator = new SimpleDoubleProperty(progressIndicator);
}
public String getFileType() {
return fileType;
}
public void setFileType(String fileType) {
this.fileType = fileType;
}
public Button getAddSchedular() {
return addSchedular;
}
public void setAddSchedular(Button addSchedular) {
this.addSchedular = addSchedular;
}
public static Callback<Directory, Observable[]> extractor() {
return (Directory d) -> new Observable[]{d.getProgressIndicatorProperty()};
}
@Override
public boolean equals(Object object) {
boolean result = false;
if (object == null || object.getClass() != getClass()) {
result = false;
} else {
Directory bean = (Directory) object;
if (this.filename.equals(bean.getFilename()) && this.fileLocation.equals(bean.getFileLocation())) {
result = true;
}
}
return result;
}
@Override
public int hashCode() {
int hash = 3;
hash = 31 * hash + Objects.hashCode(this.filename);
hash = 31 * hash + Objects.hashCode(this.fileLocation);
hash = 31 * hash + Objects.hashCode(this.filePath);
hash = 31 * hash + Objects.hashCode(this.userid);
hash = 31 * hash + Objects.hashCode(this.device_id);
hash = 31 * hash + Objects.hashCode(this.fileType);
return hash;
}
@Override
public String toString() {
return "DirectoryBean{" + "filename:" + filename + ", fileLocation:" + fileLocation + ", datetime:" + datetime + ", filePath:" + filePath + ", progressIndicator:" + progressIndicator + ", lastUpdated:" + lastUpdated + ", fileType:" + fileType + ", addSchedular:" + addSchedular + '}';
}
}
S3Service.java(请参阅uploadFile()
方法)
让我知道我哪里做错了正如您所说,我相信您的错误在于onUploadFileAction()
方法
如果我运行progresstener
,我注意到您在其中使用了变量upload
,然后在创建了listener
之后,立即设置upload
变量。因此,如果您背靠背上载两个文件,每当对第一个文件抛出ProgressEvent
时,它将使用第二个文件新设置的upload
变量更新指示器,假设事件不是TRANSFER\u COMPLETED\u event
,则它将显示第二个文件上载进度
为了解决这个问题,将upload
移动到方法中,并将其设置为ObjectProperty
,以便可以在lambda中使用它
希望这有帮助
ObjectProperty<Upload> upload = new SimpleObjectProperty();
ProgressListener progressListener = (ProgressEvent progressEvent) -> {
if (upload.get() == null) {
return;
}
Platform.runLater(() -> {
directory.setProgressIndicator(upload.get().getProgress().getPercentTransferred() / 100.0d);
MainController.directoryList.set(MainController.directoryList.indexOf(directory), directory);
});
if (progressEvent.getEventType() == ProgressEventType.TRANSFER_COMPLETED_EVENT) {
Platform.runLater(() -> {
directory.setProgressIndicator(1.0d);
MainController.directoryList.set(MainController.directoryList.indexOf(directory), directory);
});
} else if (progressEvent.getEventType() == ProgressEventType.TRANSFER_FAILED_EVENT) {
try {
AmazonClientException ex = upload.get().waitForException();
Platform.runLater(() -> {
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Error Uploading File");
alert.setContentText("Unable to upload file to Amazon S3:" + ex.getMessage());
alert.showAndWait();
});
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
};
//</editor-fold>
upload.set(s3Service.uploadFile(file, file.length(), file.getName(), progressListener));
ObjectProperty upload=new SimpleObjectProperty();
ProgressListener=(ProgressEvent ProgressEvent)->{
if(upload.get()==null){
返回;
}
Platform.runLater(()->{
目录.setProgressIndicator(upload.get().getProgress().getPercentTransfer()/100.0d);
MainController.directoryList.set(MainController.directoryList.indexOf(directory),directory);
});
if(progressEvent.getEventType()==ProgressEventType.TRANSFER\u COMPLETED\u事件){
Platform.runLater(()->{
目录.setProgressIndicator(1.0d);
MainController.directoryList.set(MainController.directoryList.indexOf(directory),directory);
});
}else if(progressEvent.getEventType()==ProgressEventType.TRANSFER\u FAILED\u事件){
试一试{
AmazonClientException ex=upload.get().waitForException();
Platform.runLater(()->{
警报=新警报(Alert.AlertType.ERROR);
alert.setTitle(“上传文件时出错”);
alert.setContentText(“无法将文件上载到AmazonS3:+ex.getMessage());
alert.showAndWait();
});
}捕捉(中断异常e){
Thread.currentThread().interrupt();
}
}
};
//
set(s3Service.uploadFile(file,file.length(),file.getName(),progressListener));
因此,根据您发布的代码,任何建议都可以避免使用ProgressListener
,看起来upload
可能是一个局部变量,在onUploadFileAction()中创建。我看不到它在其他任何地方被使用。我的建议是移动Upload-Upload=null
就在progressListener
@Jerk的正上方,我尝试过这样做……但是upload
必须是final
或有效final
,如果我必须在事件处理程序中使用它的话。至少这是NetBeans
通过执行ObjectProperty upload=new SimpleObjectProperty()告诉meTrick的
然后使用相应的.get()
和.set()
查看我的更新答案,特别是所有的upload.get()
,尤其是upload.set()
。我相信这就是你所缺少的。
import com.amazonaws.AmazonServiceException;
import com.amazonaws.SDKGlobalConfiguration;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.event.ProgressEvent;
import com.amazonaws.event.ProgressEventType;
import com.amazonaws.event.ProgressListener;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.CopyObjectRequest;
import com.amazonaws.services.s3.model.DeleteObjectRequest;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.ListObjectsV2Request;
import com.amazonaws.services.s3.model.ListObjectsV2Result;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectSummary;
import com.amazonaws.services.s3.transfer.MultipleFileDownload;
import com.amazonaws.services.s3.transfer.MultipleFileUpload;
import com.amazonaws.services.s3.transfer.TransferManager;
import com.amazonaws.services.s3.transfer.TransferManagerBuilder;
import com.amazonaws.services.s3.transfer.Upload;
import com.rayz.officebackup.controllers.MainController;
import com.rayz.officebackup.models.Folder;
import com.rayz.officebackup.models.IFile;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import javafx.application.Platform;
import javafx.beans.property.DoubleProperty;
import javafx.scene.control.Alert;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class S3Service {
private final String AWS_S3_BUCKET = "s3-bucket";
private String AWS_S3_BUCKET;
private static final String AWS_ACCESS_KEY = "access-key";
private static final String AWS_SECRET_KEY = "secret-key";
private final static AWSCredentials CREDENTIALS = new BasicAWSCredentials(AWS_ACCESS_KEY, AWS_SECRET_KEY);
private final static AmazonS3Client S3CLIENT = new AmazonS3Client(CREDENTIALS);
private static final String RESOURCE_CONTENT_TYPE = "text/xml";
private static final Logger LOG = LoggerFactory.getLogger(S3Service.class);
public MultipleFileUpload uploadDirectory(File directory, ProgressListener listener) throws FileNotFoundException {
System.setProperty(SDKGlobalConfiguration.ENABLE_IN_REGION_OPTIMIZED_MODE, "true");
TransferManager tm = new TransferManager(S3CLIENT);
MultipleFileUpload upload = tm.uploadDirectory(AWS_S3_BUCKET, directory.getName(), directory, true);
upload.addProgressListener(listener);
return upload;
}
public void downloadDirectory(String key, File downloadDirectory) {
System.setProperty(SDKGlobalConfiguration.ENABLE_IN_REGION_OPTIMIZED_MODE, "true");
TransferManager tm = TransferManagerBuilder.standard().withS3Client(S3CLIENT).build();
MultipleFileDownload download = tm.downloadDirectory(AWS_S3_BUCKET, key, downloadDirectory);
}
public Upload uploadFile(File file, long fileSize, String filePath, ProgressListener listener) throws FileNotFoundException {
System.setProperty(SDKGlobalConfiguration.ENABLE_IN_REGION_OPTIMIZED_MODE, "true");
ObjectMetadata objectMetaData = new ObjectMetadata();
objectMetaData.setContentLength(fileSize);
objectMetaData.setContentType(RESOURCE_CONTENT_TYPE);
objectMetaData.setCacheControl("public");
PutObjectRequest putObjectRequest = new PutObjectRequest(AWS_S3_BUCKET, filePath, file)
.withCannedAcl(CannedAccessControlList.PublicRead)
.withGeneralProgressListener(listener);
TransferManager tm = new TransferManager(S3CLIENT);
return tm.upload(putObjectRequest);
}
}
ObjectProperty<Upload> upload = new SimpleObjectProperty();
ProgressListener progressListener = (ProgressEvent progressEvent) -> {
if (upload.get() == null) {
return;
}
Platform.runLater(() -> {
directory.setProgressIndicator(upload.get().getProgress().getPercentTransferred() / 100.0d);
MainController.directoryList.set(MainController.directoryList.indexOf(directory), directory);
});
if (progressEvent.getEventType() == ProgressEventType.TRANSFER_COMPLETED_EVENT) {
Platform.runLater(() -> {
directory.setProgressIndicator(1.0d);
MainController.directoryList.set(MainController.directoryList.indexOf(directory), directory);
});
} else if (progressEvent.getEventType() == ProgressEventType.TRANSFER_FAILED_EVENT) {
try {
AmazonClientException ex = upload.get().waitForException();
Platform.runLater(() -> {
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Error Uploading File");
alert.setContentText("Unable to upload file to Amazon S3:" + ex.getMessage());
alert.showAndWait();
});
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
};
//</editor-fold>
upload.set(s3Service.uploadFile(file, file.length(), file.getName(), progressListener));