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

时间:2017-04-06 14:49:43

标签: javafx server append client textarea

我从服务器接收字符串,我想在客户端附加到Textarea(想想聊天窗口)。问题是,当我收到字符串时,客户端会冻结。

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应该可以解决问题。它不适合我。

任何人都知道它可能是由什么引起的?谢谢!

1 个答案:

答案 0 :(得分:2)

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