【问题标题】:Main application thread not updating GUI until it reaches end of the method主应用程序线程在到达方法结束之前不会更新 GUI
【发布时间】:2019-04-22 23:12:32
【问题描述】:

我在应用程序中有一个连接按钮,两个窗格放在一个堆栈窗格上。第一个窗格是 chatPane,第二个窗格是背景设置为 .gif 的加载程序。

我想要做的是点击连接后,我想显示加载器(在他的背景上有移动的gif),然后等到delegate.connectToServer(..)方法结束,然后关闭加载器窗格并切换回聊天窗格。

使用当前代码,javaFX 应用程序线程似乎没有可视化对 GUI 所做的更改,直到它到达 connectClicked() 方法的末尾,这意味着没有显示加载程序窗格。

我尝试在线程中将 setConnectionStatus 方法的内容作为任务运行,但在执行此操作时,我通过 Label 对象的 setText 方法收到 Not On fx application thread 异常,但是加载器 gif 显示得很好。

我也尝试过像这样使用暂停过渡:

@FXML
public void connectClicked() {
    setConnectionStatus(CONNECTING);
    PauseTransition pause = new PauseTransition(Duration.seconds(0.1));

    pause.setOnFinished(event -> {
        try {
            delegate.connectToServer(connectionConfig.getServerAddress().getIp(),
                        connectionConfig.getServerAddress().getPort(),
                        connectionConfig.getTimeout());
            setConnectionStatus(CONNECTED);
            } catch (ConnectionException e) {
                setConnectionStatus(DISCONNECTED);
                //todo reconnect dialog
            } catch (FatalException e) {
                handleFatalError("Connection error", e.getMessage());
            }
        });
        pause.play();
    }

这导致加载器窗格显示移动 0.1 秒,然后动画停止(加载器窗格仍然可见,只有 gif 停止)

我也尝试使用Platform.runLater()Thread 包装try catch 块,但没有效果。

我不能使用Platform.runLater 来显示加载程序,因为我希望立即执行 gui 更改,而不是“在未来的某个时间”

这是完整的代码:

@FXML public VBox loader;
@FXML public SplitPane chatPane;
@FXML public MenuItem connectMenuItem;
@FXML public MenuItem disconnectMenuItem;
@FXML public Label connectionStatus;

@FXML
public void connectClicked() {
       setConnectionStatus(CONNECTING);
        try {
            delegate.connectToServer(connectionConfig.getServerAddress().getIp(),
                    connectionConfig.getServerAddress().getPort(),
                    connectionConfig.getTimeout());
            setConnectionStatus(CONNECTED);

        } catch (ConnectionException e) {
            setConnectionStatus(DISCONNECTED);
            //todo reconnect dialog
        } catch (FatalException e) {
            handleFatalError("Connection error", e.getMessage());
        }
    }

     private void setConnectionStatus(ConnectionStatus status) {
        switch (status) {
            case CONNECTED:
                setStatusLabel("Connected", GREEN);
                setConnectionMenu(false, true);
                showChatPane();
                break;
            case DISCONNECTED:
                setStatusLabel("Not Connected", RED);
                setConnectionMenu(true, false);
                showChatPane();
                break;
            case CONNECTING:
                setStatusLabel("Connecting...", BLUE);
                setConnectionMenu(false, false);
                showLoader();
                break;
            case DISCONNECTING:
                setStatusLabel("Disconnecting...", BLUE);
                setConnectionMenu(false, false);
                showLoader();
                break;
        }
    }

    private void setStatusLabel(String text, Color color) {
        connectionStatus.setText(text);
        connectionStatus.setTextFill(color);
    }

    private void setConnectionMenu(boolean isConnectEnabled, boolean isDisconnectEnabled) {
        connectMenuItem.setDisable(!isConnectEnabled);
        disconnectMenuItem.setDisable(!isDisconnectEnabled);
    }

    private void showLoader() {
        chatPane.setVisible(false);
        loader.setVisible(true);
    }

    private void showChatPane() {
        chatPane.setVisible(true);
        loader.setVisible(false);
    }

【问题讨论】:

  • 把你的逻辑放到一个不同于 UI 线程的线程中。
  • 用线程包裹try catch块没有效果,加载器窗格仍然没有显示
  • Google 搜索“JavaFX 后台任务”,我相信您会找到大量资源。非 UI 逻辑(如建立连接,需要很长时间)必须在 UI 线程之外执行。 UI 逻辑(如更新标签)必须在 UI 线程上完成。
  • 将逻辑放入线程中有效,这只是我的愚蠢,因为我使用的是 thread.run() 而不是 thread.start()

标签: java javafx


【解决方案1】:

看起来像用线程包装 try catch 块一样,它之前没有工作,因为我使用的是 thread.run() 而不是 thread.start() ...

我还必须在线程主体内的setConnectionStatus 方法上添加 Platform.runLater。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 2021-01-21
    • 1970-01-01
    相关资源
    最近更新 更多