我从服务器接收字符串,我想在客户端附加到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应该可以解决问题。它不适合我。
任何人都知道它可能是由什么引起的?谢谢!
答案 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();
}
});
});