【问题标题】:Updating scene in javafx with delays延迟更新 javafx 中的场景
【发布时间】:2021-07-04 07:23:48
【问题描述】:

我想编写一个 javafx 应用程序,其中有两个“更新”和“取消”按钮以及三个矩形。当您点击取消按钮时,它会使所有矩形变为黑色。当您单击更新按钮时,我只希望第一个矩形变为红色,半秒后,第二个矩形变为绿色(其他变为黑色),再过半秒,第三个矩形变为蓝色和其他黑色。

我试图通过Thread.sleep 来实现这一点,但我无法解决我的问题。

关于如何做到这一点的任何建议?

这是我到目前为止写的代码,但它似乎忽略了Thread.sleep,只使第三个变成蓝色。

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

import static javafx.scene.paint.Color.*;

public class UpdatingSceneWithDelays extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        AnchorPane anchorPane = new AnchorPane();
        Rectangle rectangle1 = new Rectangle(100, 100, 100, 100);
        Rectangle rectangle2 = new Rectangle(100, 250, 100, 100);
        Rectangle rectangle3 = new Rectangle(100, 400, 100, 100);
        Button button1 = new Button("cancel");
        Button button2 = new Button("update");
        button2.setLayoutY(100);
        button1.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent mouseEvent) {
                rectangle1.setFill(BLACK);
                rectangle2.setFill(BLACK);
                rectangle3.setFill(BLACK);
            }
        });
        button2.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent mouseEvent) {
                rectangle1.setFill(RED);
                rectangle2.setFill(BLACK);
                rectangle3.setFill(BLACK);
                try {
                    Thread.sleep(500);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                rectangle1.setFill(BLACK);
                rectangle2.setFill(GREEN);
                rectangle3.setFill(BLACK);
                try {
                    Thread.sleep(500);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                rectangle1.setFill(BLACK);
                rectangle2.setFill(BLACK);
                rectangle3.setFill(BLUE);
            }
        });
        anchorPane.getChildren().add(rectangle1);
        anchorPane.getChildren().add(rectangle2);
        anchorPane.getChildren().add(rectangle3);
        anchorPane.getChildren().add(button1);
        anchorPane.getChildren().add(button2);
        Scene scene = new Scene(anchorPane, 800, 800);
        stage.setScene(scene);
        stage.show();
    }
}

【问题讨论】:

    标签: java javafx


    【解决方案1】:

    您不能sleep JavaFX 应用程序线程。该线程专门用于读取和写入 UI 状态、调度渲染“脉冲”以及处理用户生成的事件。如果您阻止或以其他方式垄断它,则它无法完成工作,并且 UI 冻结/变得无响应。

    无论何时您想要在 JavaFX 应用程序线程 上进行延迟操作(无论是否循环),您都应该使用动画。就个人而言,在这种情况下,我会选择Timeline。这是一个例子:

    Timeline timeline =
        new Timeline(
            // first rectangle to red (assumes all start as black)
            new KeyFrame(
                Duration.ZERO, 
                e -> rectangle1.setFill(Color.RED)),
            // first rectangle to black, second to green
            new KeyFrame(
                Duration.seconds(0.5),
                e -> {
                  rectangle1.setFill(Color.BLACK);
                  rectangle2.setFill(Color.GREEN);
                }),
            // second rectangle to black, third to blue
            new KeyFrame(
                Duration.seconds(1.0), // duration doesn't stack
                e -> {
                  rectangle2.setFill(Color.BLACK);
                  rectangle3.setFill(Color.BLUE);
                }));
    timeline.playFromStart();
    

    您可以根据需要重复使用动画(尽管它不能同时运行多个自身实例)。请注意,Timeline 将异步播放,对playFromStart()play() 的调用将立即返回。如果这对您的应用程序来说是个问题,那么您需要重写它以考虑到这一点。例如,您可以在完成后使用timeline.setOnFinished(...) 做某事。

    只是为了提出它们,您至少可以在此处使用两种替代方法(我不会详细介绍):

    1. 将每个KeyFrame 的已完成处理程序替换为一个或多个KeyValues。对于与以前相同的行为,您需要每个 KeyValue 使用离散的 Interpolator

    2. 将多个PauseTransitions 与SequentialTransition(持续时间叠加)或ParallelTransition(持续时间不叠加)结合使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-18
      • 2015-05-16
      • 2015-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-28
      相关资源
      最近更新 更多