How to avoid Not on FX application thread; currentThread = JavaFX Application Thread error?
Asked Answered
T

7

67

Below code snippets is giving me error Not on FX application thread; currentThread=JavaFX Application Thread.This application was working fine in java 1.7 but when i moved it to fx8 it is now giving error. when I start the application on my 1st attempt it is working as intended .But after closing the stage and opening it again it is not working.

The error is also ambiguous Not On fx application thread and current thread- javafx application thread.What did it mean by not on fx application thread if the current thread is a fx application thread.

progressDialog = createProgressDialog(service);
progressDialog.show();
progressDialog.setOnCloseRequest(new EventHandler<WindowEvent>() {
    @Override
    public void handle(WindowEvent event) {
        // if (service.isRunning()) {
        // service.cancel();
        progressDialog.close();
        // }
    }
});
@SuppressWarnings("unchecked")
private Stage createProgressDialog(final Service<IStatus> service) {
    stage = new Stage();

    URL url = FileLocator.find(Activator.getDefault().getBundle(),
    new Path("icons/xxx_16x16.png"), null); //$NON-NLS-1$
    stage.getIcons().add(new Image(url.getFile()));
    stage.setTitle("Downloading ..."); //$NON-NLS-1$
    // Creating StackPane
    stage.initModality(Modality.WINDOW_MODAL);
}
Transition answered 13/1, 2014 at 4:34 Comment(1)
Edit your code to make it an sscce and the answer will become obvious.Codd
T
19

Platform.setImplicitExit(false); solved my problem. I think they changed the implementation in JavaFX 8, so the same code that works without any issue in JavaFX 2 gives the not an fx application thread error there.

Transition answered 23/1, 2014 at 12:47 Comment(0)
T
103

Calling

Platform.runLater(new Runnable() {
    @Override
    public void run() {
        // do your GUI stuff here
    }
});

will fix it.

