如何阻止“JavaFX应用程序线程”(how to stop “JavaFX Application

2019-08-19 11:08发布

我有一个简单的控制台应用程序,它有时需要进行图形操作,对于那些我使用JavaFX框架(也有一些功能,我需要像CSS样式文本)我只是产生一些形状和文本到一个隐藏的画面,然后保存那些文件,这一切,

我知道,使用JavaFX编写工作,我不得不图形操作传递到JavaFX的线程,但是当一切都做,我不得不关闭应用程序(几个小时后),这个线程了JavaFx仍然保持开放...我真的不要强制退出与System.exit()的,因为如果事情是阻止我可能想知道/等待(我也不想执行的一切作为JavaFX应用程序(如JavaFX组件是我的主要应用小于1%)

代码很简单,谷歌上搜索周围我发现只有在使用

Platform.exit();

这似乎并不工作,我也试着与平台参数,如打

Platform.setImplicitExit(false);

这里是我的测试应用程序,它可以运行:

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(String[] 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");
    }
}

这是线程从未关闭

“附加监听器” - 线程t @ 17 java.lang.Thread.State中:RUNNABLE

锁定的可拥有同步: - 无

“JavaFX应用程序线程” - 线程t @ 13 java.lang.Thread.State中:在com.sun.glass.ui.gtk.GtkApplication._runLoop(本机方法)RUNNABLE在com.sun.glass.ui.gtk.GtkApplication $ 3 $ 1.run(GtkApplication.java:82)在java.lang.Thread.run(Thread.java:722)

锁定的可拥有同步: - 无

更新:我在Linux上使用的Fedora 16 64位最新的Oracle JDK 7u17 64位。

Answer 1:

固定:

我是能够解决通过调用这个问题com.sun.javafx.application.PlatformImpl.tkExit()之前Platform.exit() 我真的不明白JavaFX的来源,很好,但它似乎是工作; 因人而异。

更新:在Java中8这样做会产生警告,你可以只是把警告了与@SuppressWarnings("restriction") 它不应该是一个问题。

说明:

我这出通过经由源代码挖; JFXPanel有这个小片段(这是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()
  {
  }

问题是,如果你使用你的应用程序的JavaFX的只有一点点,然后在idle(boolean)方法不会做任何事情(因为firstPanelShown == false ),防止后删除的监听,防止了JavaFX Toolkit从关闭......这意味着你必须手动关闭它。



Answer 2:

你的主要功能不属于JavaFX应用程序对象,我认为你的程序从来没有eneter应用程序线程循环。

看来你应该做的:

public class SOTestFX extends Application {
    public static void main(String[] 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
    }
}


Answer 3:

这是一个光滑的情况,因为(我的理解),JavaFX的线程的目的是为了充分利用各种硬件管线的透明。 可能我建议放置在一个单独的,引用的,项目中的JavaFX的要求; 并保留一切,包括你的主要方法,在另一个? 这一直为我工作。

基本上,业务逻辑和模式走在一个项目中,以及查看和控制(一般的JavaFX为主)在对方走。 这允许了JavaFX线程的独立终止。 希望这是适用于你正在尝试做的。



Answer 4:

我尝试了很多事情在这个因为没有适合我的工作上面的答案。 对我来说最好的事情就是刚刚关闭整个JVM使用

System.exit(1);

因为我的整个应用程序仅仅是一个JavaFX应用程序,并为此可以关闭阶段,当被关闭。 在我的情况下,1只是一个随机的int值。



文章来源: how to stop “JavaFX Application Thread”