2017-04-06 16 views
2

クライアント側のTextareaに追加する文字列をサーバーから受信しています(Think chat window)。問題は、文字列を受け取ったときにクライアントがフリーズすることです。TextArea(JavaFX 8)にテキストを追加する際の問題

insertUserNameButton.setOnAction((event) -> { 
     userName=userNameField.getText(); 
     try { 
      connect(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    }); 

public Client() { 
    userInput.setOnAction((event) -> { 

     out.println(userInput.getText()); 
     userInput.setText(""); 

    }); 
} 

private void connect() throws IOException { 

    String serverAddress = hostName; 
    Socket socket = new Socket(serverAddress, portNumber); 
    in = new BufferedReader(new InputStreamReader(
      socket.getInputStream())); 
    out = new PrintWriter(socket.getOutputStream(), true); 

    while (true) { 
      String line = in.readLine(); 

     if (line.startsWith("SUBMITNAME")) { 
      out.println(userName); 

     } else if (line.startsWith("MESSAGE")) { 
      Platform.runLater(()->serverOutput.appendText(line.substring(8) + "\n")); 

     } else if (line.startsWith("QUESTION")) { 
      Platform.runLater(()->serverOutput.appendText(line.substring(8) + "\n")); 

     } else if (line.startsWith("CORRECTANSWER")) { 
      Platform.runLater(()->serverOutput.appendText(line.substring(14) + "\n")); 
     } 
    } 
} 

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

私はいくつかの調査を行いましたが、それぞれの追加でPlatform.runLaterを使用すると問題が解決するようです。それは私のためではありません。

誰でも原因が考えられますか?ありがとうございました!

+0

は、 '()'を接続するのですその後、

private final Executor exec = Executors.newCachedThreadPool(runnable -> { Thread t = new Thread(runnable); t.setDaemon(true); return t ; }); 

と:それはスレッドを管理するためにExecutorを使用するのが最善ですか?どのスレッドで? –

+0

私はコードを編集しました。アクションイベントから呼び出されます。接続を開始する接続ボタン。スレッドなし。 – binerkin

+0

イベントハンドラから呼び出す場合は、FXアプリケーションスレッドで実行しています。ですから、あなたの無限の 'while(true){...}'ループはFXアプリケーションスレッド上で実行されており、それをブロックし、UIが更新を実行することを妨げます。これをバックグラウンドスレッドで実行する必要があります。 –

答えて

2

FXアプリケーションスレッドでconnect()を呼び出しています。 (ユーザーイベントなどへの対応、UIをレンダリング)

while(true) { 
    String line = in.readLine(); 
    // ... 
} 

構造を経由して無期限をブロックするので、あなたはFXのアプリケーションスレッドをブロックし、その通常の作業のいずれかをやってからそれを防ぎます。

これはバックグラウンドスレッドで実行する必要があります。あなたが呼び出している

insertUserNameButton.setOnAction((event) -> { 
    userName=userNameField.getText(); 
    exec.execute(() -> { 
     try { 
      connect(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    }); 
}); 
+0

それはそれをしました!ありがとうございました! – binerkin

関連する問題