0

I am currently trying to create a Stage in a background thread using the Task<Stage> object, which is not working, because the Task never finishes.

Here is my code:

Task<Stage> myTask = new Task<Stage>() {

    @Override
    protected Stage call() throws Exception {
        Stage stage = new Stage();
        return stage;
    }
};

myTask.setOnSucceeded(e -> {
    System.out.println("done :D");
});

 myTask.setOnFailed(e -> {
    System.out.println("oh no");
    myTask.getException().printStackTrace();
});

new Thread(myTask).start();

The method above prints oh no and following exception message:

java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-5
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Unknown Source)
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(Unknown Source)
at javafx.stage.Stage.<init>(Unknown Source)
at javafx.stage.Stage.<init>(Unknown Source)
at controller.ManageWebsiteTestsWindowController$OpenButton$1.call(ManageWebsiteTestsWindowController.java:77)
at controller.ManageWebsiteTestsWindowController$OpenButton$1.call(ManageWebsiteTestsWindowController.java:1)
at javafx.concurrent.Task$TaskCallable.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

When I use the same code to create a e.g. Label, it works perfectly fine:

Task<Label> myTask = new Task<Label>() {

    @Override
    protected Label call() throws Exception {
        Label label = new Label("Hello World");
        return label;
    }
};
myTask.setOnSucceeded(e -> {
    System.out.println("done :D");
});

myTask.setOnFailed(e -> {
    System.out.println("oh no");
    myTask.getException().printStackTrace();
});

new Thread(myTask).start();

What am I doing wrong?

Some background information: I am trying to create a Popout object which extends Stage.

Angry Red Panda
  • 388
  • 1
  • 4
  • 24
  • See this https://stackoverflow.com/questions/21083945/how-to-avoid-not-on-fx-application-thread-currentthread-javafx-application-th – xingbin Feb 14 '18 at 10:02
  • 1
    As stated in the [documentation](https://docs.oracle.com/javase/8/javafx/api/javafx/stage/Stage.html): "Stage objects must be constructed and modified on the JavaFX Application Thread". At any rate, creating a stage shouldn't be a long/heavy process, and as such there is usually no need to create it in a `Task`. Why did you try doing it in the first place? – Itai Feb 14 '18 at 10:04
  • @sillyfly hey, I am trying to create a Object that `extends` Stage. My Object is called `Popup` and it takes about two seconds for it to get created, thats why I wanted to use a task. The `Stage` that I tried to create in the code above was just for debugging purposes. – Angry Red Panda Feb 14 '18 at 11:20
  • You should perhaps look into why it takes long to get created... Perhaps some of the creation logic isn't really UI-related, and it alone may be delegated to a task/background thread... – Itai Feb 14 '18 at 11:27
  • @sillyfly the reason it is taking so long to get created, is because there are many SQL queries involved. my plan was to show a loadingscreen while the `Stage` and its content is getting created, so the user doesnt get the impression that the application froze. so you would be advising me to put my SQL queries in a background thread and once its done, join that thread and create the `Stage` to display said content? – Angry Red Panda Feb 14 '18 at 11:41
  • 2
    Do the database work in your task and return the results from the `call()` method. Then create the UI to display the results in the `onSucceeded()` handler. See https://stackoverflow.com/questions/30249493/using-threads-to-make-database-requests for something similar. – James_D Feb 14 '18 at 12:11

0 Answers0