JavaFX progress bar show file upload status

i am using JavaFX (using scene builder) and i am trying to build a progressBar with a progressIndicator that will show a background file upload status.

Here is my javafx controller (some initialization):

@FXML
private Pane uploadsStatuses;
@FXML
private ProgressBar uploadBar;
@FXML
private ProgressIndicator uploadProgressIndicator;
...
@Override
@FXML
public void initialize(URL url, ResourceBundle rb) {
    ...
    assert uploadsStatuses != null : "fx:id=\"uploadsStatuses\" was not injected: check your FXML file 'FXMLDocument.fxml'.";
    assert uploadBar != null : "fx:id=\"uploadBar\" was not injected: check your FXML file 'FXMLDocument.fxml'.";
    assert uploadProgressIndicator != null : "fx:id=\"uploadProgressIndicator\" was not injected: check your FXML file 'FXMLDocument.fxml'.";
    ...

For uploading the file i am using FTP4J library and i have already implemented a way to calculate file upload percentage:

public class Ftp4jListener implements FTPDataTransferListener {
    private int transfBytes=0;
    private int totalBytes=0;
    private long fileSize = -1;
    private String fileName;
    ...
    @Override
    public void transferred(int length)
    {
        transfBytes+=length;
        float percent = (float) transfBytes / this.fileSize;
        float fPercent = percent*100;
        log.info("File: " + this.fileName + " | Bytes transfered "+ transfBytes + " Percentage: " + fPercent + "%");
    }

The question is how could i bound FTP4J listener with my progressBar & progressIndicator?


ANSWERS:


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)));


 MORE:


 ? How to configure Progress Bar and Progress Indicator of javaFx?
 ? How to configure Progress Bar and Progress Indicator of javaFx?
 ? How to configure Progress Bar and Progress Indicator of javaFx?
 ? JavaFX: Update ProgressBar (@FXML) from Thread
 ? JavaFX refresh Progress Bar within a method
 ? JavaFX indeterminate progress bar while doing a process
 ? JavaFX progress bar causes severe window lag after a resize
 ? How to update Progress Bar using double Binding in JavaFX
 ? javafx , how to show progress bar while printing into text area
 ? Progress Bar while downloading image in javafx