Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFX2: Can I pause a background Task / Service?

I am trying to set up a background service that would perform bulk loading of transaction data from a csv file. This background service would be initiated from a menu item action mapped to a method in the controller/presenter class.

Ever so often, some data turns up in the csv file for which no master data can be found in the database, this would normally cause the upload to choke and fail.

On such occasions, I would like to be able to have the background service pause its processing and invoke a dialog from a presenter class to take in user input. The user input would be used to add a master row in the database, after which the background service should resume from where it had left off (not from the beginning of the csv file, but from the row which caused the error).

Is this possible to achieve in JavaFX, perhaps with the javafx.concurrent API? How would I go about doing this?

like image 948
Lambda II Avatar asked Feb 18 '13 16:02

Lambda II


1 Answers

Solution

When your background process encounters a situation where it requires a user to be prompted for input, use FutureTask executed in Platform.runLater to showAndWait the dialog prompt on the JavaFX application thread. In the background process use futureTask.get to pause the background process until the user has input the necessary values which will allow the process to continue.


Sample Code Snippet

Here is the essence of code for this approach which can be placed inside the call method of your background process:

String nextText = readLineFromSource();
if ("MISSING".equals(nextText)) {
  updateMessage("Prompting for missing text");
  FutureTask<String> futureTask = new FutureTask(
    new MissingTextPrompt()
  );
  Platform.runLater(futureTask);
  nextText = futureTask.get();
}
...
class MissingTextPrompt implements Callable<String> {
  private TextField textField;

  @Override public String call() throws Exception {
    final Stage dialog = new Stage();
    dialog.setScene(createDialogScene());
    dialog.showAndWait();
    return textField.getText();
  }
  ...
}

Sample Application

I created a small, complete sample application to demonstrate this approach.

The output of the sample application is:

promptingtaskdemooutput

Sample Output Explanation

Lines read without missing values are just plain brown. Lines with a prompt value entered have a pale green background. Fourteen lines have been read, the background task has already paused once at the 6th line which was missing a value. The user was prompted for the missing value (to which the user entered xyzzy), then the process continued until line 14 which is also missing and the background task is again paused and another prompt dialog is being displayed.

like image 99
jewelsea Avatar answered Nov 16 '22 16:11

jewelsea