Mukesh P
Mukesh P

Reputation: 23

Progress indicator remains indeterminate and there is no download

I have written a piece of code for downloading a file from internet (in background service) and showing the progress of download in a popup stage. The code compiles successfully and there is no runtime error. However no download takes place and progress indicator remains indeterminate.

The code is tailored for illustrating my point. Please have a look at it and let me understand where I have gone wrong.

Thanks!

public class ExampleService extends Application {
URL url;    
Stage stage;

public void start(Stage stage)
{
    this.stage = stage;
    stage.setTitle("Hello World!");
    stage.setScene(new Scene(new StackPane(addButton()), 400, 200));
    stage.show();
}

private Button addButton()
{
    Button downloadButton = new Button("Download");
    downloadButton.setOnAction(new EventHandler<ActionEvent>()
    {
        public void handle(ActionEvent e)
        {
           FileChooser fileSaver = new FileChooser();
            fileSaver.getExtensionFilters().add(new FileChooser.ExtensionFilter("PDF", "pdf"));                

            File file = fileSaver.showSaveDialog(stage);

            getDownloadService(file).start();               
        }
    });        
    return downloadButton;
}

private Service getDownloadService(File file)
{
   Service downloadService = new Service() 
   {
       protected Task createTask()
       {
           return doDownload(file);
       }
   };

   return downloadService;
}

private Task doDownload(File file)
{
    Task downloadTask = new Task<Void>()
    {
       protected Void call() throws Exception
        {
            url = new URL("http://www.daoudisamir.com/references/vs_ebooks/html5_css3.pdf");

            // I have used this url for this context only
            org.apache.commons.io.FileUtils.copyURLToFile(url, file); 

            return null;
        } 
    };
    showPopup(downloadTask);
    return downloadTask;
}

Popup showPopup(Task downloadTask)
{
    ProgressIndicator progressIndicator = new ProgressIndicator();
    progressIndicator.progressProperty().bind(downloadTask.progressProperty());

    Popup progressPop = new Popup();
    progressPop.getContent().add(progressIndicator);
    progressPop.show(stage);

    return progressPop;

    // I have left out function to remove popup for simplicity
}
public static void main(String[] args)
{
    launch(args);
}}

Upvotes: 0

Views: 216

Answers (2)

Andrzej Doyle
Andrzej Doyle

Reputation: 103797

You bind the ProgressIndicator's progress property to the Task's progress property, so that changes in the latter will be reflected in the former. However you never actually update your Task's progress.

If you want the progress indicator to show something, you're going to have to call updateProgress(workDone, max) within your task's body (or elsewhere). And that might be tricky if the download logic you're using doesn't give you any progress callbacks. (You could, perhaps, spawn a thread to repeatedly check the size of the file on the filesystem and use that as your current workDone; but you'd need to know what the eventual/complete size of the file would be in order to turn this into a percentage, which may or may not be easy.)

Upvotes: 0

john16384
john16384

Reputation: 8054

The line:

org.apache.commons.io.FileUtils.copyURLToFile(url, file);

...doesn't provide you any information about the progress of your download (there is no callback or any other indication of its progress). It just downloads something without giving you feedback.

You will have to use something else that gives you feedback on the progress.

Take a look at this questions answers for solutions with feedback (it is for Swing, but you should be able to adapt them for JavaFX): Java getting download progress

Upvotes: 1

Related Questions