In this simple code example for an animation of a bouncing ball:
import javax.swing.JApplet;
import javax.swing.JFrame;
import java.awt.*;
public class GraphicsMovement extends JApplet
{
public static void pause()
{
try {
Thread.sleep(10);
} catch(InterruptedException e) {
}
}
public static void main(String args[])
{
JApplet example = new GraphicsMovement();
JFrame frame = new JFrame("Movement");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(example);
frame.setSize(new Dimension(500,300)); //Sets the dimensions of panel to appear when run
frame.setVisible(true);
}
public void paint (Graphics page)
{
int width = getWidth(); // width = the width of the panel which appears when run
int height = getHeight(); // height = the height of the panel which appears when run.
//Changes background color to a blueish color
page.setColor(new Color (140,214,225));
page.fillRect(0,0,width,height);
for(int i = 0; i <= 5; i++)
{
for (int j = 0; j <= 100; j++)
{
page.setColor(Color.YELLOW);
page.fillOval(100,55 + j,100,100); //draws a yellow oval
pause();
page.setColor(new Color (140,214,225));
page.fillOval(100,55 + j,100,100); //draws a blueish oval over the yellow oval
}
for (int k = 100; k >= 0; k--)
{
page.setColor(Color.YELLOW);
page.fillOval(100,55 + k,100,100); //draws a yellow oval
pause();
if (k != 0)
{
page.setColor(new Color (140,214,225)); //draws a blueish oval over the yellow oval
page.fillOval(100,55 + k,100,100);
}
}
}
}
}
The animation is drawn fine and runs on a Windows machine (using JCreator), but will not run on Mac OS X compiled with either IntelliJ or Eclipse. Tried on two different OS X machines, and both will draw the ball and background (after a long wait) but will not proceed with the animation.
Is there some sort of platform-specific code in here that I am missing? Thanks!
paint()
method is called in the UI thread, and it should return as fast as possible.So where will you put the animation code then?The answer is simple: you will need to put the code into a separate thread.
For the difference between Windows and OS X, all I can say is that it should be related on how they schedule threads, or something like that.
Never do anything in any
paint
method that would either block or might trigger a repaint request.You should always call
super.paintXxx
, these methods do a lot of work in the background, usually a lot better then you can.You shouldn't need to (very rare cases) extend from top level containers, like
JApplet
orJFrame
. You are better of creating a custom container (such asJPanel
) and add your components to it (or perform your custom painting). Apart from the double buffering support, you also gain flexibility in deployment choices.Don't kid yourself, you don't control the paint process, it's up to the repaint manager to make those decisions, you can however, "encourage" it to update. This causes the most pain when people start playing with animation.
You should modify the "state" of the animation outside of the influence of the Event Dispatching Thread (EDT) or in your case, out side the
paint
context.You problem is simple enough that a simple
javax.swing.Timer
will solve it. More complex animations might require a "animation" thread.I'm concerned with the "delay" of 10 milliseconds, it's enough to want me to face a fit :P
You might find reading through...
Of some interest