如何停止“JavaFX应用程序线程” [英] how to stop "JavaFX Application Thread"

查看:346
本文介绍了如何停止“JavaFX应用程序线程”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的控制台应用程序,有时需要执行图形操作,对于那些我正在使用JavaFx框架(我需要一些函数,如文本的css样式)
我只是生成一些形状和将文本保存到一个隐藏的场景然后保存在文件中,这就是全部,

I have a simple console application which sometimes need to perform graphics operations, for those I'm using JavaFx framework (there are some functions that I need like the css styling for text ) I simply generate some shapes and text into an hidden scene then save those on file and that's all,

我知道要使用JavaFx我必须将图形操作传递给JavaFx线程,但是当一切已完成,我必须关闭应用程序(几个小时后)这个JavaFx线程仍然保持打开...我真的不想强制退出System.exit()因为如果有什么东西被阻止我可能想知道/等待(我不想将所有内容都作为JavaFx应用程序执行(因为JavaFx组件不到我主应用程序的1%)

I know that to work with JavaFx I have to pass graphics operations to the JavaFx thread, but when everything is done and I have to close the application (after some hours) this JavaFx thread still remain open... and I really don't want to force exit with System.exit() because if something is blocked I may want to know/wait (ALSO I don't want to execute everything as an JavaFx application (as JavaFx components are less than 1% of my main application)

代码非常简单谷歌搜索我发现只使用

the code is very simple and googling around I've found only to use

Platform.exit();

这似乎不起作用,我也是特里d使用平台参数,如

which doesn't seems to work, I've also tried playing with Platform parameters like

Platform.setImplicitExit(false);

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

here is my test application which you can run :

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

"Attach Listener" - Thread t@17 java.lang.Thread.State: RUNNABLE

锁定的可拥有同步器:
- 无

Locked ownable synchronizers: - None

JavaFX应用程序线程 - 线程t @ 13 java.lang.Thread.State:
RUNNABLE at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native
Method)at
com.sun.glass.ui.gtk.GtkApplication $ 3 $ 1.run(GtkApplication.java:82)
at java.lang.Thread.run(Thread.java:722)

"JavaFX Application Thread" - Thread t@13 java.lang.Thread.State: RUNNABLE at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method) at com.sun.glass.ui.gtk.GtkApplication$3$1.run(GtkApplication.java:82) at java.lang.Thread.run(Thread.java:722)

锁定的可拥有同步器:
- 无

Locked ownable synchronizers: - None

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

Update: I'm using latest Oracle JDK 7u17 64bit on Linux Fedora 16 64bit.

推荐答案

修复:



我可以通过调用 com.sun解决此问题紧接在之前的.javafx.application.PlatformImpl.tkExit() Platform.exit()。我不太了解JavaFX源,但它似乎正在工作; YMMV。

Fix:

I was able to fix this problem by calling com.sun.javafx.application.PlatformImpl.tkExit() immediately before Platform.exit(). I don't really understand the JavaFX source that well, but it seems to be working; YMMV.

更新:在Java 8中执行此操作会产生警告,您只需使用关闭警告即可@SuppressWarnings( 限制)。这应该不是问题。

Update: Doing this in Java 8 will produce a warning, you can just turn the warning off with @SuppressWarnings("restriction"). It shouldn't be a problem.

我通过挖掘源代码来解决这个问题; JFXPanel 有这个小片段(这是来自JavaFX 2.2.25)

I figured this out by digging through the source code; JFXPanel has this little snippet (this is from 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 关闭..这意味着你必须手动关闭它。

The problem is, if you are using only a little bit of JavaFX in your application, then the idle(boolean) method never does anything (because firstPanelShown == false), which prevents the listener from getting removed, which prevents the JavaFX Toolkit from shutting down... which means you have to shut it down manually.

这篇关于如何停止“JavaFX应用程序线程”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