Comment éviter de ne pas sur le thread d'application FX; currentThread = erreur de Thread D'Application JavaFX?
Les extraits de code ci-dessous me donnent une erreur Not on FX application thread; currentThread
=JavaFX
Application Thread
.Cette application fonctionnait bien en java 1.7 mais quand je l'ai déplacé vers fx8, elle donne maintenant une erreur. lorsque je démarre l'application lors de ma 1ère tentative, elle fonctionne comme prévu .Mais après avoir fermé la scène et l'ouvrir à nouveau, cela ne fonctionne pas.
L'erreur est également ambigu Not On fx application thread and current thread- javafx
application thread
.Qu'est-ce que cela signifiait en ne pas sur le thread d'application fx si le thread actuel est un thread d'application fx.
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);
}
6 réponses
Cela s'est passé avec moi quand je modifiais L'élément D'interface utilisateur de la tâche dans javafx 2 comme les éléments listview. une tâche qui modifie le graphique de Scène m'a aidé à résoudre le problème, c'est-à-dire à mettre à jour les éléments de l'interface utilisateur par
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;
}
};
Appeler
Platform.runLater(new Runnable(){
// ...
});
Va le réparer aussi.
Platform.setImplicitExit(false);
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 aucun problème dans JavaFX 2 donne l'erreur pas un thread d'application fx là.
Cela devrait arriver lorsque vous essayez de changer une interface utilisateur de composant, comme un texte d'étiquette. Courir comme ça fonctionne toujours:
@FXML Label myLabel;
Platform.runLater(new Runnable(){
myLabel.setText("some text");
});
Vous pouvez changer de forme ou aller à une autre vue ou fxml 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();
}
}
}
Il n'est pas montré explicitement dans le code ci-dessus, mais ce que je suis assez sûr est que quelque part vous créez un thread en dehors du thread javafx de l'application (principale), puis vous essayez de préformer les opérations sur les objets javafx (comme la fermeture, l'ouverture de 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 que vous devez utiliser le deuxième thread pour d'autres des choses comme les calculs, etc, etc. Vous devez utiliser une forme de passage de message pour faire savoir à l'autre thread que vous voulez faire n'importe quelle action javafx.