2015-11-07 96 views
1

我需要等待服務器程序使用套接字將數據發送到客戶端程序,因此我必須等待它使用while循環。然而,客戶端程序是一個JavaFX應用程序,如果在while循環中使用,它會凍結並崩潰,所以我把while循環放在一個新的Thread中。然而,這個while循環的主體需要更新JavaFX UI,因爲它導致「不在FX應用程序線程上」,所以無法完成。異常,所以我不能爲它創建一個新的線程。JavaFX和套接字=不在FX應用程序線程上

這是我的代碼:

import static util.Constants.PORT; 
import static util.Constants.SERVER_NAME; 

public class Client extends Application { 

    private static View view; 
    public static Scanner in; 
    public static PrintWriter out; 
    private static boolean appRunning = true; 

    public static void main(String[] args) { 
     try { 
      Socket socket = new Socket(SERVER_NAME, PORT); 
      in = new Scanner(socket.getInputStream()); 
      out = new PrintWriter(socket.getOutputStream(), true); 

      launch(args); 
     } catch (IOException e) { 
      System.out.println("Could not establish connection to server. Program terminating.."); 
      System.exit(1); 
     } 
    } 

    @Override 
    public void start(Stage window) throws Exception { 
     // This is a JavaFX BorderPane that adds itself to window: 
     view = new View(window); 

     // ServerListener 
     new Thread(() -> { 
      try { 
       while (appRunning) { 
        // will through exception. needs to run on Application thread: 
        parseServerMessage(Client.in.nextLine()); 
       } 
      } catch (Exception e) { 
       System.out.println(e.getMessage()); 
      } 
     }).start(); 
    } 

    private static String[] parseServerMessage(String message0 { 
     // update the JavaFX UI 
    } 
} 

,如果我用下面的啓動方法的代碼沒有線程,JavaFX的應用程序將凍結:

@Override 
public void start(Stage window) throws Exception { 
    // This is a JavaFX BorderPane that adds itself to window: 
    view = new View(window); 

    // causes JavaFX to freeze: 
    while (appRunning) {    
     parseServerMessage(Client.in.nextLine()); 
    } 
} 

而且把線程睡眠沒有幫助。 我該如何解決這個問題?謝謝!

編輯解決方案:

由於該解決方案,我修改了代碼,現在,它完美的作品。這裏是編輯的解決方案:

new Thread(() -> { 
    while (true) { 
     String serverMessage = Client.in.nextLine(); 
     Platform.runLater(() -> { 
      parseServerMessage(serverMessage);     
     }); 
    } 
}).start(); 
+0

不確定,因爲我還在學習如何使用線程。我會試着看看,謝謝。 – Mayron

+0

查看[Task](https://docs.oracle.com/javase/8/javafx/api/javafx/concurrent/Task.html),它提供了與線程相同的功能,但以更加優雅的方式。它具有可用於直接更新JavaFX UI的方法。 – ItachiUchiha

回答

1

你可以看看Platform::runLater。來自JavaDoc:

在未來某個未指定的時間在JavaFX應用程序線程上運行指定的Runnable。這個可以從任何線程調用的方法會將Runnable發佈到事件隊列中,然後立即返回給調用者。

+0

謝謝,所以如果我在客戶端JavaFX應用程序類中創建了「updateUI」方法,我該如何讓runLater運行該方法?我用這個例子看到的例子創建了一個全新的Runnable,它不適合我的情況。 – Mayron

+0

沒關係我做到了! :D謝謝你完美的工作! – Mayron

相關問題