I\'m attempting to code a simple animation or physics example in a Java Swing application. I have the actual windows application open and working, but I can\'t figure out how to
There are any number of ways to achieve this.
Start by taking a look at:
For details about how painting in Swing is done.
Animation is not as simple as just pausing a small period of time and then repainting, theres acceleration and deceleration and other concepts that need to be considered.
While you could write your own, that's not a small task, a better solution might be to use a pre-existing engine, for example...
Then take a look at:
Which are all examples of animation engines in Swing. While I prefer the Timing Framework as it provides me with a lower level API, this is a personal opinion. Both Trident and the JUWE seem to be geared more towards component/property based animation (which the Timing Framework can do if you want to build some of the feature sets up)
"I've read some stuff about over riding a paint method, but I don't know what that means"
So you've overridden actionPerformed
, so you know what an @Override
is. As you'll notice from the ActionListener
, you never actually explicitly call actionPerformed
, but whatever you put in the there, still get's used. That's because the ActionListener
implicitly call it for you.
The same is true with painting. In the Swing painting process, there is a paint chain that Swing uses to paint components. Along the way paint
is called somewhere. So just like actionPerformed
, you can override paint
and it will get implicitly called for you.
@Override
public void paint(Graphics g) {
super.paint(g);
}
The Graphics
object passed to the method is the graphics context that Swing will use for the painting. You can look at the Graphics API to see the methods you can use. You can use drawOval to draw a circle
@Override
public void paint(Graphics g) {
super.paint(g);
g.drawOval(x, y, width, height);
}
Now here's the thing. You don't actually want to override paint
. In the tutorials linked above, some of the examples will use applets and override paint
, but you shouldn'y paint on top level containers like JFrame
or JApplet
. Instead paint on a JPanel
or JComponent
and just add it the JFrame
. When you do paint on JPanel
or JComponent
, you'll instead override paintComponent
(which also gets called along the paint chain), instead of paint
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawOval(x, y, width, height);
}
You see how I used variables for the drawOval
method. The x
is the x location from the top-let of the screen, and y
and the y point. width
and height
are width and height of the circle. The great thing about using variables is that their values can be changed at runtime.
That's where the animation comes to play. As pointed out, you an use a javax.swing.Timer
The basic construct is
public Timer(int delay, ActionListener listener) {
}
The delay
is the milliseconds to delay each call to the listener. The listener will have your actionPerformed
call back that will do what's inside, every delay
milliseconds. So what you can do, is just change the x
from the drawOval
and repaint()
, and it will animate. Something like
Timer timer = new Timer(40, new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
x += 5;
repaint();
}
});
timer.start();
The timer code you can just put in the constructor. That's probably simplest explanation I can give. Hope it helps.
Don't forget the to see Custom Painting and Grapics2D for more advance topics on graphics. Also see some example of timers and animation here and here and here and here and here
Also avoid using null layouts. See Laying out Components Within a Container to learn how to use layout managers, as should be done with Swing apps.
Take a look at the Swing tutorial on Custom Painting.
The example shows you how to do painting. If you want animation, then you would use a Swing Timer
to schedule the animation. The tutorial also has a section on How to use a Swing Timer
.
Put the two tutorial together and you have a solution.
I created a simple animation with two rockets blasting off. The full eclipse project is here: https://github.com/CoachEd/JavaExamples/tree/master/RaceToSpace. Here's a screenshot: