2016-03-22 6 views
2

Nach einem falschen Einfügen möchte ich ein Textfeld schütteln. Dafür i-Code haben eine statische Shake AnimationKnoten zurück zu Position nach 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(); 
} 

Diese Animation in einem Change aufgerufen wird, wenn die Eingabe falsch ist. Das funktioniert gut, aber wenn der Benutzer falsche Zeichen sehr schnell eingibt, bewegt sich das TextField nach rechts. Gibt es eine Möglichkeit, eine Neupositionierung durchzuführen? Oder gibt es einen besseren Weg, dies zu tun?

Antwort

1

Erstelle nicht jedes Mal einen neuen Übergang, wenn du das Feld schütteln willst, sonst wird das Feld zittern, während es bereits zittert, dessen Ergebnis schwer vorhersehbar, aber wahrscheinlich ziemlich unerwünscht wäre.

Die andere Sache, die Sie tun müssen, ist setFromX(0) für den Übergang zu übersetzen. Dies ist eigentlich ziemlich wichtig, denn was mit einem Translate-Übergang passiert, ist, dass der translateX-Wert für den Knoten bei seinem Stopp bei dem bleibt, was er war, als der Übergang aufhörte.

Wenn Sie playFromStart mehrmals während der Wiedergabe aufrufen, wird der Übergang erneut gestoppt und dann von Anfang an gestartet. Wenn Sie kein fromX haben, dann ist der Anfang, wo auch immer der Wert von translateX zuletzt gelandet ist (was vielleicht nicht das ist, was Sie wollen und nach dem Schütteln könnte sich der Gegenstand in scheinbar zufällige Positionen auf dem Bildschirm bewegen) . Wenn Sie jedoch ein fromX haben, beginnt der anfängliche translateX-Wert immer von einer nicht übersetzten Position.

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(); 
     } 
    } 
} 
+0

Dank juwelsea, mit der setFromX-Funktion funktioniert es ohne meine if-Laufzeit. – kayf

0

So wie ich denke. Danke Juwel!

Die Lösung ist für mich die TranslateTransition statisch und verwenden Sie es in der statischen Methode wie folgt zu machen:

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; 
} 

Auf diese Weise wird ein Schütteln nur durch, wenn die vorherigen gestoppt wird. Und der Übergang wurde nur geändert, wenn es NULL oder ein anderer Knoten ist.