JavaFX和套接字=不在FX应用程序线程

时间:2015-11-07 09:47:05

标签: java multithreading sockets javafx

我需要等待服务器程序使用套接字将数据发送到客户端程序,所以我必须使用while循环等待它。但是Client程序是一个JavaFX应用程序,如果在while循环中使用它会冻结并崩溃,所以我把while循环放在一个新的Thread中。但是,这个while循环的主体需要更新无法完成的JavaFX UI,因为它导致“不在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
    }
}

如果我在没有线程的start方法中使用下面的代码,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();

1 个答案:

答案 0 :(得分:1)

您可以查看Platform::runLater。来自JavaDoc:

  

将来某个未指定的时间在JavaFX应用程序线程上运行指定的Runnable。此方法可以从任何线程调用,将Runnable发布到事件队列,然后立即返回给调用者。