title: How to properly thread off javafx Alerts/fileChooser etc
body: <p>I was looking at this question <a href="https://stackoverflow.com/questions/32773115/javafx-show-dialogue-after-thread-task-is-completed">JavaFX show dialogue after thread task is completed</a>, but my question is kind of the opposite. What is the best way to thread off after a filechooser or alert where you need some data back from the user?</p>
  
  <p>Here's what I have now:</p>
  
  <pre><code>Platform.runLater(()-&gt;{
      File file = fileChooser.showOpenDialog(root.getScene().getWindow());
      if(file == null) {
          return;
      }
      executorService.execute(()-&gt;{
          //more code here which uses file
      });
  });
  </code></pre>
  
  <p>where executorService is an ExecutorService that was made earlier. I suppose I could just as easily use a Task or a Thread or anything else, but how it's threaded off doesn't matter, just that it's something that takes a while that I don't want to have happen on the Application thread because it would lock up the UI. </p>
  
  <p>I know this isn't an mvce, but I hope it demonstrates the problem I'm having with threads inside <code>Platform.runLater</code> calls.</p>
  
  <p>Here's an extreme example of how convoluted this kind of thing gets</p>
  
  <pre><code>@FXML
  public void copyFiles(ActionEvent event){
      //this method is on the application thread because a button or something started it
      // so we thread off here
      executorService.execute(()-&gt;{
          // do some stuff
          // ...
          // get location to copy to from user
          // must happen on the application thread!
          Platform.runLater(()-&gt;{
              File file = fileChooser.showOpenDialog(root.getScene().getWindow());
              if(file == null) {
                  return;
              }
              executorService.execute(()-&gt;{
                  // more code here which uses file
                  // ...
                  // oh wait, some files have the same names! 
                  // we need a user's confirmation before proceeding
                  Platform.runLater(()-&gt;{
                      Alert alert = new Alert(AlertType.CONFIRMATION, "Do you want to overwrite files with the same names?", ButtonType.OK, ButtonType.CANCEL);
                      Optional&lt;ButtonType&gt; choice = alert.showAndWait();
                      if(choice.isPresent &amp;&amp; choice.get == ButtonType.OK){
                          // do something, but not on the application thread
                          executorService.execute(()-&gt;{
                              // do the last of the copying
                              // ...
                          });
                      }
                  });
              });
          });
      });
  }
  </code></pre>