AnimationState(final State startState, final long milliseconds, boolean isForwardAndReverse) {
      assert startState != null && milliseconds > 0;
      assert SwingUtilities.isEventDispatchThread();

      this.startState = startState;
      this.duration = milliseconds * 1000000;
      this.startTime = System.nanoTime();
      this.isForwardAndReverse = isForwardAndReverse;
      progress = 0f;
    }
    private void updateProgress() {
      assert SwingUtilities.isEventDispatchThread();

      if (isDone()) {
        return;
      }
      long currentTime = System.nanoTime();

      progress = ((float) (currentTime - startTime)) / duration;
      progress = Math.max(progress, 0); // in case time was reset
      if (progress >= 1) {
        progress = 1;
        if (isForwardAndReverse) {
          startTime = currentTime;
          progress = 0;
          isForward = !isForward;
        }
      }
    }