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

Posted

技术标签:

【中文标题】JavaFX 中的 TranslateTransition 后节点回到位置(摇动 TextField)【英文标题】:Node back to Position after TranslateTransition in JavaFX (shake TextField) 【发布时间】:2016-03-22 06:43:55 【问题描述】:

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

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 会向右移动。 有没有办法重新定位?或者有更好的方法吗?

【问题讨论】:

【参考方案1】:

不要在每次想要摇动场时都创建新的过渡,否则场会在已经摇动的同时摇动,其结果将难以预测,但可能非常不可取。

您需要做的另一件事是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,有了 setFromX 函数,它可以在没有我的 if-term 的情况下工作。【参考方案2】:

和我的想法一样。 谢谢珠宝海!

我的解决方案是将 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 或另一个 Node 时,转换才会改变。

【讨论】:

以上是关于JavaFX 中的 TranslateTransition 后节点回到位置(摇动 TextField)的主要内容,如果未能解决你的问题,请参考以下文章

JavaFX 中的披露窗格

JavaFX中的样式文本?

JavaFX 中的动画渲染效果

JavaFX 中的 fx:id 和 id: 有啥区别?

JavaFX 中的标签和文本差异

JavaFX UI 在事件侦听器中的 JavaFX 应用程序线程中冻结,但可与 Platform.runLater 一起使用