Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFX working with threads and GUI

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!

like image 749
ksarunas Avatar asked May 23 '13 08:05

ksarunas


People also ask

Does JavaFX use threads?

JavaFX uses a single-threaded rendering design, meaning only a single thread can render anything on the screen, and that is the JavaFX application thread. In fact, only the JavaFX application thread is allowed to make any changes to the JavaFX Scene Graph in general.

What is the method in JavaFX to run a method in the UI thread?

runLater(Runnable) .

Is JavaFX thread safe?

The JavaFX scene graph, which represents the graphical user interface of a JavaFX application, is not thread-safe and can only be accessed and modified from the UI thread also known as the JavaFX Application thread.

Is JavaFX used for GUI?

JavaFX is a GUI toolkit for Java (GUI is short for Graphical User Interface). JavaFX makes it easier to create desktop applications and games in Java.


2 Answers

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();
like image 115
Antonio J. Avatar answered Oct 08 '22 13:10

Antonio J.


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

like image 8
Puce Avatar answered Oct 08 '22 12:10

Puce