This applet demonstrates a simple animation of a dropped ball.
A subclass of JPanel
called DropPanel
calculates the position of the ball for each increment in frame
time and redraws it. The Runnable
applet creates a thread that invokes the run()
method in the applet. The run()
holds a loop that tells the DropPanel
to update the ball position and redraw itself. Then the loop pauses
for 25 milliseconds using the static sleep()
method in the Thread
class.
The applet builds a basic interface to hold the DropPanel
and a button to initiate a drop. Note how the button is disabled
during the drop.
DropApplet.java
+ DropPanel.java
|
import
javax.swing.*;
import java.awt.*;
import java.awt.event.*;
/**
* This applet implements Runnable and uses a thread
* to create a simple dropped ball demonstration.
**/
public class DropApplet extends JApplet
implements
Runnable, ActionListener{
// Will use thread reference as a flag
Thread fThread = null;
DropPanel fDropPanel = null;
JButton fDropButton = null;
/** Constructor builds the interface. **/
public void init () {
Container content_pane = getContentPane
();
content_pane.setLayout (new BorderLayout
());
// Create an instance of DropPanel
fDropPanel = new DropPanel ();
// Add the DropPanel to the content
pane.
content_pane.add ("Center",fDropPanel);
// Create a button and add it
fDropButton = new JButton ("Drop");
fDropButton.addActionListener (this);
content_pane.add ("South",fDropButton);
} // init
/** Start when browser is loaded or button pushed.
**/
public void start () {
// If the thread reference not null
then a
// thread is already running. Otherwise,
create
// a thread and start it.
if (fThread == null){
fThread =
new Thread (this);
fThread.start
();
}
} // start
/** Applet's stop method used to stop thread.**/
public void stop () {
// Setting thread to null will cause
loop in
// run () to finish and kill the
thread.
fThread = null;
} // stop
/** Button command. **/
public void actionPerformed (ActionEvent ae){
if (fDropPanel.isDone ()) start ();
}
/** The thread loops to draw each frame of drop.**/
public void run () {
// Disable button during drop
fDropButton.setEnabled (false);
// Initialize the ball for the drop.
fDropPanel.reset ();
// Loop through animation frames
while ( fThread != null){
// Sleep 25msecs between
frames
try{ Thread.sleep (25);
} catch (InterruptedException
e) { }
// Repaint drop panel
for each new frame
fDropPanel.repaint ();
if ( fDropPanel.isDone
()) fThread = null;
}
// Enable button for another drop
fDropButton.setEnabled (true);
} /// run
} // class DropApplet |
import
javax.swing.*;
import java.awt.*;
/** This JPanel subclass animates the dropping of a ball.**/
public class DropPanel extends JPanel {
// Parameters for the drop
double fY = 0.0, fVy = 0.0, fYConvert = 0.0;
int fXPixel = 0, fYPixel = 0, fRadius = 0, fDiam
= 0;
// Flag for drop status
boolean fDropDone = false;
// starting point for ball in cm
double fY0 = 1000.0;
// Frame dimensions.
int fFrameHt = 100, fFrameWd = 100;
// Reset parameters for a new drop
void reset () {
fFrameHt = getHeight ();
fFrameWd = getWidth ();
fXPixel = getWidth ()/2;
fY = fY0; fVy = 0;
// Conversion factor from cm to
pixels
// Start the ball about 20% from
the top
// of the frame
fYConvert = fFrameHt / (1.2
* fY0);
// Choose a size for the ball relative
fRadius = (int) ( (0.1
* fY0) * fYConvert);
fDiam = 2 * fRadius;
setBackground (Color.WHITE);
fDropDone=false;
} // reset
/** Draw the ball at its current position. **/
public void paintComponent (Graphics
g){
super.paintComponent (g);
// Clip so no part of the ball is
drawn
// outside of the frame.
g.setClip (0, 0, fFrameWd-1,
fFrameHt-1);
// Determine position after this
time increement
calcPosition ();
g.setColor (Color.RED);
// Now draw a solid color circle.
g.fillOval (fXPixel-fRadius,fYPixel-fRadius,fDiam,fDiam);
}
void calcPosition () {
// Increment by 25 millseconds per
frame
double dt = 0.025;
// Calculate position and velocity
at each step
fY = fY + fVy * dt - 490.* dt *
dt;
fVy = fVy - 980.0
* dt;
// Convert to the pixel coordinates
fYPixel = fFrameHt - (int)
(fY * fYConvert);
// Reverse direction when ball hits
bottom.
if ((fYPixel + fRadius) >= (fFrameHt-1))
{
fVy = Math.abs (fVy);
// Subtract
friction loss
fVy -=
0.1*fVy;
// Stop
when speed at bottom drops below arbitrary limit
if (fVy
< 15.0) {
fDropDone=true;
}
}
} // clacPosition
/** Provide a flag on drop status. **/
public boolean isDone () {
return fDropDone;
}
} // class DropPanel
|
See the Java 2D version of this applet in the Chapter
8: Supplements section.
Latest update April 29, 2004
|