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

标签 java multithreading sockets javafx

我需要等待服务器程序使用套接字将数据发送到客户端程序,因此我必须使用 while 循环等待它。然而,客户端程序是一个 JavaFX 应用程序,如果在 while 循环中使用,它将卡住并崩溃,因此我将 while 循环放在一个新线程中。然而,这个 while 循环的主体需要更新 JavaFX UI,这是无法完成的,因为它会导致“Not on FX application thread;”异常,所以我无法为其创建新线程。

这是我的代码:

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()); 
    }
}

将线程置于 sleep 状态也没有帮助。 我该如何解决这个问题?谢谢!

编辑解决方案:

感谢这个解决方案,我编辑了代码,现在它可以完美运行。这是编辑后的解决方案:

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

最佳答案

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

Run the specified Runnable on the JavaFX Application Thread at some unspecified time in the future. This method, which may be called from any thread, will post the Runnable to an event queue and then return immediately to the caller.

关于JavaFX 和套接字 = 不在 FX 应用程序线程上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33581330/

相关文章:

c# - 专用网络上的套接字

sockets - 用于响应 native 的socket.io(发送查询问题)

sockets - UDP 数据包可以像 TCP 一样部分发送吗?

java - Intellij 无法解析具有多个 SourceSet 的 Gradle 项目中的符号

java - 每当我重新单击或导航到下一个 fragment 时,我的 fragment 都会不断重新创建

java - 有哪些不同的框架可用于 SOAP

java - 使用 newSingleThreadScheduledExecutor 调度多个任务

java - 使用西里尔字符解码 JSON

asp.net - .Net MVC线程长时间运行的过程

java - 如何在 Tomcat 正常关闭时获取线程中断/通知?