JavaFX multiple tasks












0















Can someone please help me out?
I have a program which uses JavaFX.
Now after pressing a button I want to do n-calculations.
Those calculations should be done using threads (parallel) and they should NOT make the main JavaFX app hang / freeze. What I want to do, is to display a loading state while the calcuations are running and if all tasks have finished calculating, I want to continue with the program (remove the loading state and show results).



After reading some stuff about the "Concurrency in JavaFX" I came up with this:



for (int i = 0; i < n; ++i) {
CalcTask task = new CalcTask(i);

task.setOnSucceeded(e -> {
// process is just a static method in which I count
// how many results (i) I already received
// (where n is the required amount). If i == n,
// I know I am done with all the tasks
process(task.getValue());
});

new Thread(task).start();
}


And the CalcTask Class:



public class CalcTask extends Task<Integer> {
protected int id;

public CalcTask (int id) {
this.id = id;
}

@Override
public Integer call() {
return CALCULATION_RESULT;
}
}


Now my question is: This seems a bit "cluncky" to me. Is there any better way for implementing stuff like this in JavaFX? Thanks :)










share|improve this question





























    0















    Can someone please help me out?
    I have a program which uses JavaFX.
    Now after pressing a button I want to do n-calculations.
    Those calculations should be done using threads (parallel) and they should NOT make the main JavaFX app hang / freeze. What I want to do, is to display a loading state while the calcuations are running and if all tasks have finished calculating, I want to continue with the program (remove the loading state and show results).



    After reading some stuff about the "Concurrency in JavaFX" I came up with this:



    for (int i = 0; i < n; ++i) {
    CalcTask task = new CalcTask(i);

    task.setOnSucceeded(e -> {
    // process is just a static method in which I count
    // how many results (i) I already received
    // (where n is the required amount). If i == n,
    // I know I am done with all the tasks
    process(task.getValue());
    });

    new Thread(task).start();
    }


    And the CalcTask Class:



    public class CalcTask extends Task<Integer> {
    protected int id;

    public CalcTask (int id) {
    this.id = id;
    }

    @Override
    public Integer call() {
    return CALCULATION_RESULT;
    }
    }


    Now my question is: This seems a bit "cluncky" to me. Is there any better way for implementing stuff like this in JavaFX? Thanks :)










    share|improve this question



























      0












      0








      0








      Can someone please help me out?
      I have a program which uses JavaFX.
      Now after pressing a button I want to do n-calculations.
      Those calculations should be done using threads (parallel) and they should NOT make the main JavaFX app hang / freeze. What I want to do, is to display a loading state while the calcuations are running and if all tasks have finished calculating, I want to continue with the program (remove the loading state and show results).



      After reading some stuff about the "Concurrency in JavaFX" I came up with this:



      for (int i = 0; i < n; ++i) {
      CalcTask task = new CalcTask(i);

      task.setOnSucceeded(e -> {
      // process is just a static method in which I count
      // how many results (i) I already received
      // (where n is the required amount). If i == n,
      // I know I am done with all the tasks
      process(task.getValue());
      });

      new Thread(task).start();
      }


      And the CalcTask Class:



      public class CalcTask extends Task<Integer> {
      protected int id;

      public CalcTask (int id) {
      this.id = id;
      }

      @Override
      public Integer call() {
      return CALCULATION_RESULT;
      }
      }


      Now my question is: This seems a bit "cluncky" to me. Is there any better way for implementing stuff like this in JavaFX? Thanks :)










      share|improve this question
















      Can someone please help me out?
      I have a program which uses JavaFX.
      Now after pressing a button I want to do n-calculations.
      Those calculations should be done using threads (parallel) and they should NOT make the main JavaFX app hang / freeze. What I want to do, is to display a loading state while the calcuations are running and if all tasks have finished calculating, I want to continue with the program (remove the loading state and show results).



      After reading some stuff about the "Concurrency in JavaFX" I came up with this:



      for (int i = 0; i < n; ++i) {
      CalcTask task = new CalcTask(i);

      task.setOnSucceeded(e -> {
      // process is just a static method in which I count
      // how many results (i) I already received
      // (where n is the required amount). If i == n,
      // I know I am done with all the tasks
      process(task.getValue());
      });

      new Thread(task).start();
      }


      And the CalcTask Class:



      public class CalcTask extends Task<Integer> {
      protected int id;

      public CalcTask (int id) {
      this.id = id;
      }

      @Override
      public Integer call() {
      return CALCULATION_RESULT;
      }
      }


      Now my question is: This seems a bit "cluncky" to me. Is there any better way for implementing stuff like this in JavaFX? Thanks :)







      java javafx concurrency parallel-processing task






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 18 '18 at 2:04







      Big Lebowski

















      asked Nov 18 '18 at 1:58









      Big LebowskiBig Lebowski

      1214




      1214
























          2 Answers
          2






          active

          oldest

          votes


















          3














          Since you extend class Task, you can also overwrite method succeeded() and remove invocation of task.setOnSucceeded() on the main thread:



          for (int i = 0; i < n; ++i) {
          CalcTask task = new CalcTask(i);
          new Thread(task).start();
          }

          public class CalcTask extends Task<Integer> {
          protected int id;

          public CalcTask (int id) {
          this.id = id;
          }

          public void succeeded() {
          process(this.getValue());
          }

          @Override
          public Integer call() {
          return CALCULATION_RESULT;
          }
          }


          or even use plain Runnable instead of Task:



          public class CalcTask implements Runnable {
          protected int id;

          public CalcTask (int id) {
          this.id = id;
          }

          @Override
          public void run() {
          CALCULATION_RESULT = calculate();
          process(CALCULATION_RESULT);
          }
          }





          share|improve this answer



















          • 1





            Just want to point out that your two examples are not equivalent. The Task.succeeded method will call process on the FX thread whereas the pure Runnable will call process on whatever thread called run.

            – Slaw
            Nov 18 '18 at 11:26













          • Thanks! I will give it a try later this day and come back to comment on this.

            – Big Lebowski
            Nov 18 '18 at 12:37











          • OK, thank you for the answer. I ended up implementing it like this (the Task variant). Still I am a bit curious if there is no "cleaner" way to implement this. I was thinking about a "container", which holds all the Tasks - and if all the Tasks have finished, the "container" would trigger an event and you can fetch all the Tasks results. But anyway - thank you!

            – Big Lebowski
            Nov 18 '18 at 15:03



















          0














          In my opinion the better way is RxJavaFx

          This sample: https://github.com/pkrysztofiak/rxjavafx-demo

          RxJavaFx tutorial https://github.com/ReactiveX/RxJavaFX



          package com.github.pkrysztofiak.rxjavafx.rxjavafxdemo.concurrency;

          import java.util.Random;

          import io.reactivex.Observable;
          import io.reactivex.rxjavafx.observables.JavaFxObservable;
          import io.reactivex.rxjavafx.schedulers.JavaFxScheduler;
          import io.reactivex.schedulers.Schedulers;
          import javafx.application.Application;
          import javafx.scene.Scene;
          import javafx.scene.control.Button;
          import javafx.scene.control.Label;
          import javafx.scene.layout.HBox;
          import javafx.stage.Stage;

          public class ParallelTasksApp extends Application {

          public static void main(String args) {
          launch(args);
          }

          @Override
          public void start(Stage stage) throws Exception {
          Button button = new Button("Start");
          Label label = new Label();
          HBox hBox = new HBox(button, label);
          stage.setScene(new Scene(hBox));
          stage.show();

          JavaFxObservable.actionEventsOf(button)
          .flatMap(actionEvent -> Observable.range(1, 4))
          .flatMap(i -> Observable.just(i)
          .subscribeOn(Schedulers.newThread())
          .map(this::runLongProcess))
          .observeOn(JavaFxScheduler.platform())
          .scan(0, (aggregator, next) -> ++aggregator)
          .map(String::valueOf)
          .subscribe(label::setText);
          }

          private int runLongProcess(int i) {
          try {
          Thread.sleep(new Random().nextInt(10000));
          } catch (InterruptedException e) {
          e.printStackTrace();
          }
          System.out.println(Thread.currentThread().getName() + " i=" + i);
          return i;
          }
          }





          share|improve this answer
























          • Hi - thanks for your answer, but I dont like excessive method chaining. Maybe for some people this is an elegant solution, but sadly not for me. I still thank you very much for contribution :)

            – Big Lebowski
            Nov 18 '18 at 12:44











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53357250%2fjavafx-multiple-tasks%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          3














          Since you extend class Task, you can also overwrite method succeeded() and remove invocation of task.setOnSucceeded() on the main thread:



          for (int i = 0; i < n; ++i) {
          CalcTask task = new CalcTask(i);
          new Thread(task).start();
          }

          public class CalcTask extends Task<Integer> {
          protected int id;

          public CalcTask (int id) {
          this.id = id;
          }

          public void succeeded() {
          process(this.getValue());
          }

          @Override
          public Integer call() {
          return CALCULATION_RESULT;
          }
          }


          or even use plain Runnable instead of Task:



          public class CalcTask implements Runnable {
          protected int id;

          public CalcTask (int id) {
          this.id = id;
          }

          @Override
          public void run() {
          CALCULATION_RESULT = calculate();
          process(CALCULATION_RESULT);
          }
          }





          share|improve this answer



















          • 1





            Just want to point out that your two examples are not equivalent. The Task.succeeded method will call process on the FX thread whereas the pure Runnable will call process on whatever thread called run.

            – Slaw
            Nov 18 '18 at 11:26













          • Thanks! I will give it a try later this day and come back to comment on this.

            – Big Lebowski
            Nov 18 '18 at 12:37











          • OK, thank you for the answer. I ended up implementing it like this (the Task variant). Still I am a bit curious if there is no "cleaner" way to implement this. I was thinking about a "container", which holds all the Tasks - and if all the Tasks have finished, the "container" would trigger an event and you can fetch all the Tasks results. But anyway - thank you!

            – Big Lebowski
            Nov 18 '18 at 15:03
















          3














          Since you extend class Task, you can also overwrite method succeeded() and remove invocation of task.setOnSucceeded() on the main thread:



          for (int i = 0; i < n; ++i) {
          CalcTask task = new CalcTask(i);
          new Thread(task).start();
          }

          public class CalcTask extends Task<Integer> {
          protected int id;

          public CalcTask (int id) {
          this.id = id;
          }

          public void succeeded() {
          process(this.getValue());
          }

          @Override
          public Integer call() {
          return CALCULATION_RESULT;
          }
          }


          or even use plain Runnable instead of Task:



          public class CalcTask implements Runnable {
          protected int id;

          public CalcTask (int id) {
          this.id = id;
          }

          @Override
          public void run() {
          CALCULATION_RESULT = calculate();
          process(CALCULATION_RESULT);
          }
          }





          share|improve this answer



















          • 1





            Just want to point out that your two examples are not equivalent. The Task.succeeded method will call process on the FX thread whereas the pure Runnable will call process on whatever thread called run.

            – Slaw
            Nov 18 '18 at 11:26













          • Thanks! I will give it a try later this day and come back to comment on this.

            – Big Lebowski
            Nov 18 '18 at 12:37











          • OK, thank you for the answer. I ended up implementing it like this (the Task variant). Still I am a bit curious if there is no "cleaner" way to implement this. I was thinking about a "container", which holds all the Tasks - and if all the Tasks have finished, the "container" would trigger an event and you can fetch all the Tasks results. But anyway - thank you!

            – Big Lebowski
            Nov 18 '18 at 15:03














          3












          3








          3







          Since you extend class Task, you can also overwrite method succeeded() and remove invocation of task.setOnSucceeded() on the main thread:



          for (int i = 0; i < n; ++i) {
          CalcTask task = new CalcTask(i);
          new Thread(task).start();
          }

          public class CalcTask extends Task<Integer> {
          protected int id;

          public CalcTask (int id) {
          this.id = id;
          }

          public void succeeded() {
          process(this.getValue());
          }

          @Override
          public Integer call() {
          return CALCULATION_RESULT;
          }
          }


          or even use plain Runnable instead of Task:



          public class CalcTask implements Runnable {
          protected int id;

          public CalcTask (int id) {
          this.id = id;
          }

          @Override
          public void run() {
          CALCULATION_RESULT = calculate();
          process(CALCULATION_RESULT);
          }
          }





          share|improve this answer













          Since you extend class Task, you can also overwrite method succeeded() and remove invocation of task.setOnSucceeded() on the main thread:



          for (int i = 0; i < n; ++i) {
          CalcTask task = new CalcTask(i);
          new Thread(task).start();
          }

          public class CalcTask extends Task<Integer> {
          protected int id;

          public CalcTask (int id) {
          this.id = id;
          }

          public void succeeded() {
          process(this.getValue());
          }

          @Override
          public Integer call() {
          return CALCULATION_RESULT;
          }
          }


          or even use plain Runnable instead of Task:



          public class CalcTask implements Runnable {
          protected int id;

          public CalcTask (int id) {
          this.id = id;
          }

          @Override
          public void run() {
          CALCULATION_RESULT = calculate();
          process(CALCULATION_RESULT);
          }
          }






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 18 '18 at 4:19









          Alexei KaigorodovAlexei Kaigorodov

          10.1k11029




          10.1k11029








          • 1





            Just want to point out that your two examples are not equivalent. The Task.succeeded method will call process on the FX thread whereas the pure Runnable will call process on whatever thread called run.

            – Slaw
            Nov 18 '18 at 11:26













          • Thanks! I will give it a try later this day and come back to comment on this.

            – Big Lebowski
            Nov 18 '18 at 12:37











          • OK, thank you for the answer. I ended up implementing it like this (the Task variant). Still I am a bit curious if there is no "cleaner" way to implement this. I was thinking about a "container", which holds all the Tasks - and if all the Tasks have finished, the "container" would trigger an event and you can fetch all the Tasks results. But anyway - thank you!

            – Big Lebowski
            Nov 18 '18 at 15:03














          • 1





            Just want to point out that your two examples are not equivalent. The Task.succeeded method will call process on the FX thread whereas the pure Runnable will call process on whatever thread called run.

            – Slaw
            Nov 18 '18 at 11:26













          • Thanks! I will give it a try later this day and come back to comment on this.

            – Big Lebowski
            Nov 18 '18 at 12:37











          • OK, thank you for the answer. I ended up implementing it like this (the Task variant). Still I am a bit curious if there is no "cleaner" way to implement this. I was thinking about a "container", which holds all the Tasks - and if all the Tasks have finished, the "container" would trigger an event and you can fetch all the Tasks results. But anyway - thank you!

            – Big Lebowski
            Nov 18 '18 at 15:03








          1




          1





          Just want to point out that your two examples are not equivalent. The Task.succeeded method will call process on the FX thread whereas the pure Runnable will call process on whatever thread called run.

          – Slaw
          Nov 18 '18 at 11:26







          Just want to point out that your two examples are not equivalent. The Task.succeeded method will call process on the FX thread whereas the pure Runnable will call process on whatever thread called run.

          – Slaw
          Nov 18 '18 at 11:26















          Thanks! I will give it a try later this day and come back to comment on this.

          – Big Lebowski
          Nov 18 '18 at 12:37





          Thanks! I will give it a try later this day and come back to comment on this.

          – Big Lebowski
          Nov 18 '18 at 12:37













          OK, thank you for the answer. I ended up implementing it like this (the Task variant). Still I am a bit curious if there is no "cleaner" way to implement this. I was thinking about a "container", which holds all the Tasks - and if all the Tasks have finished, the "container" would trigger an event and you can fetch all the Tasks results. But anyway - thank you!

          – Big Lebowski
          Nov 18 '18 at 15:03





          OK, thank you for the answer. I ended up implementing it like this (the Task variant). Still I am a bit curious if there is no "cleaner" way to implement this. I was thinking about a "container", which holds all the Tasks - and if all the Tasks have finished, the "container" would trigger an event and you can fetch all the Tasks results. But anyway - thank you!

          – Big Lebowski
          Nov 18 '18 at 15:03













          0














          In my opinion the better way is RxJavaFx

          This sample: https://github.com/pkrysztofiak/rxjavafx-demo

          RxJavaFx tutorial https://github.com/ReactiveX/RxJavaFX



          package com.github.pkrysztofiak.rxjavafx.rxjavafxdemo.concurrency;

          import java.util.Random;

          import io.reactivex.Observable;
          import io.reactivex.rxjavafx.observables.JavaFxObservable;
          import io.reactivex.rxjavafx.schedulers.JavaFxScheduler;
          import io.reactivex.schedulers.Schedulers;
          import javafx.application.Application;
          import javafx.scene.Scene;
          import javafx.scene.control.Button;
          import javafx.scene.control.Label;
          import javafx.scene.layout.HBox;
          import javafx.stage.Stage;

          public class ParallelTasksApp extends Application {

          public static void main(String args) {
          launch(args);
          }

          @Override
          public void start(Stage stage) throws Exception {
          Button button = new Button("Start");
          Label label = new Label();
          HBox hBox = new HBox(button, label);
          stage.setScene(new Scene(hBox));
          stage.show();

          JavaFxObservable.actionEventsOf(button)
          .flatMap(actionEvent -> Observable.range(1, 4))
          .flatMap(i -> Observable.just(i)
          .subscribeOn(Schedulers.newThread())
          .map(this::runLongProcess))
          .observeOn(JavaFxScheduler.platform())
          .scan(0, (aggregator, next) -> ++aggregator)
          .map(String::valueOf)
          .subscribe(label::setText);
          }

          private int runLongProcess(int i) {
          try {
          Thread.sleep(new Random().nextInt(10000));
          } catch (InterruptedException e) {
          e.printStackTrace();
          }
          System.out.println(Thread.currentThread().getName() + " i=" + i);
          return i;
          }
          }





          share|improve this answer
























          • Hi - thanks for your answer, but I dont like excessive method chaining. Maybe for some people this is an elegant solution, but sadly not for me. I still thank you very much for contribution :)

            – Big Lebowski
            Nov 18 '18 at 12:44
















          0














          In my opinion the better way is RxJavaFx

          This sample: https://github.com/pkrysztofiak/rxjavafx-demo

          RxJavaFx tutorial https://github.com/ReactiveX/RxJavaFX



          package com.github.pkrysztofiak.rxjavafx.rxjavafxdemo.concurrency;

          import java.util.Random;

          import io.reactivex.Observable;
          import io.reactivex.rxjavafx.observables.JavaFxObservable;
          import io.reactivex.rxjavafx.schedulers.JavaFxScheduler;
          import io.reactivex.schedulers.Schedulers;
          import javafx.application.Application;
          import javafx.scene.Scene;
          import javafx.scene.control.Button;
          import javafx.scene.control.Label;
          import javafx.scene.layout.HBox;
          import javafx.stage.Stage;

          public class ParallelTasksApp extends Application {

          public static void main(String args) {
          launch(args);
          }

          @Override
          public void start(Stage stage) throws Exception {
          Button button = new Button("Start");
          Label label = new Label();
          HBox hBox = new HBox(button, label);
          stage.setScene(new Scene(hBox));
          stage.show();

          JavaFxObservable.actionEventsOf(button)
          .flatMap(actionEvent -> Observable.range(1, 4))
          .flatMap(i -> Observable.just(i)
          .subscribeOn(Schedulers.newThread())
          .map(this::runLongProcess))
          .observeOn(JavaFxScheduler.platform())
          .scan(0, (aggregator, next) -> ++aggregator)
          .map(String::valueOf)
          .subscribe(label::setText);
          }

          private int runLongProcess(int i) {
          try {
          Thread.sleep(new Random().nextInt(10000));
          } catch (InterruptedException e) {
          e.printStackTrace();
          }
          System.out.println(Thread.currentThread().getName() + " i=" + i);
          return i;
          }
          }





          share|improve this answer
























          • Hi - thanks for your answer, but I dont like excessive method chaining. Maybe for some people this is an elegant solution, but sadly not for me. I still thank you very much for contribution :)

            – Big Lebowski
            Nov 18 '18 at 12:44














          0












          0








          0







          In my opinion the better way is RxJavaFx

          This sample: https://github.com/pkrysztofiak/rxjavafx-demo

          RxJavaFx tutorial https://github.com/ReactiveX/RxJavaFX



          package com.github.pkrysztofiak.rxjavafx.rxjavafxdemo.concurrency;

          import java.util.Random;

          import io.reactivex.Observable;
          import io.reactivex.rxjavafx.observables.JavaFxObservable;
          import io.reactivex.rxjavafx.schedulers.JavaFxScheduler;
          import io.reactivex.schedulers.Schedulers;
          import javafx.application.Application;
          import javafx.scene.Scene;
          import javafx.scene.control.Button;
          import javafx.scene.control.Label;
          import javafx.scene.layout.HBox;
          import javafx.stage.Stage;

          public class ParallelTasksApp extends Application {

          public static void main(String args) {
          launch(args);
          }

          @Override
          public void start(Stage stage) throws Exception {
          Button button = new Button("Start");
          Label label = new Label();
          HBox hBox = new HBox(button, label);
          stage.setScene(new Scene(hBox));
          stage.show();

          JavaFxObservable.actionEventsOf(button)
          .flatMap(actionEvent -> Observable.range(1, 4))
          .flatMap(i -> Observable.just(i)
          .subscribeOn(Schedulers.newThread())
          .map(this::runLongProcess))
          .observeOn(JavaFxScheduler.platform())
          .scan(0, (aggregator, next) -> ++aggregator)
          .map(String::valueOf)
          .subscribe(label::setText);
          }

          private int runLongProcess(int i) {
          try {
          Thread.sleep(new Random().nextInt(10000));
          } catch (InterruptedException e) {
          e.printStackTrace();
          }
          System.out.println(Thread.currentThread().getName() + " i=" + i);
          return i;
          }
          }





          share|improve this answer













          In my opinion the better way is RxJavaFx

          This sample: https://github.com/pkrysztofiak/rxjavafx-demo

          RxJavaFx tutorial https://github.com/ReactiveX/RxJavaFX



          package com.github.pkrysztofiak.rxjavafx.rxjavafxdemo.concurrency;

          import java.util.Random;

          import io.reactivex.Observable;
          import io.reactivex.rxjavafx.observables.JavaFxObservable;
          import io.reactivex.rxjavafx.schedulers.JavaFxScheduler;
          import io.reactivex.schedulers.Schedulers;
          import javafx.application.Application;
          import javafx.scene.Scene;
          import javafx.scene.control.Button;
          import javafx.scene.control.Label;
          import javafx.scene.layout.HBox;
          import javafx.stage.Stage;

          public class ParallelTasksApp extends Application {

          public static void main(String args) {
          launch(args);
          }

          @Override
          public void start(Stage stage) throws Exception {
          Button button = new Button("Start");
          Label label = new Label();
          HBox hBox = new HBox(button, label);
          stage.setScene(new Scene(hBox));
          stage.show();

          JavaFxObservable.actionEventsOf(button)
          .flatMap(actionEvent -> Observable.range(1, 4))
          .flatMap(i -> Observable.just(i)
          .subscribeOn(Schedulers.newThread())
          .map(this::runLongProcess))
          .observeOn(JavaFxScheduler.platform())
          .scan(0, (aggregator, next) -> ++aggregator)
          .map(String::valueOf)
          .subscribe(label::setText);
          }

          private int runLongProcess(int i) {
          try {
          Thread.sleep(new Random().nextInt(10000));
          } catch (InterruptedException e) {
          e.printStackTrace();
          }
          System.out.println(Thread.currentThread().getName() + " i=" + i);
          return i;
          }
          }






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 18 '18 at 10:29









          Przemek KrysztofiakPrzemek Krysztofiak

          2067




          2067













          • Hi - thanks for your answer, but I dont like excessive method chaining. Maybe for some people this is an elegant solution, but sadly not for me. I still thank you very much for contribution :)

            – Big Lebowski
            Nov 18 '18 at 12:44



















          • Hi - thanks for your answer, but I dont like excessive method chaining. Maybe for some people this is an elegant solution, but sadly not for me. I still thank you very much for contribution :)

            – Big Lebowski
            Nov 18 '18 at 12:44

















          Hi - thanks for your answer, but I dont like excessive method chaining. Maybe for some people this is an elegant solution, but sadly not for me. I still thank you very much for contribution :)

          – Big Lebowski
          Nov 18 '18 at 12:44





          Hi - thanks for your answer, but I dont like excessive method chaining. Maybe for some people this is an elegant solution, but sadly not for me. I still thank you very much for contribution :)

          – Big Lebowski
          Nov 18 '18 at 12:44


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53357250%2fjavafx-multiple-tasks%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          這個網誌中的熱門文章

          Xamarin.form Move up view when keyboard appear

          Post-Redirect-Get with Spring WebFlux and Thymeleaf

          Anylogic : not able to use stopDelay()