title: Building Multithreading ProgressBar in JavaFx
body: <p>I am attempting to build a progress bar that is being updated as my application is retrieving and populating data to the GUI. I figured that the progress bar will be reused a lot so I decided to create its own class. However, I don't believe I understand either the Worker/Task or Multi-Threading in general to create a re-usable situation. What would be the recommended approach to creating a progress bar that can listen to the application thread and update the bar accordingly. Here is my attempt:</p>
  
  <pre><code>// Simple Progress Bar View as Pop Up
  public class ProgressIndicatorUtil{
  
      @FXML
      private ProgressBar progressBar;
      @FXML
      private Label statusLabel;
      @FXML
      private Button closeButton;
      @FXML
      private Label valueLabel;
  
      private Worker worker;
      private Stage stage;
  
      public void setPopUpStage(Stage stage) {
          this.stage = stage;
      }
  
      public void setWorker(Worker worker) {
          this.worker = worker;
      }
  
      public void setLinkToMainPage(Object controller) {
  
          ((Task&lt;String&gt;) worker).setOnSucceeded(event -&gt; stage.close());
  
          ((Task&lt;String&gt;) worker).setOnCancelled(event -&gt; {
                  closeButton.setVisible(true);
                  stage.requestFocus();
                  statusLabel.setTextFill(Color.RED);}
          );
  
          valueLabel.textProperty().bind(Bindings.format("%5.1f%%", worker.progressProperty().multiply(100)));
          progressBar.progressProperty().bind(worker.progressProperty());
          statusLabel.textProperty().bind(worker.messageProperty());
      }
  
      @FXML
      private void handleClose(ActionEvent e){
          stage.close();
      }
  }
  </code></pre>
  
  <p>The Controller that calls the View Pop-Up and runs the Progress Bar Thread.</p>
  
  <pre><code>public class MyController{
  
     //Controller calling the view and disabling the main GUI
     private void loadProgressBar(Worker worker){
  
          try{
  
              FXMLLoader loader = new FXMLLoader(getClass()
                      .getClassLoader().getResource("main/resources/fxml/ProgressBar.fxml"));
              AnchorPane pane = (AnchorPane)loader.load();
              Stage popUpStage = new Stage();
              popUpStage.initModality(Modality.WINDOW_MODAL);
              Scene scene = new Scene(pane);
              popUpStage.setScene(scene);
  
              ProgressIndicatorUtil controller = loader.getController();
              controller.setPopUpStage(popUpStage);
              controller.setWorker(worker);
              controller.setLinkToMainPage(this);
              mainPane.setDisable(true);
              popUpStage.showingProperty().addListener((obs, hidden, showing) -&gt; {
                      if(hidden) mainPane.setDisable(false);});
              popUpStage.show();
  
          }catch(IOException e){
              e.printStackTrace();
          }   
      }
  
  
  
     private void runProgressBar(Worker worker) {
          new Thread((Runnable) worker).start();
     }
  
  
      //A user action that runs the progress bar and GUI
      @FXML
      private void aBigProcessingEvent(ActionEvent event) {
  
          Worker worker = new Task&lt;String&gt;(){
  
              @Override
              protected String call() throws Exception {        
  
                  updateProgress(0, 3);
                  updateMessage("Clearing Data");
  
                  processingEvent01();
  
                  updateProgress(1, 3);
                  updateMessage("Retriving Data And Adding To List");
  
                  processingEvent02();
  
                  updateProgress(2, 3);
                  updateMessage("Populating Data");
  
                  processingEvent03();
  
                  updateProgress(3, 3);
                  return "Finished!";
              }
          };
  
          loadProgressBar(worker);
          runProgressBar(worker);
      }
  }
  </code></pre>
  
  <p>The program works fine, visually, but it throws an Exception like this (<a href="https://stackoverflow.com/questions/30863205/multi-threading-error-when-binding-a-stringproperty">Not On FX Application Thread</a>) and running Platform.runLater() on my "processingEvent" methods will cause my progress bar to be 100% immediately, but it won't throw anymore Exceptions. Any suggestion to how to split the application modification methods and the worker methods apart while keeping the progression connected to the processingEvent methods? Much thanks. </p>