2

I am using a timer loop to implement animation on my Java app. At the moment I am using static variables that relate to the animation (the start time, where the element's starting from and where it's going to). Is there a simpler way to do this? Can I send these variables as arguments when I start the timer instead?

...
import javax.swing.Timer;

public class SlidePuzz2 extends Applet implements MouseMotionListener, MouseListener {
...

    static Element animating;
    static PieceLoc blank;
    static int delta;
    static int orig_x;
    static int orig_y;
    static long timeStart;

    Timer aniTimer;

...
    public void init() {
...        
        aniTimer = new Timer(20, new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                    int dx = (blank.x*piece-orig_x);
                    int dy = (blank.y*piece-orig_y);
                    int t = 200;
                    delta = (int)(System.currentTimeMillis()-timeStart);
                    if (delta>t) delta=t;
                    animating.x = orig_x + dx*delta/t;
                    animating.y = orig_y + dy*delta/t;
                    repaint();
                    if (delta==t) {
                        animating.updateCA();
                        board.checkCompleted();
                        aniTimer.stop();
                    }
               }
        });
...
            setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));

            blank = board.getBlankPl();
            animating = e;
            timeStart = System.currentTimeMillis();
            orig_x = animating.x;
            orig_y = animating.y;

            aniTimer.start();
...
flea whale
  • 1,783
  • 3
  • 25
  • 38
  • 3
    I believe using the `javax.swing.Timer` is the best way to implement animation. – mre Feb 07 '12 at 19:15
  • @mre yes, that is what I am doing already. my question is how can I use the swing Timer better as in more elegantly, like with avoiding having static variables outside of the animation loop to configure it. – flea whale Feb 07 '12 at 19:19
  • 6
    You don't have to use anonymous ActionListener. Create new class that implements ActionListener and configure it with all related/required data. – tenorsax Feb 07 '12 at 19:24
  • Mwahaa, intriguing, thanks @Max! I shall experiment with this... but any links to examples would be appreciated cos I've only been learning Java less than a week :) – flea whale Feb 07 '12 at 19:26
  • More examples [here](http://stackoverflow.com/a/8237370/230513). – trashgod Feb 07 '12 at 19:30
  • @Max I'm guessing you mean like this: http://zetcode.com/tutorials/javagamestutorial/animation/ apart from that in this example the `board` class that implements `ActionListener` is also the one that needs to be repainted. How can I call `repaint()` method for my applet object from my new animation object? – flea whale Feb 07 '12 at 19:41
  • @Jimmy_Bob, your ActionListener can be inner class, so it can easily access outer class methods. – tenorsax Feb 07 '12 at 20:13

1 Answers1

1

Thanks to comments by @Max I have found a solution to my own problem, creating an inner class inside my main Applet class that extends ActionListener.

public class AniTimer implements ActionListener {
    Element animating;
    PieceLoc blank;
    int orig_x;
    int orig_y;
    long timeStart;
    int delta;

    public AniTimer(Element e, PieceLoc pl) {
        animating = e;
        blank = pl;
        orig_x = animating.x;
        orig_y = animating.y;
        timeStart = System.currentTimeMillis();
    }

        public void actionPerformed(ActionEvent evt) {
        int dx = (blank.x*piece-orig_x);
        int dy = (blank.y*piece-orig_y);
        int t = 200;
        delta = (int)(System.currentTimeMillis()-timeStart);
        if (delta>t) delta=t;
        animating.x = orig_x + dx*delta/t;
        animating.y = orig_y + dy*delta/t;
        repaint();
        if (delta==t) {
            aniTimer.stop();
            animating.updateCA();
            board.checkCompleted();
        }
    }
}

Then when I want to start the animation all I do is make a new Timer with a new instance of my ActionListener class as the second argument and I can pass all the vital arguments relating to just this particular stint of animation to the constructor.

aniTimer = new Timer(20, new AniTimer(e, board.getBlankPl()));
aniTimer.start();

Thanks Max, I'm starting to love Java now!

flea whale
  • 1,783
  • 3
  • 25
  • 38
  • +1 for implementing `ActionListener`. See also [*How to Use Actions*](http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html). – trashgod Feb 25 '12 at 07:24