JavaFX Timeline II: Verschieben einer ImageView

hk

Bekanntes Mitglied
Ich verschiebe mit Timeline eine ImageView um 10 Pixel. Das funktioniert und wird am Bildschirm korrekt angezeigt. Sehe ich mir nachher die Position des ImageView an (.getY()) so steht dort aber immer noch die ursprüngliche Position die nun aber falsch ist. Wie komme ich zu einer richtigen Position des ImageView?
 
Y

yfons123

Gast
Das Problem ist dass das Update erst nach dem Frame passiert

du kannst einen ChangeEventhandler für die Y position schreiben und auf die New Value reagieren
 

hk

Bekanntes Mitglied
Das Problem ist dass das Update erst nach dem Frame passiert

du kannst einen ChangeEventhandler für die Y position schreiben und auf die New Value reagieren
Ich habe ein setOnFinished EventHandler und dort sind die Werte noch die Alten.
Auch wenn ich mir später (auf Klick) die Position ansehe ist sie noch die Alte obwohl sie am Schirm auf der richtigen Position steht.
Aber ich werde das probieren, Danke
 

KonradN

Super-Moderator
Mitarbeiter
Es wäre wichtig, dass wir genaue Informationen bekommen, was getan wird.

Wenn Du ein setY aufrufst, dann wird ein nachfolgendes getY den neuen Wert zurück geben. Mögliche Probleme kommen nur, wenn Veränderungen asynchron ablaufen:
  • Du rufst irgendwas auf. Dies triggert ein Event und im Rahmen des Eventhandlings ändert sich dann etwas
  • Da im weiteren Code das Event noch nicht behandelt wurde, gibt es die Änderungen noch nicht
  • irgendwann später wird dann das Event bearbeitet. Dann erst ändern sich die Werte,

Das aber nur als einfache Bescheibung worum in in dem anderen Thread ging. Was bei Dir ggf. falsch läuft können wir aber nur sagen, wenn wir den Code sehen. (Ideal ist immer etwas das auch übersetzt und das man selbst ausführen kann zum testen!)
 

hk

Bekanntes Mitglied
Es wäre wichtig, dass wir genaue Informationen bekommen, was getan wird.
Hier der Code:
Java:
  /**************************************************
   * Eine Schrittfolge links, rechts, links animieren
   */
  public void walkOn() {
//    step();
    makeOneStep(app.schuhOL, 0, -10, 500, 0);      //linker Schritt kurz
    makeOneStep(app.schuhOR, 0, -20, 1000, 500);   //rechter Schritt normal
//    makeOneStep(app.schuhOL, 0, -20, 1000, 1000);  //linker Schritt normal
  } //end walkOn *****************************************************

  /**************************
   * Eine Schritt durchführen
   *
   * @param imgV
   * @param x
   * @param y
   * @param dur : Durchlaufzeit
   * @param del : Wartezeit bis Start
   */
  private void makeOneStep(ImageView imgV, double x, double y, int dur,
          int del) {
    KeyValue kvX = new KeyValue(imgV.translateXProperty(), x);
    KeyValue kvY = new KeyValue(imgV.translateYProperty(), y);
    KeyFrame kf = new KeyFrame(Duration.millis(dur), kvX, kvY);
    Timeline tl = new Timeline(kf);
    tl.setCycleCount(1);
    tl.setAutoReverse(false); 
    tl.setDelay(Duration.millis(del));
    tl.setOnFinished(new EventHandler<ActionEvent>() {
      @Override
      public void handle(ActionEvent t) {
         System.out.println("X: " + newX + " Y: " + newY);    <-- URSPRÜNGLICHE POSITION
      }
    });
    tl.playFromStart();
  } //end makeOneStep *************************************************
 

KonradN

Super-Moderator
Mitarbeiter
Wie sehen keine weiteren Stellen mit newX / newY: Wo sind dieser deklariert? Wann wird diesen etwas zugewiesen?
 

KonradN

Super-Moderator
Mitarbeiter
Also generell sehe ich mehrere Möglichkeiten:
a) Du nutzt die translate Properties. Schauen wir uns einfach einmal die Dokumentation an:
The node's final translation will be computed as layoutX + translateX, where layoutX establishes the node's stable position and translateX optionally makes dynamic adjustments to that position.

