Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8106906

Can't get interpolated values when pausing at dynamically inserted empty frame.

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Won't Fix
    • Icon: P4 P4
    • None
    • None
    • javafx
    • Windows Vista, Netbeans 6.5, JavaFX Kit 1.7, JavaFX SDK 1.6 for Windows,

      All weekends I was trying to find the way to pause animation at any(!) frame and get interpolated values of animated objects at this particular frame.
      I've found the way to pause timeline but still I have terrible problem: I can't get correct interpolated values.

      It's possible to pause at any time using newly inserted frame with action function which performs pause() on timeline.
      But interpolated values will be returned for pausedFrame -1. For example you make pause at 1000ms and see that your interpolated values == 0. You make pause() at 2000 and get values for 1000ms. Strange thing.

      This is a code:
      ***************************************************

      import javafx.stage.Stage;
      import javafx.scene.Scene;
      import javafx.scene.shape.Rectangle;
      import javafx.scene.paint.Color;
      import javafx.animation.KeyFrame;
      import javafx.animation.Timeline;
      import javafx.animation.Interpolator;
      import javafx.ext.swing.SwingTextField;
      import javafx.ext.swing.SwingButton;
      import javafx.scene.input.MouseEvent;
      import javafx.scene.layout.HBox;

      /**
       * @author SSheipak
       */

       //Movable rectangle
      var xOff = 0.0;
      var yOff = 0.0;
      def rectangle: Rectangle = Rectangle{
          x: bind 50.0 + xOff
          y: bind 50.0 + yOff
          width: 50
          height: 50
          fill: Color.RED
      }

      //Read frame value
      def inputTimeField: SwingTextField = SwingTextField{
          width: 100
          height: 30
          columns: 10
      }

      def button: SwingButton = SwingButton{
          text: "Go to frame"
          onMouseClicked: function(evt: MouseEvent): Void{
              //get Duration
              var time: Duration = Duration.valueOf( Float.valueOf(inputTimeField.text) );
              //Prepare new KeyFrame with pause() action
              var newKeyFrame: KeyFrame = createKeyFrameWithPause(time);//+1ms);
              //find place for newKeyFrame
              var i: Integer = 0;
              for(keyFrame in timeline.keyFrames){
                  if(isAtTheEndOfSequence(i, timeline.keyFrames.size())
                     or isCanBeInserted(newKeyFrame, keyFrame, timeline.keyFrames[i+1])){
                      //<debug>
                      println("---------------------------------------------");
                      if( isAtTheEndOfSequence(i, timeline.keyFrames.size()) ){
                          println("insert {newKeyFrame.time} after {timeline.keyFrames[i].time} at the end of the sequence");
                      }else {
                          println("insert {newKeyFrame.time} after {timeline.keyFrames[i].time} and before {timeline.keyFrames[i+1].time}");
                      }
                      //</debug>
                      insert newKeyFrame after timeline.keyFrames[i];
                      break;
                  }//
                  i++;
              }//for
              timeline.time = time;
              timeline.play();
              println("At {newKeyFrame.time} rectangle has x={rectangle.x} and y={rectangle.y}, xOff={xOff},yOff={yOff}");
              printKeyFramesTime();
              println("");
          }
      }

      //Container for Swing components
      def hBox: HBox = HBox{
          content: [inputTimeField, button]
      }

      //Frames for timeline
      var keyFrames: KeyFrame[] = [
          KeyFrame{
              time: 0ms
              values: [xOff => 0.0, yOff => 0.0]
          },
          KeyFrame{
              time: 6000ms
              values: [xOff => 400.0 tween Interpolator.LINEAR, yOff => 400.0 tween Interpolator.LINEAR]
          }
      ];

      //Timeline
      def timeline: Timeline = Timeline{
          time: 0ms
          keyFrames: keyFrames
      }

      Stage {
          title: "Halt Timeline"
          width: 600
          height: 600
          scene: Scene {
              content: [hBox, rectangle]
          }
      }

      /**Checks is current index points to the last element of Sequence
       @param position is an index to test
       @param seqSize is a value of someSeq.size()
       @return true if position points to the last element of the sequence else returns false
       */
      function isAtTheEndOfSequence(position: Integer, seqSize: Integer): Boolean{
          var isAt: Boolean = false;
          if( (position + 1) >= seqSize){
              isAt = true;
          }
          return isAt;
      }

      /**Find ordered place for KeyFrame in KeyFrame sequence using keyFrame.time
       @param testing is a KeyFrame you want to insert into seq
       @param current is a current KeyFrame of a seq
       @param next is a next KeyFrame of q seq
       @return true if testing.time >= current.time and <= next.time else returns false
       */
      function isCanBeInserted(testing: KeyFrame, current: KeyFrame, next: KeyFrame): Boolean{
          var isCan = false;
          var testingTime = testing.time;
          var currentTime = current.time;
          var nextTime = next.time;
          if(testingTime >= currentTime and testingTime <= nextTime){
              isCan = true;
          }
          return isCan;
      }

      /**Print all frames of timeline in format [keyFrame.time]*/
      function printKeyFramesTime():Void{
          var str: String = "KeyFrames -> ";
          for(kf in timeline.keyFrames){
              str+="[{kf.time}] ";
          }
          println(str);

      }

      function createKeyFrameWithPause(time: Duration): KeyFrame{
          var keyFrame: KeyFrame = KeyFrame{
                                      time: time
                                      action: function(): Void{
                                                  timeline.pause();
                                              }
                                   };
          return keyFrame;
      }

      output:
      *****************************************
      ---------------------------------------------
      insert 3000ms after 0ms and before 6000ms
      At 3000ms rectangle has x=50.0 and y=50.0, xOff=0.0,yOff=0.0
      KeyFrames -> [0ms] [3000ms] [6000ms]

      ---------------------------------------------
      insert 4000ms after 3000ms and before 6000ms
      At 4000ms rectangle has x=250.0 and y=250.0, xOff=200.0,yOff=200.0
      KeyFrames -> [0ms] [3000ms] [4000ms] [6000ms]

      ---------------------------------------------
      insert 5000ms after 4000ms and before 6000ms
      At 5000ms rectangle has x=316.6667 and y=316.6667, xOff=266.6667,yOff=266.6667
      KeyFrames -> [0ms] [3000ms] [4000ms] [5000ms] [6000ms]

      ---------------------------------------------
      insert 6000ms after 5000ms and before 6000ms
      At 6000ms rectangle has x=383.3333 and y=383.3333, xOff=333.3333,yOff=333.3333
      KeyFrames -> [0ms] [3000ms] [4000ms] [5000ms] [6000ms] [6000ms]

      ---------------------------------------------
      insert 6000ms after 5000ms and before 6000ms
      At 6000ms rectangle has x=50.0 and y=50.0, xOff=0.0,yOff=0.0
      KeyFrames -> [0ms] [3000ms] [4000ms] [5000ms] [6000ms] [6000ms] [6000ms]

      ---------------------------------------------
      insert 6000ms after 5000ms and before 6000ms
      At 6000ms rectangle has x=50.0 and y=50.0, xOff=0.0,yOff=0.0
      KeyFrames -> [0ms] [3000ms] [4000ms] [5000ms] [6000ms] [6000ms] [6000ms] [6000ms]

      ---------------------------------------------
      insert 1000ms after 0ms and before 3000ms
      At 1000ms rectangle has x=50.0 and y=50.0, xOff=0.0,yOff=0.0
      KeyFrames -> [0ms] [1000ms] [3000ms] [4000ms] [5000ms] [6000ms] [6000ms] [6000ms] [6000ms]

      ---------------------------------------------
      insert 1000ms after 0ms and before 1000ms
      At 1000ms rectangle has x=116.66667 and y=116.66667, xOff=66.66667,yOff=66.66667
      KeyFrames -> [0ms] [1000ms] [1000ms] [3000ms] [4000ms] [5000ms] [6000ms] [6000ms] [6000ms] [6000ms]

      ---------------------------------------------
      insert 3000ms after 1000ms and before 3000ms
      At 3000ms rectangle has x=117.53333 and y=117.53333, xOff=67.53333,yOff=67.53333
      KeyFrames -> [0ms] [1000ms] [1000ms] [3000ms] [3000ms] [4000ms] [5000ms] [6000ms] [6000ms] [6000ms] [6000ms]

      ---------------------------------------------
      insert 6000ms after 5000ms and before 6000ms
      At 6000ms rectangle has x=250.0 and y=250.0, xOff=200.0,yOff=200.0
      KeyFrames -> [0ms] [1000ms] [1000ms] [3000ms] [3000ms] [4000ms] [5000ms] [6000ms] [6000ms] [6000ms] [6000ms] [6000ms]

      ---------------------------------------------
      insert 6001ms after 6000ms at the end of the sequence
      At 6001ms rectangle has x=50.0 and y=50.0, xOff=0.0,yOff=0.0
      KeyFrames -> [0ms] [1000ms] [1000ms] [3000ms] [3000ms] [4000ms] [5000ms] [6000ms] [6000ms] [6000ms] [6000ms] [6000ms] [6001ms]

      ---------------------------------------------
      insert 6000ms after 5000ms and before 6000ms
      At 6000ms rectangle has x=50.0 and y=50.0, xOff=0.0,yOff=0.0
      KeyFrames -> [0ms] [1000ms] [1000ms] [3000ms] [3000ms] [4000ms] [5000ms] [6000ms] [6000ms] [6000ms] [6000ms] [6000ms] [6000ms] [6001ms]

      ---------------------------------------------
      insert 6000ms after 5000ms and before 6000ms
      At 6000ms rectangle has x=450.0 and y=450.0, xOff=400.0,yOff=400.0
      KeyFrames -> [0ms] [1000ms] [1000ms] [3000ms] [3000ms] [4000ms] [5000ms] [6000ms] [6000ms] [6000ms] [6000ms] [6000ms] [6000ms] [6000ms] [6001ms]



            mheinrichs Michael Heinrichs (Inactive)
            duke J. Duke
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported: