【问题标题】:How to animate an UI without freeze when mouse is not over window?当鼠标不在窗口上时,如何在不冻结的情况下为 UI 设置动画?
【发布时间】:2018-10-14 21:43:09
【问题描述】:

我正在构建一个带有一些必须旋转的形状的游戏,问题是,当鼠标从窗口移出时它会停止动画,并在后台继续,因为当鼠标再次进入窗口时它会继续美好的时光

我也尝试过使用TimerTimerTask 但同样的问题

我已经构建了一个精彩的最小且完整的示例,它解释了这一点:

public class Tests extends Application {    
    public static void main(String[] args) {    launch(args);    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        BorderPane pane = new BorderPane(); 
        pane.setPrefSize(300, 300);
        Arc arc = new Arc(150, 150, 50, 50, 0, 190.0);
        arc.setFill(Paint.valueOf("#f32f32"));
        Label label = new Label();
        pane.setCenter(arc);
        pane.setTop(label);
        primaryStage.setScene(new Scene(pane));
        primaryStage.show();
        primaryStage.centerOnScreen();

        Task<Void> task = new Task<Void>() {
            @Override
            protected Void call() throws Exception {
                try {
                    Thread.sleep(2000);
                    Platform.runLater(() -> label.setText("Start"));
                    for (int i = 0; i < 360 * 5; i++) {
                        arc.setRotate(i);
                        Thread.sleep(5);
                    }
                    Platform.runLater(() -> label.setText("Stop"));
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return null;
            }
        };    
        new Thread(task).start();
        task.setOnSucceeded(e -> { Platform.exit(); System.exit(0); });
    }
}

【问题讨论】:

  • 您无法从后台线程更新 UI。使用Timeline
  • 或者结合Task.progress属性+Task.updateProgress的绑定。
  • @fabian 和 rotateProperty 这样吗?

标签: java animation javafx freeze


【解决方案1】:

我认为您缺少用于轮换的 Platform.runLater:

for (int i = 0; i < 360 * 5; i++) {
    final int j = i;
    Platform.runLater(() -> arc.setRotate(j));
    Thread.sleep(5)
}

【讨论】:

    【解决方案2】:

    我没想到会回答我的问题,但因为我找到了使用Timeline 的解决方案(感谢James_D 的评论),所以这里是:

    // Instead of all the Task, only : 
    Timeline timeline = new Timeline();
    final KeyValue kv = new KeyValue(arc.rotateProperty(), 1800);
    final KeyFrame kf = new KeyFrame(Duration.millis(5000), kv);
    timeline.getKeyFrames().add(kf);
    timeline.play();
    timeline.setOnFinished(e -> label.setText("Stop"));
    

    【讨论】:

    • @fabian 在这里肯定不需要多个时间轴,但是我需要在开始时快速旋转,然后越来越慢直到它安静地停止,我必须找到一种数学函数来增加等待时间
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-05
    • 2012-02-07
    • 2011-12-27
    • 2016-09-15
    • 2012-04-21
    • 1970-01-01
    相关资源
    最近更新 更多