This variable can be used to alter the location of a node without disturbing its layoutBounds, which makes it useful for animating a node's location.
==> Wenn Du also die layoutBounds auswertest (die layoutX Position), dann ist diese nicht verändert.

b) Wenn Du die richtige Abfrage gemacht haben solltest, dann kann natürlich das Problem auch sein, dass du die Variablen nur einmal setzt und danach nie wieder.

Generell kannst Du die Position einer Komponente in der Scene bekommen per:
Bounds boundsInScene = node.localToScene(node.getBoundsInLocal());

Das ist ein Rest von meinen Versuchen die Position manuell nachträglich zu setzen. Siehe es als "System.out.println(imgV.getX(), imgV.getY())
Ok, dann dürfte a) das Problem sein. Hier evtl. noch kurz zu dem Verständnis:
  • Du hast Elemente (Nodes), welche eine gewisse Position/Größe u.s.w. haben. Dies wird einmal festgelegt.
  • Zur Anzeige wird dies aber weiter angepasst. Das sind dann unter dem Strich Transforms, die dann das Element verschieben, drehen, skalieren, ....
Was Du also da hast ist erst einmal nur die reine Basis-Angabe. Die Anpassungen machst Du ja über die Transformierung. Damit ändert sich nicht die Basis-Angabe sondern nur die Darstellung. Wenn Du jetzt wissen willst, wo der Node dargestellt wird, dann musst Du dies auch verarbeiten. getBoundsInLocal wäre da die erste Methode. Das ganze will man dann aber noch in einem einheitlichen Koordinatensystem haben, also z.B. in der Scene, daher vermutlich noch ein localToScene Aufruf.
 

hk

Bekanntes Mitglied
Wenn Du jetzt wissen willst, wo der Node dargestellt wird, dann musst Du dies auch verarbeiten. getBoundsInLocal wäre da die erste Methode. Das ganze will man dann aber noch in einem einheitlichen Koordinatensystem haben, also z.B. in der Scene, daher vermutlich noch ein localToScene Aufruf.
Die Anpassungen des Code führen zu den Ergebnis, dass das ImageView (nach der richtigen Bewegung) noch einen Sprung um weitere ca. 10 Pixel macht.
Java:
  /**************************************************
   * Eine Schrittfolge links, rechts, links animieren
   */
  public void walkOn() {
//    step();
    makeOneStep(app.schuhOL, 0, -10, 500, 0);      //linker Schritt
    makeOneStep(app.schuhOR, 0, -20, 1000, 500);   //rechter Schritt
//    makeOneStep(app.schuhOL, 0, -20, 1000, 1000);  //linker Schritt
  } //end walkOn *****************************************************

  /**************************
   * Eine Schritt durchführen
   *
   * @param imgV
   * @param x
   * @param y
   * @param dur : Durchlaufzeit
   * @param del : Wartezeit bis Start
   */
  private void makeOneStep(ImageView imgV, double x, double y, int dur,
          int del) {
    KeyValue kvX = new KeyValue(imgV.translateXProperty(), x);
    KeyValue kvY = new KeyValue(imgV.translateYProperty(), y);
    KeyFrame kf = new KeyFrame(Duration.millis(dur), kvX, kvY);
    Timeline tl = new Timeline(kf);
    tl.setCycleCount(1);
    tl.setAutoReverse(false); 
    tl.setDelay(Duration.millis(del));
    tl.setOnFinished(new EventHandler<ActionEvent>() {
      @Override
      public void handle(ActionEvent t) {
        Bounds boundsInScene = imgV.localToScene(imgV.getBoundsInLocal());
        final Point2D value = imgV.localToScene(0, 0);    <-- Differenz Start/Ziel
        imgV.setX(imgV.getX() + value.getX());  //Bewegung im ImageView nachvollziehen
        imgV.setY(imgV.getY() + value.getY());    <-- führt zu einem Sprung um weitere 10 pixel
        System.out.println("X: " + imgV.getX() + " Y: " + imgV.getY()); <-- Position ok
      }
    });
    tl.playFromStart();
  } //end makeOneStep *************************************************
 

