2016-04-12 79 views
0

第一次打開一個Shell並創建一個新的FXCanvas設置時,它的工作正常。代碼執行第二次(在關閉Shell並打開一個新代碼後),它會拋出「Not on FX application thread」異常。SWT FXCanvas中的第二個Shell.open()導致「不在FX應用程序線程上」

當我調試時,當第一個新的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> 

回答

0

我想你鏈接到這個問題,這本質上是一樣的這個問題,我發佈了一個類似於下面的答案。

Change JavaFX Application Start Form

從本質上講,創建一個 「FX應用程序線程」 您創建一個類,

  1. 擴展 「應用程序」。即,public class SwtWrapper extends Application {

  2. 覆蓋啓動方法(這是所有代碼的推移,它本質上是「FX應用程序線程。」即@Override public void start(Stage stage) throws Exception

  3. 具有的主要方法中launch(args)集,通常這是所有在某個設定,不知道的人設置任何東西在裏面。

所以,你的代碼

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

應該是啓動方法

@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); 
} 

希望這有助於。

+0

這是偉大的信息,並填寫了我一些差距固定的,但它並沒有在我的問題的根源得到。我真正的目標是從基礎SWT應用程序啓動SWT窗口,並且SWT窗口中有一個FXCanvas。該窗口可以關閉,父應用程序將再次打開SWT窗口。在這種情況下,沒有涉及到javafx.application.Application,並且FX工具箱被初始化爲FXCanvas的實例。 我會考慮將整個窗口變成一個FX應用程序,但我不確定這是否適用於我。 –

+0

嘿,我想我錯過了那個細節。 我想你已經看過這個http://docs.oracle.com/javafx/2/swt_interoperability/jfxpub-swt_interoperability.htm 看來他們在SWT中使用FX對象,所以我會閱讀這(如果你還沒有)。這也可能是一個錯誤,所以你也可以嘗試在javafx Jira上報告它,但我會一直等到所有其他選項嘗試着:) – XaolingBao

相關問題