SWT FXCanvas中的第二个Shell.open()导致“不在FX应用程序线程上”

时间:2016-04-12 19:16:19

标签: swt javafx-8

我第一次打开一个Shell并创建一个新的FXCanvas设置Scene它工作正常。代码第二次执行(在关闭Shell并打开一个新代码之后),它会抛出“Not on FX application thread”异常。

当我调试时,当第一个新的FXCanvas返回时,我在FX线程上,如javafx.application.Platform.isFxApplicationThread()所示。第二次代码运行时,新的FXCanvas返回,我不在FX线程上。

如果我将整个进程包装在Platform.runLater()中,它在第一次执行时运行正常,但第二次执行从不执行runLater()中的代码。

如果不清楚,请告诉我。

感谢。

Java代码:

package temp;

import java.net.URL;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

import javafx.embed.swt.FXCanvas;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;

public class SwtWrapper {

    public SwtWrapper() {
        super();
    }

    public void go() {
        Display display = Display.getDefault();
        try {
            Shell shell = new Shell(display);
            FXCanvas canvas = new FXCanvas(shell, SWT.NONE);

            URL url = Class.class.getResource("/temp/Fxml.fxml");
            FXMLLoader fxmlLoader = new FXMLLoader(url);
            Parent rootNode = fxmlLoader.load();

            canvas.setScene(new Scene(rootNode));
            canvas.pack();

            shell.pack();
            shell.open();
            while (!shell.isDisposed()) {
                if ( !display.readAndDispatch() )
                    display.sleep();
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            display.dispose();
        }
    }

    public static void main(String[] args) {
        new SwtWrapper().go();
        new SwtWrapper().go();
        System.exit(0);
    }

}

FXML:

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>

<VBox>
    <children>
        <Text text="The FX Content." />
        <ProgressIndicator />
    </children>
</VBox>

Maven依赖:

<dependency>
    <groupId>org.eclipse</groupId>
    <artifactId>swt</artifactId>
    <version>4.4-cocoa</version>
    <classifier>macosx-x86_64</classifier>
</dependency>
<dependency>
    <groupId>com.oracle</groupId>
    <artifactId>jfxswt</artifactId>
    <version>8.0.0-FINAL</version>
    <systemPath>${java.home}/lib/jfxswt.jar</systemPath>
    <scope>system</scope>
</dependency>

2 个答案:

答案 0 :(得分:1)

我想将您链接到这个问题,这个问题与此问题基本相同,我在这里发布了类似下面的答案。

Change JavaFX Application Start Form

基本上,要创建“FX应用程序线程”,您需要创建一个

  1. 扩展“应用程序”。即,public class SwtWrapper extends Application {

  2. 会覆盖start方法(这是您所有代码所在的位置,它基本上是“FX Application Thread”。即@Override public void start(Stage stage) throws Exception

  3. 在主要方法中设置了launch(args),通常是所有设置的,不确定人们是否在其中设置了其他内容。

  4. 所以你的代码

      public static void main(String[] args) {
        new SwtWrapper().go();
        new SwtWrapper().go();
        System.exit(0);
    }
    

    应该在start方法

    之内
      @Override
    public void start(Stage stage) throws Exception 
    {
    new SwtWrapper().go();
        new SwtWrapper().go();
        System.exit(0); // should probably be within the "stop" method
    }
    

    你的主要应该是

     public static void main(String[] args) {
        launch(args);
    }
    

    希望这有帮助。

答案 1 :(得分:0)

事实证明,删除display.dispose();以进一步参考,我的具体问题已得到解决,请参阅http://help.eclipse.org/juno/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fapi%2Forg%2Feclipse%2Fswt%2Fwidgets%2FDisplay.html