Другой вариант, вместо создания отдельной переменной boolean
, заключается в использовании свойства status
из Animation
. Вы также можете использовать один и тот же Animation
для каждой плитки.
import javafx.animation.Animation.Status;
import javafx.animation.RotateTransition;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Main extends Application {
private RotateTransition transition;
@Override
public void start(Stage primaryStage) throws Exception {
GridPane root = new GridPane();
root.setPadding(new Insets(20));
root.setHgap(15);
root.setVgap(15);
EventHandler<MouseEvent> onClick = this::handleClick;
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
Rectangle rect = new Rectangle(50, 50);
rect.setOnMouseClicked(onClick);
root.add(rect, i, j);
}
}
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.setTitle("Animation Example");
primaryStage.setResizable(false);
primaryStage.show();
}
private void handleClick(MouseEvent event) {
if (transition == null) {
transition = new RotateTransition(Duration.seconds(100));
transition.setByAngle(90);
} else if (transition.getStatus() == Status.RUNNING) {
return;
}
transition.setNode((Rectangle) event.getSource());
transition.playFromStart();
event.consume();
}
}
Этот код начнет новый переход, только если он в данный момент не запущен. Однако обратите внимание, что эта установка позволяет вращать только одну плитку в любой момент времени. Если вы хотите иметь анимацию на плитку, это требует небольшой корректировки.
import java.util.HashMap;
import java.util.Map;
import javafx.animation.Animation.Status;
import javafx.animation.RotateTransition;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Main extends Application {
private final Map<Rectangle, RotateTransition> animations = new HashMap<>();
@Override
public void start(Stage primaryStage) throws Exception {
GridPane root = new GridPane();
root.setPadding(new Insets(20));
root.setHgap(15);
root.setVgap(15);
EventHandler<MouseEvent> onClick = this::handleClick;
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
Rectangle rect = new Rectangle(50, 50);
rect.setOnMouseClicked(onClick);
root.add(rect, i, j);
}
}
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.setTitle("Animation Example");
primaryStage.setResizable(false);
primaryStage.show();
}
private void handleClick(MouseEvent event) {
RotateTransition animation = animations.computeIfAbsent((Rectangle) event.getSource(), rect -> {
RotateTransition rt = new RotateTransition(Duration.millis(100), rect);
rt.setByAngle(90);
return rt;
});
if (animation.getStatus() != Status.RUNNING) {
animation.playFromStart();
event.consume();
}
}
}
Теперь у каждой плитки есть свой RotateTransition
, но анимация будет воспроизводиться только в том случае, если она еще не запущена.