我一直想弄明白一段时间,
我正在尝试编写一个聊天服务器应用程序,仅用于学习。 我有一个我无法理解的障碍,
GUI类中的while循环冻结,但只是在它尝试读取时:
public void run(){
Platform.runLater(() -> {
do {
try {
msg = getFromServer.readUTF(); // <--- freeze GUI
chatWindow.appendText(msg);
} catch (IOException e) {
e.printStackTrace();
}
} while (true);
});
}
你可以看到它在一个线程中运行,但我确实尝试以其他方式运行它......
只有DataInputStream使其卡住,
msg = getFromServer.readUTF();
这就是它来自的方法:
public void connectToServer(){
try {
serverConectionState = new Socket("127.0.0.1", 6789);
getFromServer = new DataInputStream(serverConectionState.getInputStream());
sendToServer = new DataOutputStream(serverConectionState.getOutputStream());
onlineOffline.setText("Online");
onlineOffline.setTextFill(javafx.scene.paint.Color.web("#0076a3"));
} catch (IOException ex){
chatWindow.appendText("server connection fail\n");
}
}
这个类是Controller.class - 如果它有任何不同之处。
在社区的大量帮助之后,我在stackoverflow中的第一个问题。
提前致谢
答案 0 :(得分:4)
我假设您展示的run
方法是在后台线程中执行的Runnable
的一部分。
您正在FX应用程序线程上运行整个循环(使用Platform.runLater()
)。因此,您阻止该线程并阻止它重新绘制。您应该只在FX应用程序线程上运行UI更新:
public void run(){
do {
try {
String msg = getFromServer.readUTF(); // <--- freeze GUI
Platform.runLater(() -> chatWindow.appendText(msg));
} catch (IOException e) {
e.printStackTrace();
}
} while (true);
}
答案 1 :(得分:4)
而不是使用platform.runlater,你应该使用java task,这样你就可以在不同的线程中运行代码,而不会冻结UI线程