Java FX : Unable to open popup from different FX thread

filechooser javafx
javafx thread update ui
javafx filechooser save file
javafx filechooser get path
javafx filechooser multiple files
javafx thread-sleep
file chooser in javafx scene builder
javafx update label from thread

Hi I have application which runs both on GUI(Java FX) as well as command line. When run as GUI, i show the status on text area. This works fine.

But the issue is when ever i try to show a error(via popup) from some different (non javafx) class, it shows me Java Fx - thread Exception not on FX thread.

Below is my code

This is my Java FX class where I wish to show popup.

public class DeploymentProcesController implements Initializable {


@FXML
private TextArea statusTextArea;

@Override
public void initialize(URL location, ResourceBundle resources) {

}

public void updateGUIMessage(String message) {
    if (Platform.isFxApplicationThread()) {
        statusTextArea.appendText(message);
    } else {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                statusTextArea.appendText(message);
            }
        });
    }
}

public void displayAlertMessages(final String message) {
    Platform.setImplicitExit(false);
    Task<Void> task = new Task<Void>() {
        @Override public Void call() {
            Platform.runLater(new Runnable() {
                public void run() {
                    Alert alert = new Alert(AlertType.INFORMATION, message, ButtonType.OK);
                    alert.showAndWait();
                }
            });

            return null;
        }
    };
    new Thread(task).start();
}

}

I have a non FX class which is the entry point. So Based on type of run (command line / GUI ) I update the status.

Here is how I am calling to update the status.

public void promptUser(String message,boolean isCommandLineRun){
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
    if(isCommandLineRun) {
        System.out.println(simpleDateFormat.format(new Date()) + " - " + message);
    } else {
        controller.displayAlertMessages(message);
    }
}

I have no issues when i call the updateGUIMessage method from non fx class. This is because the statusArea element is on FX thread(member of this fx class).

Also I have no issues to generate a alert box on some button click, but to display an Alert box from a different class- I am having issues since as soon as I try to generate a alert box , the application crashes, saying not on fx thread.

I understand that the Alert box is a popup and therefore may be unhandled. But can anyone help me, I want to show user a alert box, from different class.

Everything in the UI has to be executed from the UI application thread. That is exactly what the error message means.

Fortunately you can simply wrap your call so that it is executed in the UI thread:

if(isCommandLineRun) {
    System.out.println(simpleDateFormat.format(new Date()) + " - " + message);
} else {
    Platform.runLater(() -> controller.displayAlertMessages(message));
}

Javafx close window and open another, At first I wasn't even able to launch any JavaFX app with the JPen library and goxr3plus/FX-BorderlessScene If you open just an image in a pop up window The JavaFX Application Thread is created as part of the startup� 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. Implementing long-running tasks on the JavaFX Application thread inevitably makes an application UI unresponsive.

Finally found the solution to it,

Since Java fx runs on single thread, everything has to be on same thread. For every task (such as popup) where there needs background to pause, we need to use FutureTask.

I found this article, here :

JavaFX2: Can I pause a background Task / Service?

Using JavaFX UI Controls: File Chooser, The samples provided in this chapter explain how to open one or several files, classes, the FileChooser class does not belong to the javafx.scene.controls package. other basic root graphical elements, such as Stage , Window , and Popup . main(String[] args) { Application.launch(args); } private void openFile( File file)� My JavaFX application runs but doesn't open up the window. In Eclipse, I have it as a JavaFX Project, running as a Java Application. But when I hit run, the window doesn't show up.

Assuming that you want some long running code to run before the popup is called, There are two steps that need to be done when dealing with the Fx Buttons. The first thread lets the code run as a thread when the button is pushed. The second is the Platform.runlater() which is telling the Fx Platform to execute the code in that thread from the Platform. Note that the popup will not get executed until the runlater is reached in the outer thread. Otherwise you can call the popup directly.

public void MyExampleBtn() {
  Thread t = new Thread() {
    // long running work to be done, threaded so as not to hang the main controls.
    // .... 
    // work is done do the success popup
    @Override
      public void run() {
      Platform.runLater(new Runnable() {
       @Override
         public void run() {
           Alert alert = new Alert(AlertType.INFORMATION);
           alert.setTitle("Success!");
           alert.setHeaderText(null);
           alert.setContentText("This is my popup");
           alert.showAndWait();
         }
       });
     }
   };
}

Concurrency in JavaFX, Implementing long-running tasks on the JavaFX Application thread inevitably the JavaFX Application thread and other constraints faced by GUI developers. the Worker object, its state becomes FAILED and the exception property is set to the service.start(); } public static void main(String[] args) { launch(); } private static� JavaFX - Event Handling - In JavaFX, we can develop GUI applications, web applications and graphical applications. In such applications, whenever a user interacts with the application (n

Make a popup window that will stay open for 3 seconds, You can't directly shutdown the ExecutorService, because that would cancel the scheduled This means all of your code is running on the JavaFX main thread. JavaFX 8u40 finally includes simple Dialogs and Alerts! I’ve been waiting for this since 2012! In the meantime I wrote about how to use Dialogs in JavaFX 2 and later in JavaFX 8 with ControlsFX. Now that they are available in the official JDK, let’s learn how to use them. Prerequisites. To use the official JavaFX Dialogs you need JDK 8u40

Opening a new Window in JavaFX, 1- Window in JavaFX; 2- Example, Open a Modeless Window; 3- Example, Open a Modal Window You can not interact with any other windows until this window is closed. public static void main(String[] args) { Java for Intermediate Users � Java Fx Concepts With Practical Examples � JavaFX : Learn to build powerful� Recommended Solution Use JavaFX 8u40+, you can find an early access release. For 8u40, the following bug was fixed: RT-17716 Some controls can only be created on the FX application thread This fix allows you to create all controls (except currently a WebView) off of the JavaFX application thread.

JavaFX Concurrency Example, JavaFX, like Swing and AWT, uses a single thread, called JavaFX Application Multiple threads perform different tasks to keep the UI in sync with the user actions. The following examples will show the problem in detail. IllegalStateException: Not on FX application thread; currentThread = Thread- 4. Specifies the popup anchor point which is used in popup positioning. The point can be set to a corner of the popup window or a corner of its content. In this context the content corners are derived from the popup root node's layout bounds. In general changing of the anchor location won't change the current window position.

Comments
  • Any class is free to call any JavaFX class or method, but that call has to be done on the Java FX thread, no matter what class makes the call. If you don’t want a particular class to import Platform, write a method in a different class which makes use of Platform.runLater, and have the "non fx" class call that method.
  • Did not work, First of all, promptUser method is in a NON Java FX class, so I have to import Platform (which I do not want to - Intend to keep JavaFX classes in seperate class). Also after trying this my application crashes and does not show popup. Exception : java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-6
  • Also Platform.runLater shoud be used for small operations, I want to display a alert box, in which i will use showaAndWait() , so using Platform.runLater is not advisable
  • When calling the method controller.displayAlertMessages the update has to happen on the UI thread. So you can move the call of Platform.runLater to the other side and only wrap that part of the code that actually updates the UI.