【问题标题】:Node back to Position after TranslateTransition in JavaFX (shake TextField)JavaFX 中的 TranslateTransition 后节点回到位置(摇动 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 会向右移动。 有没有办法重新定位?或者有更好的方法吗?

【问题讨论】:

    标签: animation javafx shake


    【解决方案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 时,转换才会改变。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-08
      • 1970-01-01
      • 2015-06-02
      • 2015-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多