14

I have a problem while working with JavaFX and Threads. Basically I have two options: working with Tasks or Platform.runLater. As I understand Platform.runLater should be used for simple/short tasks, and Task for the longer ones. However, I cannot use any of them.

When I call Thread, it has to pop up a captcha dialog in a middle of task. While using Task, it ignores my request to show new dialog... It does not let me to create a new stage.

On the other hand, when I use Platform.runLater, it lets me show a dialog, however, the program's main window freezes until the pop up dialog is showed.

I need any kind of solution for this. If anyone knows how to deal with this or had some similar experience and found a solution I am looking forward to hearing from you!

jmrk
  • 34,271
  • 7
  • 59
  • 74
ksarunas
  • 1,187
  • 2
  • 11
  • 16
  • possible duplicate of [JavaFX2: Can I pause a background Task / Service?](http://stackoverflow.com/questions/14941084/javafx2-can-i-pause-a-background-task-service) – jewelsea May 23 '13 at 22:49

4 Answers4

39

As puce says, you have to use Task or Service for the things that you need to do in background. And Platform.runLater to do things in the JavaFX Application thread from the background thread.

You have to synchronize them, and one of the ways to do that is using the class CountDownLatch.

Here is an example:

Service<Void> service = new Service<Void>() {
        @Override
        protected Task<Void> createTask() {
            return new Task<Void>() {           
                @Override
                protected Void call() throws Exception {
                    //Background work                       
                    final CountDownLatch latch = new CountDownLatch(1);
                    Platform.runLater(new Runnable() {                          
                        @Override
                        public void run() {
                            try{
                                //FX Stuff done here
                            }finally{
                                latch.countDown();
                            }
                        }
                    });
                    latch.await();                      
                    //Keep with the background work
                    return null;
                }
            };
        }
    };
    service.start();
Antonio J.
  • 1,750
  • 3
  • 21
  • 33
  • Exactly what I was searching for. Thank you so much! – ksarunas May 23 '13 at 15:41
  • After looking at this answer closer, I have come to the conclusion that this is a terrible answer. I would recommend using `Service` or `Task` as they are designed. See https://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm – SedJ601 Jul 31 '23 at 16:05
8

Use a Worker (Task, Service) from the JavaFX Application thread if you want to do something in the background.

http://docs.oracle.com/javafx/2/api/javafx/concurrent/package-summary.html

Use Platform.runLater from a background thread if you want to do something on the JavaFX Application thread.

http://docs.oracle.com/javafx/2/api/javafx/application/Platform.html#runLater%28java.lang.Runnable%29

Puce
  • 37,247
  • 13
  • 80
  • 152
  • I create a Worker (Task). Once I need so show a pop up I call Platform.runLater however I need to wait for response (it is input dialog), but if I create new thread (Platform.runLater) it does not wait for respons and Worker continues... How to deal with it. Maybe there is a way to pause Worker thread wait for input from Platform.runLater and then continue...? – ksarunas May 23 '13 at 10:22
0

It's too late to answer but for those who have the error, here is the solution XD

You can use one Thread.

Use the lambda expression for the runnable in the thread and the runlater.

Thread t = new Thread(() -> {
        //Here write all actions that you want execute on background

        Platform.runLater(() -> {
            //Here the actions that use the gui where is finished the actions on background.
        });
    });
t.start();
-2

You can user directly this code Don't forget you can't send non-final variable in thread . you can send final variable in thread

     //final String me="ddddd";
      new Thread(new Runnable() {
            @Override
            public void run() {
                    // me = me + "eee";
                    //...Your code....
              
            }
        }).start();

Use in

your code

try/catch

m-tech
  • 338
  • 2
  • 14