JavaFX 中的 TranslateTransition 后节点回到位置(摇动 TextField)

Node back to Position after TranslateTransition in JavaFX (shake TextField)

插入错误后,我想摇动文本字段。 为此,我编写了一个静态摇动动画

public static void shake(Node node) {
  TranslateTransition tt = new TranslateTransition(Duration.millis(50), node);
  tt.setByX(10f);
  tt.setCycleCount(2);
  tt.setAutoReverse(true);
  tt.playFromStart();
}

当输入错误时,在 ChangeListener 中调用此动画。 这工作正常,但如果用户输入错误字符的速度非常快,则 TextField 会向右移动。 有没有办法重新定位?或者有更好的方法吗?

不要每次都想晃动场就创建一个新的过渡,否则场会在晃动的时候晃动,其结果很难预测,但可能很不受欢迎。

您需要做的另一件事是 setFromX(0) 进行翻译转换。这实际上非常重要,因为转换转换发生的情况是,当它停止时,节点的 translateX 值保持在转换停止时的值。

当您在播放过渡时多次调用 playFromStart 时,过渡将再次停止,然后从头开始。如果你没有 fromX,那么开始将是 translateX 值最后结束的地方(这可能根本不是你想要的,并且在摇动之后,该项目可能开始移动到屏幕上看似随机的位置) .但是,如果您有 fromX,则起始 translateX 值将始终从未翻译的位置开始。

import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.*;
import javafx.scene.control.TextField;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Duration;

public class ShakenNotStirred extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        TextField field = new TextField();
        Shaker shaker = new Shaker(field);
        field.textProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue != null) {
                try {
                    Integer.parseInt(newValue);
                } catch (NumberFormatException e) {
                    shaker.shake();
                }
            }
        });
        StackPane layout = new StackPane(field);
        layout.setPadding(new Insets(20));

        stage.setScene(new Scene(layout));
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

    class Shaker {
        private TranslateTransition tt;

        public Shaker(Node node) {
            tt = new TranslateTransition(Duration.millis(50), node);
            tt.setFromX(0f);
            tt.setByX(10f);
            tt.setCycleCount(2);
            tt.setAutoReverse(true);
        }

        public void shake() {
            tt.playFromStart();
        }
    }
}

我也是这么想的。 谢谢 jewelsea!

我的解决方案是使 TranslateTransition 静态化并在静态方法中使用它,如下所示:

private static TranslateTransition tt;
public static TranslateTransition shake(Node node) {
  if (tt == null || tt.getNode() != node)
  {
      tt = new TranslateTransition(Duration.millis(50), node);
  }
  tt.setByX(10f);
  tt.setCycleCount(2);
  tt.setAutoReverse(true);
  if (tt.getStatus() == Status.STOPPED)
  {
      tt.playFromStart();
  }
  return tt;
}

这样一来,摇一摇只有在前一摇停止时才会执行。只有当它为 NULL 或另一个节点时,转换才会改变。