如何在按钮操作内部刷新 JavaFX 场景?

huangapple go评论91阅读模式
英文:

How do you refresh JavaFX scene from inside an button action?

问题

我正在制作一个排序算法的可视化工具,我希望界面能够实时更新,以逐步展示排序算法的工作过程。

但是界面只有在sort()方法完成后才会更新,我希望它在updateHeight()方法完成后也能更新。

sort()方法是由onAction触发的。

@FXML
public void sort() throws InterruptedException {
    minHeight = RectHeight[0];
    counter = 0;
    minIndex = 0;
    temp = 0;

    for (int i = 1; i < RectList.size(); i++) {
        System.out.println(RectList.size());
        System.out.println(counter);
        sort2();
    }
}

public void sort2() throws InterruptedException {
    System.out.println("开始排序");

    System.out.println(minHeight);

    System.out.println("寻找最小值");
    for (int i = counter; i < RectList.size(); i++) {
        System.out.println("i= " + i);
        if (RectHeight[i] < minHeight) {
            minHeight = RectHeight[i];
            System.out.println("最小高度= " + minHeight);
            System.out.println("最小索引= " + i);
            minIndex = i;
        }
    }

    updateHeight();
    Thread.sleep(500);
}

public void updateHeight() {
    temp = RectHeight[counter];
    RectHeight[counter] = RectHeight[minIndex];
    RectList.get(counter).setHeight(RectHeight[counter]);

    RectHeight[minIndex] = temp;
    RectList.get(minIndex).setHeight(temp);

    counter++;
    minHeight = RectHeight[counter];
    minIndex = counter;
}

如上所示,这段代码中的内容是关于排序算法可视化工具的。

英文:

I'm making a sorting algorithm visualizer and i want the UI to update in real time to show how it works, step by step.

But the UI only updates when the sort() method is done, I want it to update when updateHeight() is done

the sort() method is initiated by an onAction

   @FXML
public void sort() throws InterruptedException {
minHeight = RectHeight[0];
counter = 0;
minIndex = 0;
temp = 0;
for(int i=1;i&lt;RectList.size();i++){
System.out.println(RectList.size());
System.out.println(counter);
sort2();
}
}
public void sort2() throws InterruptedException {
System.out.println(&quot;start sort&quot;);
System.out.println(minHeight);
System.out.println(&quot;find min&quot;);
for (int i = counter; i &lt; (RectList.size()); i++) {
System.out.println(&quot;i= &quot; + i);
if (RectHeight[i] &lt; minHeight) {
minHeight = RectHeight[i];
System.out.println(&quot;minHeight= &quot; + minHeight);
System.out.println(&quot;minIndex= &quot; + i);
minIndex = i;
}
}
updateHeight();
Thread.sleep(500);
}
public void updateHeight() {
temp = RectHeight
0
+
网站访问量
; RectHeight
0
+
网站访问量
= RectHeight[minIndex]; RectList.get(counter).setHeight(RectHeight
0
+
网站访问量
); RectHeight[minIndex] = temp; RectList.get(minIndex).setHeight(temp); counter++; minHeight = RectHeight
0
+
网站访问量
; minIndex = counter; }

答案1

得分: 1

在 FX 应用线程上永远不要使用 Thread.sleep(),该线程负责渲染 UI,因此通过阻塞它,会阻止 UI 的渲染,正如您所观察到的。

相反,使用 Animation API。这里可以使用一个简单的 Timeline

@FXML
public void sort() {

    Timeline timeline = new Timeline();
    timeline.getKeyFrames().add(new KeyFrame(Duration.millis(500), e -> sort2()));
    timeline.setCycleCount(rectList.size());
    minHeight = rectHeight[0];
    counter = 0;
    minIndex = 0;
    temp = 0;

    timeline.play();

}

public void sort2() {
    System.out.println("开始排序");

    System.out.println(minHeight);

    System.out.println("查找最小值");
    for (int i = counter; i < (rectList.size()); i++) {
        System.out.println("i= " + i);
        if (rectHeight[i] < minHeight) {
            minHeight = rectHeight[i];
            System.out.println("minHeight= " + minHeight);
            System.out.println("minIndex= " + i);
            minIndex = i;
        }
    }

    updateHeight();

}

public void updateHeight() {
    temp = rectHeight[counter];
    rectHeight[counter] = rectHeight[minIndex];
    rectList.get(counter).setHeight(rectHeight[counter]);

    rectHeight[minIndex] = temp;
    rectList.get(minIndex).setHeight(temp);

    counter++;
    minHeight = rectHeight[counter];
    minIndex = counter;

}
英文:

Never sleep on the FX Application thread. That thread is responsible for rendering the UI, so by blocking it with Thread.sleep() you prevent the UI from being rendered, as you have observed.

Instead, use the Animation API. A simple Timeline should work here:

@FXML
public void sort() {
Timeline timeline = new Timeline();
timeline.getKeyFrames().add(new KeyFrame(Duration.millis(500), e -&gt; sort2()));
timeline.setCycleCount(rectList.size());
minHeight = rectHeight[0];
counter = 0;
minIndex = 0;
temp = 0;
timeline.play();
}
public void sort2() {
System.out.println(&quot;start sort&quot;);
System.out.println(minHeight);
System.out.println(&quot;find min&quot;);
for (int i = counter; i &lt; (rectList.size()); i++) {
System.out.println(&quot;i= &quot; + i);
if (rectHeight[i] &lt; minHeight) {
minHeight = rectHeight[i];
System.out.println(&quot;minHeight= &quot; + minHeight);
System.out.println(&quot;minIndex= &quot; + i);
minIndex = i;
}
}
updateHeight();
}
public void updateHeight() {
temp = rectHeight
0
+
网站访问量
; rectHeight
0
+
网站访问量
= rectHeight[minIndex]; rectList.get(counter).setHeight(rectHeight
0
+
网站访问量
); rectHeight[minIndex] = temp; rectList.get(minIndex).setHeight(temp); counter++; minHeight = rectHeight
0
+
网站访问量
; minIndex = counter; }

huangapple
  • 本文由 发表于 2020年10月27日 21:20:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/64555374.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定