web-dev-qa-db-fra.com

Comment éviter Not on thread d'application FX; currentThread = Erreur de thread d'application JavaFX?

Les extraits de code ci-dessous me donnent l'erreur Not on FX application thread; currentThread = JavaFXApplication Thread. Cette application fonctionnait bien dans Java 1,7 mais lorsque je l’ai déplacée vers fx8, elle génère maintenant une erreur. Lorsque je lance l’application lors de ma première tentative, elle fonctionne comme prévu. Mais après fermer la scène et l'ouvrir à nouveau ne fonctionne pas.

L'erreur est également ambiguë Not On fx application thread and current thread- javafxapplication 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);
}
34
Rajesh

Platform.setImplicitExit(false); a résolu mon problème. Je pense qu'ils ont changé l'implémentation dans JavaFX 8, donc le même code qui fonctionne sans problème dans JavaFX 2 donne le pas un thread d'application fx erreur.

15
Rajesh

Appel

Platform.runLater(new Runnable(){
// ...
});

va le réparer aussi.

48
Martin Pfeffer

C’est ce qui m’est arrivé lorsque j’étais en train de modifier un élément d’interface utilisateur à partir de la tâche dans javafx 2, comme des éléments listview . ne tâche qui modifie le graphe de scène m’a aidé à résoudre le problème, c’est-à-dire en mettant à jour les éléments d’UI en

 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;
     }
 };
37
vinay

Cela devrait arriver lorsque vous essayez de modifier une interface utilisateur de composant, telle qu'un texte d'étiquette. Courir comme ça marche toujours:

@FXML Label myLabel;

Platform.runLater(new Runnable(){
   myLabel.setText("some text");
});
16
arturvt

Vous pouvez changer de formulaire ou passer à une autre vue ou fichier XML avec ceci dans n’importe quelle partie de votre 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);
                            }
                        });

Mon exemple dans mon contrôleur:

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();

        }

    }

}
5
diego matos - keke

Cela n’apparaît pas explicitement dans le code ci-dessus, mais je suis presque sûr que quelque chose est en train de créer un thread en dehors du thread javafx de l’application (principal), puis vous essayez de préformer des opérations sur des objets javafx (comme la fermeture). , ouverture des fenêtres, etc.) sur le DEUXIÈME fil. Ceci est strictement interdit, car seul le thread principal peut contrôler directement les objets javafx. Si cela devient une exigence de votre programme, vous devez utiliser le second thread pour d'autres tâches telles que les calculs, etc., etc. Vous devez utiliser une forme de transmission de message pour que l'autre thread sache que vous souhaitez effectuer n'importe quelle action javafx.

2
WillBD