KonradN

Super-Moderator
Mitarbeiter
Da verstehe ich gerade nicht, was Du genau versuchst. Es geht doch nur um die Bestimmung der Position. Also setzt Du keine Position.

Und die Werte solltest Du in boundsInScene haben. Da Du nur das imgV verschiebst kannst Du auch mit dem localToScene Aufruf feststellen, um wieviel es verschoben wurde und du könntest dann die effektiven x und y Koordinaten berechnen.
Aber diese darfst Du natürlich nicht setzen, denn dann würdest Du es natürlich erneut verschieben.

Sprich: Berechne mit imgV.getX() + value.getX() die effektie X-Koordinate aber setze diese nicht!
 

hk

Bekanntes Mitglied
Da verstehe ich gerade nicht, was Du genau versuchst. Es geht doch nur um die Bestimmung der Position. Also setzt Du keine Position.
Wenn ich die Position nach der Animation nicht setze, dann wird bei einer Wiederholung der Animation wieder auf der Ursprungsposition begonnen. Beispiel: Start Animation 1 300/250 Bewegung -10 Pixel Y. Die Animation ist ok. Start Animation 2 wieder bei 300/250. Also muss ich irgendwie die Position um den Animationsfaktor anpassen.
 

hk

Bekanntes Mitglied
Ich habe das Problem nun in einer kleinen fertigen App dargestellt. Da sieht man deutlich, dass das Aufeinanderfolgen von Bewegungen nicht stimmt. Allerdings weiß ich nicht warum!

Java:
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;

/**
 * JavaFX App
 */
public class App extends Application {

  @Override
  public void start(Stage stage) {
    Rectangle r = new Rectangle(300, 200, 20, 20);
    var scene = new Scene(new Pane(r), 640, 480);
    // bei Maus-Klick
    scene.addEventHandler(MouseEvent.MOUSE_RELEASED, e -> {
      if(e.getButton().equals(MouseButton.PRIMARY)) move(r, 10, 0); //nach rechts
      else move(r, 0, 10);  //nach unten
  });   
    stage.setScene(scene);
    stage.show();
  }
  // Eine Bewegung durchführen
  private void move(Rectangle r, double x, double y) {
    KeyValue kvX = new KeyValue(r.translateXProperty(), x);
    KeyValue kvY = new KeyValue(r.translateYProperty(), y);
    System.out.println("Gewünschte Bewegung nach: X= " + x + " Y= " + y);
    KeyFrame kf = new KeyFrame(Duration.millis(500), kvX, kvY);
    Timeline tl = new Timeline(kf);
    tl.setCycleCount(1);
    tl.setAutoReverse(false); 
    tl.setDelay(Duration.millis(500));
    tl.setOnFinished(new EventHandler<ActionEvent>() {
      @Override
      public void handle(ActionEvent t) {
        System.out.println("LayoutX: " + r.getLayoutX() + " LayoutY: " + r.getLayoutY());
        System.out.println("boundsInScene: " + r.localToScene(r.getBoundsInLocal()));
        System.out.println("X: " + r.getX() + " Y: " + r.getY());
      }
    });
    tl.playFromStart();
  }   
  public static void main(String[] args) {
    launch();
  }
}
 

KonradN

Super-Moderator
Mitarbeiter
Noch einmal die Grundlagen, die ich schon einmal versucht habe, zu erläutern:

a) So ein Node hat eine Position im übergeordneten Element. Diese kannst Du mit x / y holen/setzen (also getX, setX, getY, setY)
b) Bei der Anzeige wird das Element aber ggf. noch verschoben. Dazu dienen translateXProperty / translateYProperty.

Diese nutzt Du bei deiner Bewegung. Denn da gibst Du vor, wie etwas verschoben werden soll. Dein Rechteck ist also auf 300, 200, translate x/y ist 0 / 0 --> Rechteck wird bei 300,200 angezeigt.

Nun kommt der erste Klick -> translateX soll auf 10 gehen, translateY soll auf 0 gehen (in der Animation)
==> Das Rechteck wandert nun in der Animation auf 310, 200

