2016-06-11 8 views
0

私たちはGUIとCLIの両方で動作するクライアント/サーバアプリケーションを開発しています。 CLIに問題はありませんが、私たちはJavaFXで実装しようとしています:JavaFxとソケットリスナー

私たちのサーバはクライアントに(ソケット経由で)いくつかのオブジェクトを送ります。

これは私達のSocketServerListener(ライタ)である:

public class SockeServerListener extends Thread implements ServerListener{ 
    private CliController controller; 
    private ObjectInputStream in; 
    private ObjectOutputStream out; 

    public SocketServerListener(Socket server, CliController controller) throws UnknownHostException, IOException { 
     this.controller = controller; 
     this.out = new ObjectOutputStream(server.getOutputStream()); 
     this.in = new ObjectInputStream(server.getInputStream()); 
    } 

    public void publishMessage(String message) throws IOException, RemoteException { 
     out.writeObject(message); 
     out.flush(); 
    } 

    public void run() { 
     try { 
      while (true) { 
       Dialogue dialogue = (Dialogue) in.readObject(); 
       controller.parseDialogue(dialogue); 
      } 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (ClassNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 


} 

はSocketServerListenerはインタフェース(CLI/GUI)を更新し、受信したオブジェクトを「実行」誰実行一つであるコントローラによってインスタンス化されます

public void parseDialogue(Dialogue dialog) { 
     dialog.execute(view); //view is an interface extended by both the Cli and GUI 
     this.canWrite = true; 
    } 

私は、これはCLIと非常によく動作しますが、それはJavaFXの

Exception in thread "Thread-7" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-7 
で例外がスローされます、言ったように

すべてのGUIを生成するために使用されたクラスをコントローラとして使用しようとしましたが、(肯定的な)結果は一切ありませんでした。 スレッドをインスタンス化してJavaFXと連携し、必要な画面を表示するメソッドを呼び出すにはどうすればよいですか?

はおそらくcontroller.parseDialogue(dialogue);への呼び出しは、UIを更新している

答えて

1

ありがとうございます。これは、FXアプリケーションスレッドでのみ実行できます。あなたはPlatform.runLater()を使ってFXのアプリケーションスレッド上で実行するために実行可能なスケジュールを設定することができます:あなたがFXツールキットが開始されたコンテキストでこのコードを実行しているかわからない場合は、その

Platform.runLater(() -> controller.parseDialogue(dialogue)); 

注意、への呼び出しをPlatform.runLater(...)は、代わりにコントローラーで行う必要があります。

public class NonGuiController implements CliController { 

    @Override 
    public void parseDialog(Dialogue dialogue) { 
     // regular code here... 
    } 
} 

public class GuiController implements CliController { 

    @Override 
    public void parseDialogue(Dialogue dialogue) { 
     // some preliminary work (still on background thread here) if necessary... 
     Platform.runLater(() -> { 
      // code that updates UI here... 
     }); 
    } 
} 

とあなたのソケットリスナクラスの元のコードに戻します。

2
FXアプリケーションのスレッドで

ない

あなたの問題の原因を提供します。 NodeクラスのJavadocをよれ

ノードオブジェクトは、それらがまだ表示されているウィンドウのシーンに取り付けられていない 限り、任意のスレッドで構成され、修正されてもよいです。 アプリケーションは、そのようなシーンにノードを接続するか、 JavaFXアプリケーションスレッドでノードを変更する必要があります。

使用Platform.runLaterは、FXのアプリケーションスレッドでコードを実行し、さらに、ユーティリティクラスのjavafx.concurrentパッケージを見て持っています。