首页 > 解决方案 > JavaFX 阻止非 UI 线程,直到 GUI 完成更新(在暂停转换中)

问题描述

我想可视化我的 HeapSort。基本上,当我交换数组中的两个元素时,我还想更改表示数组值的图表的条形。见下图。

我在每次数组交换后使用 PauseTransition,因为我也想在 GUI 中可视化每个交换,但是,完整的算法在第一次暂停转换的延迟结束之前完成,因此不是每个步骤都显示在 GUI 上,但是只有最终的结果。

我需要阻止非 UI 线程,以便显示每个交换。

我努力了
Thread.sleep(1000)

但是在对数组进行排序之前,GUI 是隐藏的

这是我的 swapElements 代码片段

private void swapElements(int parentIndex, int childIndex) {
    int tempParent = array[parentIndex];
    array[parentIndex] = array[childIndex];
    array[childIndex] = tempParent;


    PauseTransition wait = new PauseTransition(Duration.seconds(1));

    wait.setOnFinished((e) -> {
        Bar parentBar = Controller.bars.get(parentIndex);
        Controller.bars.set(parentIndex, Controller.bars.get(childIndex));
        Controller.bars.set(childIndex, parentBar);
    });
    wait.play();
}

这是我的控制器:

public class Controller implements Initializable {
public HBox hBox;
public static ObservableList<Bar> bars = FXCollections.observableArrayList();


@Override
public void initialize(URL location, ResourceBundle resources) {

    bars.addListener(new ListChangeListener<Bar>() {
        @Override
        public void onChanged(Change<? extends Bar> c) {
            runOnUiThread();
        }
    });

    HeapSort heapSort = new HeapSort();
    heapSort.heapIT();
}

public void runOnUiThread(){
    Platform.runLater(new Runnable() {
        @Override
        public void run() {
            hBox.getChildren().setAll(bars);
        }
    });
}
}

PS。我在执行时填写了bars列表,heapITHeapSort把它留下了,算法与我的问题无关(IMO)

图表的示例图像:
在此处输入图像描述

标签: javajavafx

解决方案


你可能最好做完整的 MVC。你已经完成了大部分。

让控制器告诉模型排序中的更新。然后让控制器等到 GUI 更新。如何?当控制器将监听的转换完成时,让 GUI 通知模型。当控制器听到 GUI 更新时,它可以处理下一步。

您需要一个钩子才能知道排序何时完成。

FWIW:不完全熟悉 jaavafx 转换,所以我不确定如何监听转换以完成,但我想有一种方法(覆盖方法或监听事件)


推荐阅读