Nun kommt der andere Klick -> TranslateX soll wieder auf 0 gehen, translateY soll auf 10 gehen (in der Animation)
==> Das Rechteck wandert nun nach links unten.

Nehmen wir die Problematik, die Du beschrieben hattest:
Das Kästchen wandert von 300,200 nach 310,200 (position ist 300,200 aber translateX ist 10).
Wenn translateX auf 10 ist und Du die Position auf die Dargestellte Position umsetzten, dann hast Du Position bei 310,200 und dargestellt wird das Kästchen durch die translateX 10 bei 320,200
==> Da macht das Kästchen dann einen Sprung.

Was kannst Du jetzt machen?

a) Du kannst die Position jedes Mal neu setzen. Dazu musst Du dann aber nicht nur die Position setzen sondern auch das translateX auf 0 setzen. Also etwas wie:
Java:
                r.setX(r.localToScene(r.getBoundsInLocal()).getMinX());
                r.setY(r.localToScene(r.getBoundsInLocal()).getMinY());
                r.translateXProperty().set(0);
                r.translateYProperty().set(0);

b) Du lässt die Position konstant und die Bewegung ist immer relativ - es wird also addiert:
Java:
        KeyValue kvX = new KeyValue(r.translateXProperty(), r.translateXProperty().get() + x);
        KeyValue kvY = new KeyValue(r.translateYProperty(), r.translateYProperty().get() + y);
Dadurch würde die erste Bewegung das translateX von 0 auf 10 setzen, die zweite Bewegung wäre dann von 10 auf 20 u.s.w.

Da es Dir ja um die Visualisierung einer Bewegung geht, sollte es eigentlich a) sein aus meiner Sicht.
 

KonradN

Super-Moderator
Mitarbeiter
Juhu, das war's! Herzlichen Dank.
Aber bitte wo kann man das Nachlesen, ich habe mir zig Beispiele angesehen und nichts dergleichen gefunden.
Ich gehe da immer gerne über die Dokumentation. Im JavaDoc findet sich in der Regel alles, was man braucht.

Aber dazu ist wichtig, dass man etwas ein Überblick hat, was wie zusammen hängt - so lange man das noch nicht hat ist es extrem schwer.

