Hoe te vermijden dat u niet in de FX-toepassingsthread bent; currentThread = JavaFX Application Thread-fout?

Onder de codefragmenten krijg ik een foutmelding Not on FX application thread; currentThread=JavaFXApplication Thread. Deze applicatie werkte prima in Java 1.7, maar toen ik het naar fx8 verplaatste, geeft het nu een foutmelding. wanneer ik de applicatie bij mijn eerste poging start, werkt het zoals bedoeld. Maar na het sluiten van het podium en het opnieuw openen werkt het niet.

De fout is ook dubbelzinnig Not On fx application thread and current thread- javafxapplication thread. Wat bedoelde het met niet op fx-toepassingsthread als de huidige thread is een fx-toepassingsthread.

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

Antwoord 1, autoriteit 100%

Bellen

Platform.runLater(new Runnable(){
// do your GUI stuff here
});

zal het oplossen.


Antwoord 2, autoriteit 54%

Dit gebeurde met mij toen ik het UI-element van taak in javafx 2 aan het wijzigen was, zoals lijstweergave-elementen.Een taak die de scènegrafiek wijzigtheeft me geholpen om het probleem op te lossen, namelijk het bijwerken van UI-elementen door

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

Antwoord 3, autoriteit 28%

Het zou moeten gebeuren wanneer u een component-UI probeert te wijzigen, zoals een labeltekst. Zo rennen werkt altijd:

@FXML Label myLabel;
Platform.runLater(new Runnable(){
   myLabel.setText("some text");
});

Antwoord 4, autoriteit 24%

Platform.setImplicitExit(false);heeft mijn probleem opgelost. Ik denk dat ze de implementatie in JavaFX 8 hebben gewijzigd, dus dezelfde code die probleemloos werkt in JavaFX 2 geeft daar de fout geen fx-toepassingsthread.


Antwoord 5, autoriteit 7%

Je kunt het formulier wijzigen of naar een andere weergave of fxml gaan met dit in elk deel van je 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);
                            }
                        });

Mijn voorbeeld in mijn 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();
        }
    }
}

Antwoord 6, autoriteit 6%

Het wordt niet expliciet getoond in de bovenstaande code, maar ik ben er vrij zeker van dat je ergens een thread aan het maken bent buiten de applicatie (hoofd) javafx-thread, en dan probeer je bewerkingen uit te voeren op javafx-objecten (zoals sluiten, openen van vensters, enz.) op de TWEEDE draad. Dit is strikt niet toegestaan, omdat alleen de hoofdthread javafx-objecten rechtstreeks kan besturen. Als dit een vereiste van uw programma wordt, moet u de tweede thread gebruiken voor andere dingen, zoals berekeningen, enz., enz. U moet een vorm van doorgeven van berichten gebruiken om de andere thread te laten weten dat u welke javafx-actie dan ook wilt doen.


Antwoord 7

Ik ondervond hetzelfde probleem toen ik een opstartscherm voor mijn programma probeerde toe te voegen. Zo was mijn code

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

Dit uitvoeren gaf een ‘not on fx applicatie’. Door Platform.runLater() toe te voegen aan mijn taak, loste dat het probleem op.
Dit is hoe ik momenteel mijn code heb:

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

Ik hoop dat dit je zal helpen het probleem op te lossen. Proost.

Other episodes