Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multithreading in JavaFX hangs the UI

Tags:

I have a simple JavaFX 2 app, with 2 buttons, saying Start and Stop. When the start button is clicked, I want to create a background thread which will do some processing and update the UI (e.g a progress bar) as it goes along. If the stop button is clicked, I want the thread to terminate.

I've tried to do this using the javafx.concurrent.Task class which I gathered from the documentation would work fine for this. But whenever I click Start, the UI freezes/hangs rather than staying normal.

Her's the code from the main Myprogram extends Application class for showing the buttons:

public void start(Stage primaryStage) {                    final Button btn = new Button();     btn.setText("Begin");      //This is the thread, extending javafx.concurrent.Task :     final MyProcessor handler = new MyProcessor();     btn.setOnAction(new EventHandler<ActionEvent>()     {         public void handle(ActionEvent event)         {                            handler.run();          }     });      Button stop = new Button();     stop.setText("Stop");     stop.setOnAction(new EventHandler<ActionEvent>()         {              public void handle(ActionEvent event)              {                 handler.cancel();              }         }      );     // Code for adding the UI controls to the stage here. } 

Here's the code of MyProcessor class:

import javafx.concurrent.Task; public class MyProcessor extends Task {        @Override     protected Integer call()     {         int i = 0;         for (String symbol : feed.getSymbols() )         {             if ( isCancelled() )             {                 Logger.log("Stopping!");                 return i;             }             i++;             Logger.log("Doing # " + i);             //Processing code here which takes 2-3 seconds per iteration to execute             Logger.log("# " + i + ", DONE! ");                     }         return i;     } } 

Pretty simple, but the UI hangs whenever I click the Start button, though the console messages continue to get displayed (Logger.log simply does System.out.println )

What am I doing wrong?

like image 670
Ali Avatar asked Feb 03 '13 15:02

Ali


People also ask

Why is JavaFX not thread safe?

Thread safety in a JavaFX application cannot be achieved by synchronizing thread actions. We must ensure that the programs that manipulate the scene graph must do so only from the JavaFX Application Thread. Therefore, multithreading in JavaFX has to be handled in a different manner.

How do you stop a thread in JavaFX?

application. Application#stop() is called before the context terminates. Put inside the stop() method everything that needs to be executed before the JavaFX context terminates. With the System.

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.


1 Answers

Task implements Runnable, so when you call handler.run(); you actually run the call method in the UI Thread. That will hang the UI.

You should start the task in a background thread, either via an executor or simply by calling new Thread(handler).start();.

This is explained (maybe not very clearly) in the javadoc or in the JavaFX concurrency tutorial.

like image 112
assylias Avatar answered Oct 13 '22 15:10

assylias