将文本附加到 TextArea 的问题 (JavaFX 8)

Issues appending text to a TextArea (JavaFX 8)

我正在从我的服务器接收字符串,我想将其附加到客户端的文本区域中(想想聊天 window)。问题是,当我收到字符串时,客户端冻结了。

insertUserNameButton.setOnAction((event) -> {
        userName=userNameField.getText();
        try {
            connect();
        } catch (IOException e) {
            e.printStackTrace();
        }
    });

public Client() {
    userInput.setOnAction((event) -> {

        out.println(userInput.getText());
        userInput.setText("");

    });
}

private void connect() throws IOException {

    String serverAddress = hostName;
    Socket socket = new Socket(serverAddress, portNumber);
    in = new BufferedReader(new InputStreamReader(
            socket.getInputStream()));
    out = new PrintWriter(socket.getOutputStream(), true);

    while (true) {
            String line = in.readLine();

        if (line.startsWith("SUBMITNAME")) {
            out.println(userName);

        } else if (line.startsWith("MESSAGE")) {
            Platform.runLater(()->serverOutput.appendText(line.substring(8) + "\n"));

        } else if (line.startsWith("QUESTION")) {
            Platform.runLater(()->serverOutput.appendText(line.substring(8) + "\n"));

        } else if (line.startsWith("CORRECTANSWER")) {
            Platform.runLater(()->serverOutput.appendText(line.substring(14) + "\n"));
        }
    }
}

public static void main(String[] args) {
    launch(args);
}

我做了一些研究,似乎在每个附加上使用 Platform.runLater 应该可以解决问题。不适合我。

有人知道它可能是由什么引起的吗?谢谢!

您正在 FX 应用程序线程上调用 connect()。因为它通过

无限期阻塞
while(true) {
    String line = in.readLine();
    // ...
}

构造,您阻止 FX 应用程序线程并阻止它执行任何常规工作(呈现 UI、响应用户事件等)。

您需要 运行 在后台线程上执行此操作。最好使用 Executor 来管理线程:

private final Executor exec = Executors.newCachedThreadPool(runnable -> {
    Thread t = new Thread(runnable);
    t.setDaemon(true);
    return t ;
});

然后

insertUserNameButton.setOnAction((event) -> {
    userName=userNameField.getText();
    exec.execute(() -> {
        try {
            connect();
        } catch (IOException e) {
            e.printStackTrace();
        }
    });
});