2015-11-07 100 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

相关问题