当鼠标不在 window 上时,如何在不冻结的情况下为 UI 设置动画?
How to animate an UI without freeze when mouse is not over window?
我正在构建一个游戏,其中包含一些必须旋转的形状,问题是,当鼠标离开 window 时,它会停止动画,并在后台继续,因为当鼠标再次出现时在window它继续在美好的时刻
我也试过使用 Timer
和 TimerTask
但同样的问题
我构建了一个极好的最小完整示例,它解释了:
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); });
}
}
我没想到会回答我的问题,但因为我使用 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"));
我认为您缺少 Platform.runLater 轮换:
for (int i = 0; i < 360 * 5; i++) {
final int j = i;
Platform.runLater(() -> arc.setRotate(j));
Thread.sleep(5)
}
我正在构建一个游戏,其中包含一些必须旋转的形状,问题是,当鼠标离开 window 时,它会停止动画,并在后台继续,因为当鼠标再次出现时在window它继续在美好的时刻
我也试过使用 Timer
和 TimerTask
但同样的问题
我构建了一个极好的最小完整示例,它解释了:
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); });
}
}
我没想到会回答我的问题,但因为我使用 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"));
我认为您缺少 Platform.runLater 轮换:
for (int i = 0; i < 360 * 5; i++) {
final int j = i;
Platform.runLater(() -> arc.setRotate(j));
Thread.sleep(5)
}