2016-02-12 85 views
1

我一直在試圖弄明白了一段時間,JavaFX的GUI卡住時DataInputStream類是在while循環

我試圖寫一個聊天 - 服務器應用程序,只是爲了學習。 我有一個障礙,我無法理解,

的GUI類凍結內部的while循環,但只是當它試圖讀取:

public void run(){ 
    Platform.runLater(() -> { 
     do { 
      try { 
       msg = getFromServer.readUTF(); // <--- freeze GUI 
       chatWindow.appendText(msg); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } while (true); 
    }); 
} 

你可以看到它在一個線程中運行,但我曾嘗試以其他方式運行...

只有DataInputStream類使其卡住,

msg = getFromServer.readUTF(); 

這它methud,它的來自何處:

public void connectToServer(){ 
    try { 
     serverConectionState = new Socket("127.0.0.1", 6789); 
     getFromServer = new DataInputStream(serverConectionState.getInputStream()); 
     sendToServer = new DataOutputStream(serverConectionState.getOutputStream()); 
     onlineOffline.setText("Online"); 
     onlineOffline.setTextFill(javafx.scene.paint.Color.web("#0076a3")); 
    } catch (IOException ex){ 
     chatWindow.appendText("server connection fail\n"); 
    } 
} 

這個類是Controller.class - 如果它使任何不同。

我在stackoverflow的第一個問題,在社區的很多幫助之後。

在此先感謝

+1

正如下面的答案中所建議的那樣,只有當您想要更新UI並且不在這些線程中進行業務邏輯或數據操作時,您才必須使用'Platform.runLater()'。因此,在你的例子中,你應該調用一個'Runnable',當runnable完成工作時,它應該用'Platform.runLater()'更新UI。還要注意,對於大型應用程序,更好地使用ExecutorService,而不是根據需要產生線程 – AntJavaDev

回答

3

我假設run方法你表明是在後臺線程中執行的Runnable的一部分。

您正在運行FX應用程序線程上的整個循環(使用Platform.runLater())。所以你阻止該線程並防止重新繪製。你應該只運行在FX應用程序線程的UI更新:

public void run(){ 
    do { 
     try { 
      String msg = getFromServer.readUTF(); // <--- freeze GUI 
      Platform.runLater(() -> chatWindow.appendText(msg)); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } while (true); 
} 
+0

感謝James,我知道它用於更新textField,但我的問題是:String msg = getFromServer.readUTF();即使我不會追加文本,我仍然會凍結GUI。而且是的,bdw在Controller中實現了Runnable,那可以嗎?這可能會凍結GUI? – ROSA

+0

你在後臺線程中運行這個嗎?也許你可以編輯你的代碼來顯示實際調用的地方。你是說如果你刪除了'chatWindow.appendText(...)'*並*完全移除了'Platform.runLater(...)',它仍然會阻止GUI? –

+0

乾杯,再次感謝,我更新了代碼,如果你可以看一下 - https://github.com/adamdelarosa/Chat_client/blob/master/src/sample/Controller.java – ROSA

3

而不是使用platform.runlater你應該使用Java的task,這樣就可以運行不同的線程代碼,不凍結UI線程

+0

感謝Sijo!我的問題是我添加了iThread.run()而不是iThread.start()但是很確定它也可以用你的解決方案解決。 – ROSA