如何从按钮操作中刷新 JavaFX 场景?
How do you refresh JavaFX scene from inside an button action?
我正在制作一个排序算法可视化工具,我希望 UI 实时更新以逐步显示其工作原理。
但是 UI 仅在 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("start sort");
System.out.println(minHeight);
System.out.println("find min");
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();
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;
}
永远不要在 FX 应用程序线程上休眠。该线程负责呈现 UI,因此通过使用 Thread.sleep()
阻止它可以防止呈现 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("start sort");
System.out.println(minHeight);
System.out.println("find min");
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;
}
我正在制作一个排序算法可视化工具,我希望 UI 实时更新以逐步显示其工作原理。
但是 UI 仅在 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("start sort");
System.out.println(minHeight);
System.out.println("find min");
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();
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;
}
永远不要在 FX 应用程序线程上休眠。该线程负责呈现 UI,因此通过使用 Thread.sleep()
阻止它可以防止呈现 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("start sort");
System.out.println(minHeight);
System.out.println("find min");
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;
}