6 Replies Latest reply on Oct 10, 2011 9:44 PM by idle

    How to bind ProgressBar ?

    idle
      Hello ,
      I want to use ProgressBar to indicate progress how much data are downloaded ;
      How to bind ProgressBar with property and then to setProgress() method with this property.
        • 1. Re: How to bind ProgressBar ?
          Narayan
          ProgressBar can be easily binded with SimpleDoubleProperty.
          //Simple Double property for binding progress
          final SimpleDoubleProperty prop = new SimpleDoubleProperty(0);
          ProgressBar progress = new ProgressBar();   
          progress.progressProperty().bind(prop); 
          
          //MultiThread Start's here
          new Thread(){
               @Override
               public void run(){                
                    try {
                         
                         for(double i=0; i<=1; i+=0.01){
                              prop.set(i); 
                              Thread.sleep(100);                       
                         }
                         
                    } catch (InterruptedException ex) {
                         System.err.println("Error on Thread Sleep");
                    }
               }
               
          }.start();
          Thanks.
          Narayan
          • 2. Re: How to bind ProgressBar ?
            Richard Bair-Oracle
            Except for one very important thing -- you should not update the prop from the background thread as that will notify the ProgressBar of the change on the wrong thread and it will then update the UI on the wrong thread! You could try doing something simple like just wrapping every prop.set call in a Platform.runLater(new Runnable() { ... }), but this will then flood the event queue. Instead, I would recommend using javafx.concurrent.Task, because it handles all this for you. Just:
                    final Task<Void> task = new Task<Void>() {
                        public Void call() throws Exception {
                            for (int i=0; i<=10000; i++) {
                                updateProgress(i, 10000);
                                Thread.sleep(1);
                            }
                            return null;
                        }
                    };
                    ProgressBar progress = new ProgressBar();   
                    progress.progressProperty().bind(task.progressProperty()); 
                    new Thread(task).start();
            • 3. Re: How to bind ProgressBar ?
              idle
              Thanks for the advice .
              But my ProgressBar still is in indeterminate mode.

              That is a my source code :

              Im sorry for unformated source code but i dont found which is the tag for <code>


              import java.io.BufferedInputStream;
              import java.io.BufferedOutputStream;
              import java.io.FileOutputStream;
              import java.io.IOException;
              import java.net.URL;
              import javafx.application.Application;
              import javafx.concurrent.Task;
              import javafx.event.ActionEvent;
              import javafx.event.EventHandler;
              import javafx.geometry.Insets;
              import javafx.scene.Group;
              import javafx.scene.Scene;
              import javafx.scene.control.Button;
              import javafx.scene.control.ProgressBar;
              import javafx.scene.control.TextField;
              import javafx.scene.layout.HBox;
              import javafx.scene.layout.VBox;
              import javafx.stage.Stage;

              /**
              *
              * @author idle
              */
              public class YourDownloader extends Application {

              private final HBox hBox = new HBox();
              private final VBox vBox = new VBox();

              // size of the file to be downloaded
              double content;
              // buffer of the downloaded data
              byte[] data = new byte[1024];

              //current downloaded data
              int readed = 0;

              ProgressBar progress = new ProgressBar(0.01);


              public static void main(String[] args) {
              Application.launch(args);
              }

              @Override
              public void start(Stage primaryStage) {

              primaryStage.setTitle("Your Dounloader");
              Group root = new Group();
              Scene scene = new Scene(root, 500, 250);

              final TextField urlTextField = new TextField();
              urlTextField.setPromptText("Add URL here");
              urlTextField.setPrefWidth(scene.getWidth() - scene.getWidth() / 3);

              Button btn = new Button();
              btn.setText("Start Download");
              //actionListener for the download buton
              btn.setOnAction(new EventHandler<ActionEvent>() {
              @Override
              public void handle(ActionEvent event) {
              try {
              startDownload(urlTextField.getText());
              } catch (IOException ex) {
              System.err.println("There is a IOException !!! : " + ex);
              }
              }
              });

              hBox.getChildren().addAll(urlTextField, btn);
              hBox.setPadding(new Insets(10, 5, 5, 10));
              hBox.setSpacing(20);
              vBox.getChildren().addAll(hBox, progress);
              root.getChildren().add(vBox);
              primaryStage.setScene(scene);
              primaryStage.show();
              }


              public void startDownload(String stringUrl) throws IOException {

              URL url = new URL(stringUrl);

              try (
              BufferedInputStream bis = new BufferedInputStream(url.openStream());
              FileOutputStream fos = new FileOutputStream(getFileName(url));
              BufferedOutputStream bos = new BufferedOutputStream(fos, 1024)) {

              content = url.openConnection().getContentLength();

              final Task<Void> task = new Task<Void>() {

              @Override
              public Void call() throws Exception {

              while ((readed = bis.read(data, 0, 1024)) > 0) {
              bos.write(data, 0, readed);
              updateProgress(((long) (readed / content) * 100), 100);
              Thread.sleep(1);
              }
              return null;
              }
              };

              progress.progressProperty().bind(task.progressProperty());
              new Thread(task).start();

              }
              }

              // Get file name from of URL.
              public String getFileName(URL url) {
              String fileName = url.getFile();
              return fileName.substring(fileName.lastIndexOf('/') + 1);
              }
              }
              • 4. Re: How to bind ProgressBar ?
                Richard Bair-Oracle
                Ya, you just use [ code ] and [ code ] (without the spaces)
                • 5. Re: How to bind ProgressBar ?
                  Richard Bair-Oracle
                  You had two problems in your code. First, the input stream "bis" had already been closed by the time the Task ran, thanks to the try-with-resources block closing everything for you. Second, the updateProgress was always producing values that would result in -1 (or a negative number) being produced for the progress.

                  Instead, you should open the streams (try-with-resources) within the task, fully in the background thread. And, you should pass the raw values into updateProgress instead of trying to compute a value between 0 and 100, and just let the updateProgress method do it for you.
                  import java.io.BufferedInputStream;
                  import java.io.BufferedOutputStream;
                  import java.io.FileOutputStream;
                  import java.io.IOException;
                  import java.net.URL;
                  import javafx.application.Application;
                  import javafx.concurrent.Task;
                  import javafx.event.ActionEvent;
                  import javafx.event.EventHandler;
                  import javafx.geometry.Insets;
                  import javafx.scene.Group;
                  import javafx.scene.Scene;
                  import javafx.scene.control.Button;
                  import javafx.scene.control.ProgressBar;
                  import javafx.scene.control.TextField;
                  import javafx.scene.layout.HBox;
                  import javafx.scene.layout.VBox;
                  import javafx.stage.Stage;
                  
                  /**
                   *
                   * @author idle
                   */
                  public class YourDownloader extends Application {
                  
                      private final HBox hBox = new HBox();
                      private final VBox vBox = new VBox();
                      ProgressBar progress = new ProgressBar(0.01);
                  
                      public static void main(String[] args) {
                          Application.launch(args);
                      }
                  
                      @Override public void start(Stage primaryStage) {
                          primaryStage.setTitle("Your Dounloader");
                          Group root = new Group();
                          Scene scene = new Scene(root, 500, 250);
                  
                          final TextField urlTextField = new TextField();
                          urlTextField.setPromptText("Add URL here");
                          urlTextField.setPrefWidth(scene.getWidth() - scene.getWidth() / 3);
                          Button btn = new Button();
                          btn.setText("Start Download");
                          btn.setOnAction(new EventHandler<ActionEvent>() {
                              @Override public void handle(ActionEvent event) {
                                  try {
                                      startDownload(urlTextField.getText());
                                  } catch (IOException ex) {
                                      System.err.println("There is a IOException !!! : " + ex);
                                  }
                              }
                          });
                  
                          hBox.getChildren().addAll(urlTextField, btn);
                          hBox.setPadding(new Insets(10, 5, 5, 10));
                          hBox.setSpacing(20);
                          vBox.getChildren().addAll(hBox, progress);
                          root.getChildren().add(vBox);
                          primaryStage.setScene(scene);
                          primaryStage.show();
                      }
                  
                      public void startDownload(final String stringUrl) throws IOException {
                          final Task<Void> task = new Task<Void>() {
                              @Override public Void call() throws Exception {
                                  URL url = new URL(stringUrl);
                                  String fileName = url.getFile();
                                  fileName = fileName.substring(fileName.lastIndexOf('/') + 1);
                                  try (BufferedInputStream bis = new BufferedInputStream(url.openStream());
                                       FileOutputStream fos = new FileOutputStream(fileName);
                                       BufferedOutputStream bos = new BufferedOutputStream(fos, 1024))
                                  {
                                      // buffer of the downloaded data
                                      byte[] data = new byte[1024];
                                      int read = 0, totalRead = 0;
                                      long contentLength = url.openConnection().getContentLength();
                                      while ((read = bis.read(data, 0, 1024)) > 0) {
                                          totalRead += read;
                                          bos.write(data, 0, read);
                                          updateProgress(totalRead, contentLength);
                                      }
                                      return null;
                                  }
                              }
                          };
                          progress.progressProperty().bind(task.progressProperty());
                          new Thread(task).start();
                      }
                  }
                  • 6. Re: How to bind ProgressBar ?
                    idle
                    I understood my mistake.
                    Thank you very much.