Les extraits de code ci-dessous me donnent l'erreur Not on FX application thread; currentThread
= JavaFX
Application 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- javafx
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);
}
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.
Appel
Platform.runLater(new Runnable(){
// ...
});
va le réparer aussi.
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;
}
};
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");
});
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();
}
}
}
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.