title: Javafx progress not updating fast enough
body: <p>I am parsing large files, line by line, where the file size could go from a few 1000's to millions of lines. When the files are small (e.g., few 10,000s lines), all the components (those indicated by red arrows in the image below) update promptly, line by line thereby giving a true indication of where the process is. When the files are large, there is huge delay in the update, it could take up to 30 seconds before the indicators reflect the progress! I could resize it manually to refresh the display.</p>
  
  <p><a href="https://i.stack.imgur.com/L7CV4.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/L7CV4.png" alt="enter image description here"></a></p>
  
  <p>The method that gets called upon streaming though the file line by line is <code>updateProgress()</code>. In there, <code>progressPrevVal</code> goes from 0 to 1 (each increment being <code>1.0 / 2,675,150</code>), and <code>lineNum</code> goes from 1 to 2,675,150 if we use the example in the image. </p>
  
  <p>Here is the entire code:</p>
  
  <pre><code>import javafx.application.Application;
  import javafx.application.Platform;
  import javafx.geometry.Insets;
  import javafx.geometry.Pos;
  import javafx.scene.Group;
  import javafx.scene.Scene;
  import javafx.scene.control.Label;
  import javafx.scene.control.ProgressBar;
  import javafx.scene.control.ProgressIndicator;
  import javafx.scene.control.TextField;
  import javafx.scene.layout.HBox;
  import javafx.scene.layout.VBox;
  import javafx.scene.text.Font;
  import javafx.scene.text.FontWeight;
  import javafx.stage.Stage;
  
  public class DxProgressIndicator extends Application {
  
  private static ProgressBar pb;
  private static ProgressIndicator pi;
  private static TextField tfNumbers;
  private static Label lblLineNumVal;
  private static Label lblAllLines;
  private static double progressIncrement;
  private static double progressPrevVal;
  private static int lineNum;
  private static Label lblFile;
  
  @Override
  public void start(Stage stage) {
      Group root = new Group();
      Scene scene = new Scene(root);
      stage.setScene(scene);
      stage.setTitle("Dexter Parser");
  
      lblFile = new Label();
      final HBox hbFile = new HBox();
      hbFile.setAlignment(Pos.CENTER_LEFT);
      Label lblCurrentFile = new Label("Current file: ");
      lblCurrentFile.setMinWidth(90);
      lblCurrentFile.setFont(Font.font(null, FontWeight.BOLD, 13));
      hbFile.getChildren().addAll(lblCurrentFile, lblFile);
  
      pb = new ProgressBar(0);
      pb.setMinWidth(450);
      pi = new ProgressIndicator(0);
  
      final HBox hbPis = new HBox(10);
      hbPis.setAlignment(Pos.CENTER_LEFT);
      hbPis.getChildren().addAll(pb, pi);
  
      lblLineNumVal = new Label();
      lblLineNumVal.setMaxWidth(200);
  
      Label slash = new Label("  /  ");
  
      lblAllLines = new Label();
  
      final HBox hbLines = new HBox();
      hbLines.setAlignment(Pos.CENTER_LEFT);
      Label lblLineNum = new Label("    Currently parsing Line # :   ");
      lblLineNum.setFont(Font.font(null, FontWeight.BOLD, 12));
      hbLines.getChildren().addAll(lblLineNum, lblLineNumVal, slash, lblAllLines);
  
      tfNumbers = new TextField();
      tfNumbers.setEditable(false);
      tfNumbers.setMaxWidth(100);
  
      final HBox hbTrxValues = new HBox();
      hbTrxValues.setAlignment(Pos.CENTER_LEFT);
      Label lblNumbers = new Label("(transaction, step, record) = ");
      lblNumbers.setFont(Font.font(null, FontWeight.BOLD, 12));
      hbTrxValues.getChildren().addAll(lblNumbers, tfNumbers);
  
      final VBox vb = new VBox(10);
      vb.getChildren().addAll(hbFile, hbPis, hbLines, hbTrxValues);
      vb.setPadding(new Insets(10));
  
      scene.setRoot(vb);
      stage.show();
  }
  
  public static void updateProgress() {
      Platform.runLater(() -&gt; {
          progressPrevVal += progressIncrement;
          pb.setProgress(progressPrevVal);
          pi.setProgress(progressPrevVal);
          lblLineNumVal.setText(Integer.toString(lineNum++));
      });
  }
  
  public static void setFileMetadata(String str) {
      Platform.runLater(() -&gt; {
          lblAllLines.setText(str);
          progressIncrement = 1 / Double.valueOf(str);
          progressPrevVal = 0d;
          lineNum = 1;
      });     
  }
  
  public static void main(String[] args) {
      launch(args);
  }
  }
  </code></pre>
  
  <p>From the client's main method, once I start the GUI in its own thread like this:</p>
  
  <pre><code>    Runnable task = () -&gt; {
          DxProgressIndicator.main(null);
      };
      Thread thread = new Thread(task);
      thread.start();
  </code></pre>
  
  <p>I can then go through the file, streaming through it line by line like this:</p>
  
  <pre><code>    try (Stream&lt;String&gt; stream = Files.lines(file)) {
          stream.forEach(line -&gt; {
              DxProgressIndicator.updateProgress();
              // a bunch of stuff to do with the line
          });
      } catch (IOException e) {
      }
  </code></pre>
  
  <p>So, what am I missing? How can I force a refresh so that the components update smoothly at every iteration instead of every almost one minute when processing awfully large files?</p>
  
  <p>Thank you.</p>