/** Creates a timer if one doesn't already exist, then starts the timer thread. */
    private void start(int interval) {
      previousDelay = interval;
      lastCall = 0;

      if (timer == null) {
        timer = new Timer(interval, this);
      } else {
        timer.setDelay(interval);
      }

      if (ADJUSTTIMER) {
        timer.setRepeats(false);
        timer.setCoalesce(false);
      }

      timer.start();
    }
    /** Reacts to the timer's action events. */
    public void actionPerformed(ActionEvent e) {
      if (ADJUSTTIMER) {
        long time = System.currentTimeMillis();

        if (lastCall > 0) { // adjust nextDelay
          // XXX maybe should cache this after a while
          // actual = time - lastCall
          // difference = actual - interval
          // nextDelay = previousDelay - difference
          //          = previousDelay - (time - lastCall - interval)
          int nextDelay = (int) (previousDelay - time + lastCall + getRepaintInterval());
          if (nextDelay < MINIMUM_DELAY) {
            nextDelay = MINIMUM_DELAY;
          }
          timer.setInitialDelay(nextDelay);
          previousDelay = nextDelay;
        }
        timer.start();
        lastCall = time;
      }

      incrementAnimationIndex(); // paint next frame
    }
 /** Stops the timer thread. */
 private void stop() {
   timer.stop();
 }