【问题标题】:JavaFX GUI stuck when DataInputStream is in while loop当 DataInputStream 在 while 循环中时 JavaFX GUI 卡住
【发布时间】:2016-02-12 12:54:36
【问题描述】:

我已经尝试了一段时间了,

我正在尝试编写一个聊天服务器应用程序,只是为了学习。 我有一个我无法理解的障碍,

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 中的第一个问题。

提前致谢

【问题讨论】:

  • 如以下答案中所建议的那样,只有当您想要更新 UI 并且不在这些线程中执行业务逻辑或数据操作时,您才必须使用 Platform.runLater()。因此,在您的示例中,您应该调用 Runnable,并且当可运行对象完成工作时,它应该使用 Platform.runLater() 更新 UI。另请注意,对于大型应用程序,最好使用 ExecutorService ,而不是按需生成线程

标签: java javafx connection-string fxml


【解决方案1】:

我假设您展示的 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);
}

【讨论】:

  • 谢谢詹姆斯,我知道这是为了更新文本字段,但我的问题是:String msg = getFromServer.readUTF();即使我不附加文本,我仍然会冻结 GUI。是的,bdw 在 Controller 中实现 Runnable,可以吗?这可能会冻结 GUI??
  • 您是在后台线程中运行它吗?也许您可以编辑您的代码以显示实际调用它的位置。你是说如果你删除chatWindow.appendText(...)完全删除Platform.runLater(...),它仍然会阻塞GUI?
  • 干杯,再次感谢,我更新了代码,如果你可以看看 - github.com/adamdelarosa/Chat_client/blob/master/src/sample/…
  • 詹姆斯,詹姆斯!非常感谢!!!解决了!! (:我会阅读更多关于线程的信息。。新手!!
【解决方案2】:

你应该使用java task而不是platform.runlater,这样你就可以在不同的线程中运行代码,而不会冻结UI线程

【讨论】:

  • 谢谢西乔!我的问题是我添加了 iThread.run() 而不是 iThread.start() 但很确定它也可以通过您的解决方案解决。
猜你喜欢
  • 1970-01-01
  • 2020-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-04
  • 2018-05-16
  • 2017-01-12
  • 1970-01-01
相关资源
最近更新 更多