comment arrêter “JavaFX Application Thread”

J’ai une application console simple qui nécessite parfois des opérations graphiques, pour ceux qui utilisent le framework JavaFx (il y a des fonctions dont j’ai besoin comme le style css pour le texte) je génère simplement des formes et du texte dans une scène cachée puis enregistre ceux dans le dossier et c’est tout,

Je sais que pour travailler avec JavaFx, je dois passer des opérations graphiques au thread JavaFx, mais quand tout est fait et que je dois fermer l’application (après quelques heures), ce thread JavaFx rest toujours ouvert … Je veux forcer exit avec System.exit () parce que si quelque chose est bloqué, je peux vouloir savoir / attendre

le code est très simple et googler autour que je n’ai trouvé qu’à utiliser

Platform.exit(); 

qui ne semble pas fonctionner, j’ai également essayé de jouer avec les parameters de la plate-forme comme

 Platform.setImplicitExit(false); 

voici mon application de test que vous pouvez exécuter:

 import javafx.application.Platform; import javafx.embed.swing.JFXPanel; import javafx.geometry.Pos; import javafx.scene.layout.VBox; public class SOTestFX { public static void main(Ssortingng[] args) { SOTestFX t = new SOTestFX(); t.runFxThread(); } public void runFxThread(){ //Application.launch(args); final JFXPanel jfxPanel = new JFXPanel(); Platform.runLater(new Runnable() { @Override public void run() { System.err.println("CREATING IMAGE"); simpleFXoperations(); System.err.println("NOW CALL EXIT"); System.err.println("JAVA FX THREAD SHOULD BE EXITED NOW"); Platform.exit(); } }); try { Thread.sleep(3000); // just wait a bit if something should happen, let it happen.. } catch (InterruptedException e) { e.printStackTrace(); } //jfxPanel.removeNotify(); // return -> java.lang.NullPointerException //Platform.exit(); // -> does nothing System.err.println("i will never die!"); } public void simpleFXoperations(){ VBox vbox1 = new VBox(); vbox1.setAlignment(Pos.BOTTOM_CENTER); vbox1.setStyle("-fx-border-style: solid;" + "-fx-border-width: 1;" + "-fx-border-color: white"); System.err.println("simpleFXoperations() _DONE"); } } 

et c’est le fil qui ne ferme jamais

“Attach Listener” – Fil t @ 17 java.lang.Thread.State: RUNNABLE

Synchroniseurs propriétaires bloqués: – Aucun

“Thread de l’application JavaFX” – Sujet t @ 13 java.lang.Thread.State: RUNNABLE sur com.sun.glass.ui.gtk.GtkApplication._runLoop (Méthode native) sur com.sun.glass.ui.gtk.GtkApplication $ 3 $ 1.run (GtkApplication.java:82) à java.lang.Thread.run (Thread.java:722)

Synchroniseurs propriétaires verrouillés: – Aucun

Mise à jour: J’utilise le dernier Oracle JDK 7u17 64 bits sur Linux Fedora 16 64 bits.

Réparer:

J’ai pu résoudre ce problème en appelant com.sun.javafx.application.PlatformImpl.tkExit() immédiatement avant Platform.exit() . Je ne comprends pas vraiment bien la source JavaFX, mais elle semble fonctionner. YMMV.

Mise à jour: Faire cela dans Java 8 produira un avertissement, vous pouvez simplement désactiver l’avertissement avec @SuppressWarnings("ressortingction") . Cela ne devrait pas poser de problème.

Explication:

J’ai compris cela en creusant le code source; JFXPanel a ce petit extrait (de JavaFX 2.2.25)

 finishListener = new PlatformImpl.FinishListener() { public void idle(boolean paramAnonymousBoolean) { if (!JFXPanel.firstPanelShown) { return; } PlatformImpl.removeListener(JFXPanel.finishListener); JFXPanel.access$102(null); if (paramAnonymousBoolean) Platform.exit(); } public void exitCalled() { } 

Le problème est que, si vous utilisez seulement un peu de JavaFX dans votre application, la méthode idle(boolean) ne fait jamais rien (car firstPanelShown == false ), ce qui empêche l’écouteur d’être supprimé, ce qui empêche le JavaFX Toolkit de fermer … ce qui signifie que vous devez l’arrêter manuellement.

Votre fonction principale n’appartient pas à l’object Application JavaFx et je pense que votre programme ne modifie jamais la boucle du thread d’application.

Il semble que vous deviez faire:

 public class SOTestFX extends Application { public static void main(Ssortingng[] args) { launch(args); } @Override public void start(Stage stage) throws Exception { // Do stuff here to show your stage or whatever you want; // This will be called on the JavaFX thread } } 

C’est une situation glissante, car (à ma connaissance) le but du thread JavaFX est de tirer parti de divers pipelines de matériel de manière transparente. Puis-je suggérer de placer vos requêtes JavaFX dans un projet séparé, référencé; et gardez tout le rest, y compris votre méthode principale, dans un autre? Cela a toujours fonctionné pour moi.

Fondamentalement, la logique métier et le modèle vont dans un projet, et la vue et le contrôle (généralement basés sur JavaFX) dans l’autre. Cela permet une terminaison indépendante du thread JavaFX. J’espère que cela s’applique à ce que vous essayez de faire.

J’ai essayé beaucoup de choses à ce sujet car aucune des réponses ci-dessus ne fonctionnait pour moi. La meilleure chose pour moi était de simplement arrêter la JVM entière en utilisant

 System.exit(1); 

comme toute mon application est juste une application JavaFX et donc peut être fermée, lors de la fermeture de la scène. Le 1 dans mon cas est juste un int aléatoire.