【问题标题】:Second Shell.open() in SWT FXCanvas causes "Not on FX application thread"SWT FXCanvas 中的第二个 Shell.open() 导致“不在 FX 应用程序线程上”
【发布时间】:2016-08-03 14:08:27
【问题描述】:

我第一次打开 Shell 并创建一个新的 FXCanvas 设置场景时它工作正常。代码第二次执行(在关闭 Shell 并打开新的 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>

【问题讨论】:

    标签: swt javafx-8


    【解决方案1】:

    我想把你链接到这个问题,这个问题与这个问题基本相同,我在其中发布了一个类似于下面的答案。

    Change JavaFX Application Start Form

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

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

    2. 覆盖 start 方法(这是所有代码所在的位置,它本质上是“FX 应用程序线程”。即@Override public void start(Stage stage) throws Exception

    3. 在 main 方法中设置了launch(args),通常就是这样设置,不确定人们是否在其中设置了其他任何东西。

    所以你的代码

      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
    }
    

    你的 main 应该是这样的

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

    希望这会有所帮助。

    【讨论】:

    • 这是很好的信息,填补了我的一些空白,但它并没有成为我问题的根源。我的真正目标是从基本 SWT 应用程序启动一个 SWT 窗口,并且该 SWT 窗口中有一个 FXCanvas。该窗口可以关闭,父应用程序将再次打开 SWT 窗口。在这种情况下,不涉及 javafx.application.Application 并且 FX 工具包使用 FXCanvas 的实例化进行初始化。我会考虑将整个窗口制作成一个 FX 应用程序,但我不确定这是否适合我。
    • 明白了,我想我错过了那个细节。我假设你已经看过这个docs.oracle.com/javafx/2/swt_interoperability/… 似乎他们在 SWT 中使用了 FX 对象,所以我会阅读这个(如果你还没有的话)。这也可能是一个错误,因此您也可以尝试在 javafx Jira 上报告它,但我会等到尝试所有其他选项 :)
    【解决方案2】:

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

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-24
    • 2015-06-09
    • 1970-01-01
    相关资源
    最近更新 更多