5

Could someone teach me how to use a swing timer with the following purpose:

I need to have a polygon that begins being animated(simple animation such as rotating) when I click the mouse; and stops animating when I click again.

I do not have problems understanding the way the MouseListener works, but with the actual animation. I tried simulating the animation with a while block inside the paint() method where I would draw, erase and redraw the polygon(to simulate a rotation for example), but inside the while, the applet would not listen to the clicks. It would listen only after the while. I would need the swing timer to break the while when I click the mouse.

dreamcrash
  • 47,137
  • 25
  • 94
  • 117
biggdman
  • 2,028
  • 7
  • 32
  • 37

3 Answers3

7
import javax.swing.Timer;

Add an attribute;

Timer timer; 
boolean b;   // for starting and stoping animation

Add the following code to frame's constructor.

timer = new Timer(100, new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent ae) {
        // change polygon data
        // ...

        repaint();
    }
});

Override paint(Graphics g) and draw polygon from the data that was modified by actionPerformed(e).

Finally, a button that start/stop animation has the following code in its event handler.

if (b) {
    timer.start();
} else {
    timer.stop();
}
b = !b;
wannik
  • 12,212
  • 11
  • 46
  • 58
  • Sorry if my questions will seem stupid, but what do you mean by frame's constructor ( is it the init() method). Also where do I implement the button(event handler). Thank you – biggdman Nov 11 '11 at 11:11
  • The constructor of a class is a method that has the same name as the class. For example, the class `public MyFrame extends javax.swing.JFrame` has `public MyFrame() { ... }` as its constructor. The constructor will be called when we create the object using `new` keyword. For example, a frame object can be created using this command `MyFrame f = new MyFrame();` – wannik Nov 11 '11 at 11:20
  • Ok I understand, but I don't see where do I have a frame constructor in a class that extends java applet. I added the new timer to the init() method, but it doesn't seem to work right. The applet respons to clicks, but it seems that the polygon data doesn't get changed. – biggdman Nov 11 '11 at 11:42
  • If you use Applet, you can put the code `timer = new Timer...` in the `init()` method. No need to create a constructor. BTW, have you overrided `public void paint( Graphics g )` to paint the polygon? – wannik Nov 11 '11 at 13:18
  • I have put the code timer = new Timer... in the init() method. In the paint method i have something like if coordonates of the mouse click are on the polygon then{ timer.start(); drawPolygon;}. Is it ok if i put timer.start() in the paint() method? – biggdman Nov 11 '11 at 14:24
  • `paint(g)` should contain just drawing code such as `g.drawLine(...)`. – wannik Nov 11 '11 at 14:40
2

This example controls a javax.swing.Timer using a button, while this related example responds to a mouse click. The latter example reverses direction on each click, but start/stop is a straightforward alteration.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
1

The applet won't listen to clicks because the main thread (the Event Dispatch Thread, EDT) is within the while-loop and isn't listening to your clicks.

You need another thread. (try using SwingWorker http://download.oracle.com/javase/tutorial/uiswing/concurrency/worker.html)

So, the SwingWorker will do the while-loop in the background, publishing results to make your polygon move.

And the EDT can then focus on any events (like clicks). You can then just use the click-event to kill the SwingWorker if you want to stop it.

Good luck

00jt
  • 2,818
  • 3
  • 25
  • 29