File Upload with Java (with progress bar)
I ended up stumbling across an open source Java uploader applet and found everything I needed to know within its code. Here are links to a blog post describing it as well as the source:
Article
Source Code
JavaFX progress bar show file upload status
Either:
Rewrite your listener class to use JavaFX Properties:
public class Ftp4jListener implements FTPDataTransferListener {
private final ReadOnlyIntegerWrapper transfBytes = new ReadOnlyIntegerWrapper();
private final ReadOnlyIntegerWrapper totalBytes = new ReadOnlyIntegerWrapper();
private final ReadOnlyLongWrapper fileSize = new ReadOnlyLongWrapper(-1);
public ReadOnlyIntegerProperty transfBytesProperty() {
return transfBytes.getReadOnlyProperty() ;
}
public int getTransfBytes() {
return transfBytesProperty().get();
}
// etc. for other two properties...
private String fileName;
...
@Override
public void transferred(int length)
{
transfBytes.set(tranfBytes.get()+length);
float percent = (float) transfBytes.get() / this.fileSize.get();
float fPercent = percent*100;
log.info("File: " + this.fileName + " | Bytes transfered "+ transfBytes.get() + " Percentage: " + fPercent + "%");
}
}
Then you can register a listener with one or more of the properties and update your progress bar:
ftp4jListener.transfBytesProperty().addListener((obs, oldValue, newValue) ->
uploadBar.setProgress(((double)ftp4jListener.getTransfBytes())/ftp4jListener.getFileSize()));
If you are transferring the data in a background thread (which you should be), be sure to update the progress bar on the FX Application Thread:
ftp4jListener.transfBytesProperty().addListener((obs, oldValue, newValue) ->
Platform.runLater(() ->
uploadBar.setProgress(((double)ftp4jListener.getTransfBytes())/ftp4jListener.getFileSize())));
or from a Task
call updateProgress(...)
, and bind the progress property of the progress bar to the progress property of the task.
Or:
Write your listener to accept a callback:
public class Ftp4jListener implements FTPDataTransferListener {
private int transfBytes=0;
private int totalBytes=0;
private long fileSize = -1;
private String fileName;
private final DoubleConsumer percentageCallback ;
public Ftp4jListener(DoubleConsumer percentageCallback) {
this.percentageCallback = percentageCallback ;
}
...
@Override
public void transferred(int length)
{
transfBytes+=length;
float percent = (float) transfBytes / this.fileSize;
float fPercent = percent*100;
percentageCallback.accept(fPercent);
log.info("File: " + this.fileName + " | Bytes transfered "+ transfBytes + " Percentage: " + fPercent + "%");
}
}
Then you can create the listener as
Ftp4jListener ftp4jListener = new Ftp4jListener(percent ->
Platform.runLater(() -> uploadBar.setProgress(percent)));
Upload multiple files with progress bar using OKHTTP3
Finally, I got it working after a long search
Here is my class, not targeting a single file request, but the entire request body
public class CountingRequestBody extends RequestBody {
protected RequestBody delegate;
protected Listener listener;
protected CountingSink countingSink;
public CountingRequestBody(RequestBody delegate, Listener listener)
{
this.delegate = delegate;
this.listener = listener;
}
@Override
public MediaType contentType()
{
return delegate.contentType();
}
@Override
public long contentLength()
{
try
{
return delegate.contentLength();
} catch (IOException e)
{
e.printStackTrace();
}
return -1;
}
@Override
public void writeTo(BufferedSink sink) throws IOException
{
countingSink = new CountingSink(sink);
BufferedSink bufferedSink = Okio.buffer(countingSink);
delegate.writeTo(bufferedSink);
bufferedSink.flush();
}
protected final class CountingSink extends ForwardingSink
{
private long bytesWritten = 0;
public CountingSink(Sink delegate)
{
super(delegate);
}
@Override
public void write(Buffer source, long byteCount) throws IOException
{
super.write(source, byteCount);
bytesWritten += byteCount;
listener.onRequestProgress(bytesWritten, contentLength());
}
}
public static interface Listener
{
public void onRequestProgress(long bytesWritten, long contentLength);
}
}
Multiple Files uploader
public void filesUploader(){
MultipartBody.Builder multipartBody = new MultipartBody.Builder().setType(MultipartBody.FORM);
for (int g = 0; g < itemLists.size(); g++){
File readFile = itemLists.get(g);
Uri uris = Uri.fromFile(readFile);
String fileExt = MimeTypeMap.getFileExtensionFromUrl(uris.toString());
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExt.toLowerCase());
multipartBody.addFormDataPart("files[]", readFile.getName(), RequestBody.create(MediaType.parse(mimeType), readFile));
}
multipartBody.addFormDataPart("someparams1", value1)
.addFormDataPart("someparams2", value2);
final CountingRequestBody.Listener progressListener = new CountingRequestBody.Listener() {
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onRequestProgress(long bytesRead, long contentLength) {
if (bytesRead >= contentLength) {
} else {
if (contentLength > 0) {
final int progress = (int)Math.round((((double) bytesRead / contentLength) * 100));
postProgressBar.setProgress(progress, true);
postProgressText.setText(progress+"%");
if(progress == 100){
}
}
}
}
};
OkHttpClient imageUploadClient = new OkHttpClient.Builder()
.addNetworkInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
if (originalRequest.body() == null) {
return chain.proceed(originalRequest);
}
Request progressRequest = originalRequest.newBuilder()
.method(originalRequest.method(),
new CountingRequestBody(originalRequest.body(), progressListener))
.build();
return chain.proceed(progressRequest);
}
})
.build();
RequestBody requestBody = multipartBody.build();
Request request = new Request.Builder()
.url(Constants.submitPostUrl)
.header("Accept", "application/json")
.header("Content-Type", "application/json")
.post(requestBody)
.build();
imageUploadClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
String mMessage = e.getMessage().toString();
//onError
Log.e("failure Response", mMessage);
}
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onResponse(Call call, Response response) throws IOException {
String mMessage = response.body().string();
//successful
}
});
}
Best way for showing a horizontal progress bar with percentage during a file upload?
There’s a built-in mechanism for progress updates in AsyncTask
. All you need to do to access it, is override onProgressUpdate
within the AsyncTask
. It gets the progress as a parameter that you can use to update the UI. Considering that the AsyncTask
runs in a background thread and you need to update the UI thread with the progress, you can call publishProgress
from your doInBackground
which makes the progress update run on the UI thread.
protected void onProgressUpdate(String... progress) {
progressDialog.setProgress(Integer.parseInt(progress[0]));
}
Related Topics
How to Obtain Mouse Click Coordinates Outside My Window in Java
How to Display Legend for Pie Chart in Columns
Using Gzip Compression with Spring Boot/Mvc/Javaconfig with Restful
Converting Integer to String with Comma for Thousands
When to Close Connection, Statement, Preparedstatement and Resultset in Jdbc
Loading Context in Spring Using Web.Xml
Configure Hibernate (Using JPA) to Store Y/N for Type Boolean Instead of 0/1
Show Jframe in a Specific Screen in Dual Monitor Configuration
Java Regex Replace with Capturing Group
What Is a Covariant Return Type
List.Clear() VS List = New Arraylist<Integer>();
Java Garbage Collector - When Does It Collect