Da wäre dann der Weg, zu dem ich raten würde: Nerve uns hier im Forum so lange, bis wir es Dir erklären konnten :)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
H JavaFX Timeline Bewegungen am ImageView nachvollziehen AWT, Swing, JavaFX & SWT 0
missy72 JavaFX Performance / ImageView in TableView über TimeLine AWT, Swing, JavaFX & SWT 1
H JavaFX Timeline KeyFrame Reihenfolge AWT, Swing, JavaFX & SWT 6
missy72 JavaFX TimeLine / KeyFrame AWT, Swing, JavaFX & SWT 4
J JavaFX Stoppuhr mit javafx.timeline AWT, Swing, JavaFX & SWT 2
F JavaFX Timeline Animation soll X- und Y-Position während Animation ändern AWT, Swing, JavaFX & SWT 2
B Rechteck Mit Hilfe Von Timeline, KeyFrames animieren AWT, Swing, JavaFX & SWT 3
B Java Media Frame (TimeLine) AWT, Swing, JavaFX & SWT 2
Redeason Objekte in meiner GUI verschieben AWT, Swing, JavaFX & SWT 1
frager2345 JTextLabel im Flowlayout verschieben AWT, Swing, JavaFX & SWT 4
U JavaFX CheckBoxen in GUI verschieben AWT, Swing, JavaFX & SWT 20
M Polygon per Drag&Drop verschieben AWT, Swing, JavaFX & SWT 26
F Popup Menu etwas verschieben AWT, Swing, JavaFX & SWT 2
K JavaFX Element in HBOX nach rechts verschieben AWT, Swing, JavaFX & SWT 2
J Button lässt sich nicht auf dem JPanel verschieben AWT, Swing, JavaFX & SWT 5
M Swing JPanel flüssig verschieben AWT, Swing, JavaFX & SWT 5
T AWT Grafik"Array" einzelne Elemente verschieben AWT, Swing, JavaFX & SWT 1
N JLabel in JTabbedPane verschieben AWT, Swing, JavaFX & SWT 2
B JavaFX Viewport verschieben AWT, Swing, JavaFX & SWT 3
C LayoutManager Bei verkleinern des Fensters, verschieben sich JPanels übereinander. AWT, Swing, JavaFX & SWT 7
C Swing Geschachteltes GUI mit BorderLayout - Vertikal & horizontal Verschieben AWT, Swing, JavaFX & SWT 1
M Swing JPanel innerhalb eines Frames verschieben AWT, Swing, JavaFX & SWT 3
Y Titel Verschieben AWT, Swing, JavaFX & SWT 11
Z Bildervorschau, MouseDragged das Bild verschieben AWT, Swing, JavaFX & SWT 1
M label mit icon verschieben. AWT, Swing, JavaFX & SWT 1
R Swing Elemente verschieben sich im GBL beim Ein/Ausblenden AWT, Swing, JavaFX & SWT 0
W Buttons verschieben AWT, Swing, JavaFX & SWT 3
Z Plot nach links verschieben!! AWT, Swing, JavaFX & SWT 1
M 3D-Grafik Denkfehler bei Verschieben von Shapes AWT, Swing, JavaFX & SWT 0
T JLabel Nullpunkt verschieben AWT, Swing, JavaFX & SWT 6
K JavaFX Spalten der Tabellen verschieben AWT, Swing, JavaFX & SWT 2
P JList/JScroolPane Text verschieben und text wrappen AWT, Swing, JavaFX & SWT 3
L JFrame von der Taskleiste zu den ausgeblendeten Symbolen verschieben AWT, Swing, JavaFX & SWT 2
O Swing Spalten-Position nach verschieben AWT, Swing, JavaFX & SWT 6
T Swing JButton per Drag&Drop verschieben AWT, Swing, JavaFX & SWT 5
L Componenten im JFrame an genaue stelle verschieben. AWT, Swing, JavaFX & SWT 2
D JSplitPane lässt sich nicht verschieben AWT, Swing, JavaFX & SWT 3
A JLabel verschieben AWT, Swing, JavaFX & SWT 9
bluerob JComponenten verschieben sich bei Fenster wechseln AWT, Swing, JavaFX & SWT 3
J jFrame verschieben verhindern AWT, Swing, JavaFX & SWT 4
H Bild mit KeyListener verschieben AWT, Swing, JavaFX & SWT 2
R JTextField Eingabefeld innerhalb verschieben AWT, Swing, JavaFX & SWT 2
P Rectangle verschieben AWT, Swing, JavaFX & SWT 11
C Bild auf Panel vergrößern und verschieben AWT, Swing, JavaFX & SWT 4
P Objekte anzeigen und verschieben - wie? AWT, Swing, JavaFX & SWT 6
H LayoutManager Panel verschieben sich AWT, Swing, JavaFX & SWT 5
B Element schrittweise verschieben AWT, Swing, JavaFX & SWT 2
G Swing JPanel per Maus verschieben AWT, Swing, JavaFX & SWT 5
K Button verschieben AWT, Swing, JavaFX & SWT 4
T 2D-Grafik gezeichnetes Bild verschieben - rand bleibt sichtbar AWT, Swing, JavaFX & SWT 2
propra Mehrere Objekte gleichzeitig verschieben AWT, Swing, JavaFX & SWT 7
V Swing JScrollPane Viewport verschieben AWT, Swing, JavaFX & SWT 2
propra Objekte auf Zeichenfläche verschieben AWT, Swing, JavaFX & SWT 2
P Swing JTable null values an das Ende verschieben AWT, Swing, JavaFX & SWT 2
M verschieben der Objekte in JPanel nur stückchenweise möglich AWT, Swing, JavaFX & SWT 14
B FlowLayout Buttons verschieben? AWT, Swing, JavaFX & SWT 13
K JButtons innerhalb eines JPanels verschieben (DRAG&DROP) AWT, Swing, JavaFX & SWT 5
R Swing Verschieben eines jButtons mittels MouseDragged AWT, Swing, JavaFX & SWT 4
Z 2D-Grafik Bild auf JPanel verschieben AWT, Swing, JavaFX & SWT 4
D Grafik über JPanels hinweg verschieben AWT, Swing, JavaFX & SWT 2
D Swing Swing Komponenten verschieben AWT, Swing, JavaFX & SWT 7
B Swing AbstractTableModel rows verschieben AWT, Swing, JavaFX & SWT 2
S 2D-Grafik Shapes auf Zeichenfläche gleichmäßig verschieben AWT, Swing, JavaFX & SWT 5
Burny91 Swing Vertical JSplitPane lässt sich nicht nach rechts verschieben AWT, Swing, JavaFX & SWT 2
E Swing Rechteck und Kreise verschieben AWT, Swing, JavaFX & SWT 3
N verschieben von Dateien auf der Festplatte über TreePaths funktioniert nicht AWT, Swing, JavaFX & SWT 10
F Swing Objekte mit Maus verschieben AWT, Swing, JavaFX & SWT 8
E Swing Drag n Drop Verschieben von Labels o.ä. AWT, Swing, JavaFX & SWT 10
K Swing Elemente auf Zeichenfeld verschieben AWT, Swing, JavaFX & SWT 8
C Drag and Drop JPanel auf JPanel nach drop erneut verschieben? AWT, Swing, JavaFX & SWT 3
B JLabel mittels Timer und setLocation verschieben AWT, Swing, JavaFX & SWT 3
M Buttons per Drag & Drop im GridBagLayout verschieben AWT, Swing, JavaFX & SWT 6
C paintComponent mit Maus verschieben - wie? AWT, Swing, JavaFX & SWT 2
T Swing JComboBox: Listeneinträge mit der Maus verschieben AWT, Swing, JavaFX & SWT 5
J showMessageDialog nicht über frame verschieben AWT, Swing, JavaFX & SWT 6
R Bereiche auf Panel verschieben AWT, Swing, JavaFX & SWT 2
U SWT Linien verschwinden nach Verschieben AWT, Swing, JavaFX & SWT 3
D Swing Spaltenköpfe verschieben sich nicht mit, wenn man an horizontaler Scrollbar zieht AWT, Swing, JavaFX & SWT 9
R Swing Frame verschieben AWT, Swing, JavaFX & SWT 3
C JTable mit RowSorter und Drag & Drop: Zeile verschieben AWT, Swing, JavaFX & SWT 4
D Swing Buttons verschieben sich bei umbennenung! AWT, Swing, JavaFX & SWT 3
R Rows und Columns in JTable verschieben? AWT, Swing, JavaFX & SWT 8
N RCP/SWT View durch Programm auf 2. Bildschirm verschieben AWT, Swing, JavaFX & SWT 2
O JTable Zeilen "nach oben" verschieben AWT, Swing, JavaFX & SWT 3
G Listenelemente mit der Maus verschieben AWT, Swing, JavaFX & SWT 4
K JTable Spalten nicht verschieben AWT, Swing, JavaFX & SWT 2
F Verschieben einer Messnadel auf einem Bild AWT, Swing, JavaFX & SWT 2
S Buttons verschieben mit Swing AWT, Swing, JavaFX & SWT 5
R JPanel durch "klicken und ziehen" verschieben AWT, Swing, JavaFX & SWT 8
H Tabelle: Spaltenüberschriften verschieben sich AWT, Swing, JavaFX & SWT 2
T Fenster verschieben => Wann fertig? AWT, Swing, JavaFX & SWT 8
T Synchrones Window-verschieben AWT, Swing, JavaFX & SWT 4
K JFrame verschieben / Inhalt ändern AWT, Swing, JavaFX & SWT 5
E Komponenten auf Zeichenfläche gruppieren u. verschieben AWT, Swing, JavaFX & SWT 3
Tom299 JTable - Spalten verschieben deaktivieren? AWT, Swing, JavaFX & SWT 3
F "Verschieben" des paint-Bereichs AWT, Swing, JavaFX & SWT 4
vogella JPanel Größe verschieben AWT, Swing, JavaFX & SWT 2
B Objekte auf Fenster verschieben. Bewegliche jPanels. AWT, Swing, JavaFX & SWT 5
J Nochmal Drag&Drop, ABER: Object verschieben AWT, Swing, JavaFX & SWT 2
D Rechtecke verschieben? AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen

Neue Themen


Oben