Tod answered 9/9, 2015 at 22:3 Comment(1)
This will work if you are working on pure javafx application .my application was SWT where i was creating fx component over fxcanvas .If i call the ui creation on Platform.runLater(new Runnable(){ // ... }); then tool kit is not initialized will be thrown .Transition
F
44

This happened with me when i was modifying UI element from task in javafx 2 like listview elements.A Task Which Modifies The Scene Graph helped me to solve the issue i.e. updating UI elements by

 final ListView<String> group = new ListView ();

 Task<Void> task = new Task<Void>() {

     @Override protected Void call() throws Exception {

         group.getItems().clear();  

          for (int i=0; i<100; i++) {                
             Platform.runLater(new Runnable() {
                 @Override public void run() {
                     group.getItems.add(i);
                 }
             });
         }
         return null;
     }
 };
Feuillant answered 11/4, 2014 at 8:10 Comment(3)
Your solution solved my problem aswell. I stillt do not understand why. Can anybody explain to me, why "Platform.runLater(new Runnable(){});" solved it?Heroine
@Yannic Hansen it is cause in javaFX only the FX thread can modify the ui elements.That's why you use Platform.runLater.Christianson
This solved my issue too, i was trying to update window title every 1 minute. Instantly worked.Akkad
D
23

It should happens when you try to change some component UI, like a label text. Running like that works always:

@FXML Label myLabel;

Platform.runLater(new Runnable(){
   myLabel.setText("some text");
});
Dandify answered 27/1, 2016 at 16:14 Comment(0)
T
19

Platform.setImplicitExit(false); solved my problem. I think they changed the implementation in JavaFX 8, so the same code that works without any issue in JavaFX 2 gives the not an fx application thread error there.

Transition answered 23/1, 2014 at 12:47 Comment(0)
U
7

You can change of Form or go to another view or fxml with this in any part of your code :

Platform.runLater(() -> {
                            try {
                                Stage st = new Stage();
                                Parent sceneMain = FXMLLoader.load(getClass().getResource("/com/load/free/form/LoadFile.fxml"));
                                Scene scene = new Scene(sceneMain);
                                st.setScene(scene);
                                st.setMaximized(true);
                                st.setTitle("load");
                                st.show();
                            } catch (IOException ex) {
                                Logger.getLogger(LoginController.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        });

My Example in my Controller :

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Hyperlink;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.stage.Stage;


public class LoginController implements Initializable {

    @FXML
    private TextField txtUser;

    @FXML
    private TextField txtPassword;

    @FXML
    private Hyperlink urlForgetPassword;

    @FXML
    private Label lblError;

    @Override
    public void initialize(URL url, ResourceBundle rb) {

    }

    public void isLoginAction(ActionEvent event) {
        String message = "Ingrese ";
        boolean isEmtpy = false;

        if (txtUser.getText().trim().isEmpty()) {
            message += "usuario y ";
            isEmtpy = true;
        }

        if (txtPassword.getText().trim().isEmpty()) {
            message += "contraseña  ";
            isEmtpy = true;
        }
        isEmtpy = false;
        if (isEmtpy) {
            message = message.substring(0, message.length() - 2);
            lblError.getStyleClass().remove("message_process");
            lblError.getStyleClass().add("message_error");
            lblError.setText(message);
        } else {
            lblError.getStyleClass().add("message_process");
            lblError.getStyleClass().remove("message_error");
            Task task = new Task<Void>() {
                @Override
                protected Void call() throws Exception {
                    updateMessage("Procesando...");
                    System.out.println("Asignando DATOS DE PRUEBA ");
                    String passEnc = Encripta.encriptar(txtPassword.getText(), Encripta.HASH_SHA1);
                    int typeRest = new RestConnection().getConnectionUser(txtUser.getText(), passEnc);
                    if (typeRest == 1) {
                        //Load Another form
                        Platform.runLater(() -> {
                            try {
                                Stage st = new Stage();
                                Parent sceneMain = FXMLLoader.load(getClass().getResource("/com/load/free/form/LoadFile.fxml"));
                                Scene scene = new Scene(sceneMain);
                                st.setScene(scene);
                                st.setMaximized(true);
                                st.setTitle("");
                                st.show();
                            } catch (IOException ex) {
                                Logger.getLogger(LoginController.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        });

                    } else {
                        lblError.getStyleClass().remove("message_process");
                        lblError.getStyleClass().add("message_error");
                        updateMessage("Usuario y/o contraseña incorrectos");
                    }
                    return null;
                }
            };

            lblError.textProperty().bind(task.messageProperty());
            new Thread(task).start();

        }

    }

}
Utrecht answered 26/4, 2016 at 22:10 Comment(0)
B
5

It's not shown explicitly in the code above, but what I'm fairly sure is happening is that somewhere you are creating a thread outside of the application (main) javafx thread, and then you are trying to preform operations on javafx objects (like closing, opening windows, etc.) on the SECOND thread. This is strictly not allowed, as only the main thread can control javafx objects directly. If this becomes a requirement of your program that you need to use the second thread for other things like computations, etc, etc. You must use some form of message passing to let the other thread know that you want to do whatever javafx action.

Berey answered 14/1, 2014 at 17:18 Comment(1)
This specifically solved the issue that led me here, trying to do a Thread initThread = new Thread(new Runnable() { ... scraper.init(); navButton.setText("Finished!"); ... }); initThread.start(); and I didn't know that other threads trying to access the javafx application thread was disallowed (which it obviously should be :P ). I'll implement message passing. ThanksRecrement
H
1

I experienced the same problem while trying to add a splash screen for my program. This is how my code was

CircleTest pForm = new CircleTest();

Task<Void> task = new Task<Void>() {
    @Override
    public Void call() {

        try {
            FXMLLoader loader = new FXMLLoader(
                Main.class.getResource("/newRegistration/HomePage.fxml"));
            AnchorPane page = (AnchorPane) loader
                .load();
            dialogStagee.getIcons().add(new Image("/piks/showthumb.png"));
            dialogStagee.setTitle("WALGOTECH SOLUTIONS: 0703445354");
            dialogStagee.initModality(Modality.APPLICATION_MODAL);
            Scene scene = new Scene(page);
            dialogStagee.setScene(scene);
            HomePageController controller = loader.getController();
            controller.setDialogStage(dialogStagee);
            dialogStagee.setMaximized(true);
            dialogStagee.initStyle(StageStyle.UNDECORATED);

            conn.prepareStatement(
                "INSERT INTO `logs`(`date`,`user`,`Terminal`,`Action`)"
                    + " VALUES ('"
                    + (java.time.LocalDate.now()
                    + " "
                    + java.time.LocalTime.now().getHour()
                    + ":"
                    + java.time.LocalTime.now().getMinute()
                    + ":" + java.time.LocalTime.now().getSecond())
                    + "',"
                    + "'"
                    + DbConnector.getMyVariablepatientvameloginCategory()
                                                        .split("as")[1]
                    + "',"
                    + "'"
                    + StartPageController.hostname
                    + "',"
                    + " 'Logged in into Registration')")
                                        .execute();
            } catch (Exception e) {
                    e.printStackTrace();
            }   

            return null;
        }
};
pForm.activateProgressBar(task);

task.setOnSucceeded(event -> {

    dialogStagee.show();

    try {

    } catch (Exception e) {

    }
    pForm.getDialogStage().close();
});

pForm.getDialogStage().show();
dialogStage.close();

Thread thread = new Thread(task);
thread.start();

Running this gave a 'not on fx application'. By adding Platform.runLater() inside my task, that solved the issue. Now, this is how I currently have my code:

CircleTest pForm = new CircleTest();

Task<Void> task = new Task<Void>() {
    @Override
    public Void call() {
        Platform.runLater(new Runnable() {

            @Override
            public void run() {

                try {
                    FXMLLoader loader = new FXMLLoader(
                                        Main.class
                                                .getResource("/newRegistration/HomePage.fxml"));
                    AnchorPane page = (AnchorPane) loader
                                        .load();
                    dialogStagee.getIcons().add(
                                        new Image("/piks/showthumb.png"));
                    dialogStagee
                                        .setTitle("WALGOTECH SOLUTIONS: 0703445354");
                    dialogStagee
                                        .initModality(Modality.APPLICATION_MODAL);
                    Scene scene = new Scene(page);
                    dialogStagee.setScene(scene);
                    HomePageController controller = loader
                                        .getController();
                    controller.setDialogStage(dialogStagee);
                    dialogStagee.setMaximized(true);
                    dialogStagee.initStyle(StageStyle.UNDECORATED);

                    conn.prepareStatement(
                        "INSERT INTO `logs`(`date`,`user`,`Terminal`,`Action`)"
                        + " VALUES ('"
                        + (java.time.LocalDate.now()
                        + " "
                        + java.time.LocalTime.now().getHour()
                        + ":"
                        + java.time.LocalTime.now().getMinute()
                        + ":" + java.time.LocalTime.now().getSecond())
                        + "',"
                        + "'"
                        + DbConnector.getMyVariablepatientvameloginCategory()
                                                        .split("as")[1]
                        + "',"
                        + "'"
                        + StartPageController.hostname
                        + "',"
                        + " 'Logged in into Registration')")
                                        .execute();
                } catch (Exception e) {
                    e.printStackTrace();
                }   
            }
        });

        return null;
    }
};
pForm.activateProgressBar(task);

task.setOnSucceeded(event -> {

    dialogStagee.show();

    try {

    } catch (Exception e) {

    }
    pForm.getDialogStage().close();
});

pForm.getDialogStage().show();
dialogStage.close();

// dialogStage.setDisable(true);
Thread thread = new Thread(task);
thread.start();

I hope this will help you solve the problem. Cheers.

Hoeg answered 21/9, 2019 at 13:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.