The Bouncing Ball

This program is set up with two files:

Bouncer is the object to handle the user interface - the buttons. It also starts and stops the thread.

Ball is the thread. It also draws and moves the ball around.

The Code For Bouncer, with commentary:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Bouncer extends JPanel implements ActionListener
{
JButton bounceBall;
JButton reset;
Ball bounce;
public static final int sizex = 350;
public static final int sizey = 400;

instance variables include buttons to manipulate ball and size of the screen.
public Bouncer ()
{
super (new BorderLayout ());
bounce = new Ball (sizex, sizey); //a new selection bounceBall object (other file)
setBackground (Color.white);
//bounceBall button stuff
bounceBall = new JButton ("Start");
bounceBall.setActionCommand ("Start");
bounceBall.addActionListener (this);

//reset button stuff
reset = new JButton ("Stop");
reset.setActionCommand ("Stop");
reset.addActionListener (this);

//panel & interface stuff
JPanel p = new JPanel (new FlowLayout ());
p.setBackground (Color.white);
p.add (bounceBall);
p.add (reset);
add (p, "North");
add (bounce, "Center");
}

Set up the screen's buttons.
public void actionPerformed (ActionEvent e)
{ //if bounceBall button is presed
if (e.getActionCommand ().equals ("Start"))
{ //start a new thread and start bouncing the ball
Thread bounceBallingThread = new Thread (bounce, "Ballthread");
bounceBallingThread.start ();

}
else if (e.getActionCommand ().equals ("Stop"))
{ //stop the thread
bounce.stopBall ();
}
}

This is where the thread gets started. 'bounce' which is the ball object, gets passed to it. Calling 'start' actually calls the 'run' method in the thread.

When the ball is stopped, the 'bounce' object - the ball - is stopped. Not the thread.

public static void main (String [] args)
{
//Make sure we have nice window decorations.
JFrame.setDefaultLookAndFeelDecorated (true);

//Create and set up the window.
JFrame frame = new JFrame ("Bouncing Ball Demo");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

//Create and set up the content pane.
JComponent newContentPane = new Bouncer ();
newContentPane.setOpaque (true); //content panes must be opaque
frame.setContentPane (newContentPane);
frame.setSize (sizex, sizey+65);

//Display the window.
frame.setVisible (true);
}
}

Set up a frame to hold it all. Change the object in the contentPane and the name on the Frame.

The Code for Ball.java, with commentary:

import java.awt.*;
import javax.swing.*;
import java.text.*;

public class Ball extends JComponent implements Runnable
{
private volatile int x; //present co-ordinate
private volatile int y; //present co-ordinate
private volatile boolean dir_x; //true equals right
private volatile boolean dir_y; //true equals up
private volatile boolean stopped; //true if the ball isn't bouncing
private int bound_x; //how big the screen is in the x direction
private int bound_y; //how big the screen is in the y direction
private int speed; //how fast the ball is moving

Instance Variables for position and direction
public Ball (int xx, int yy)
{ //Pre: xx is how big the screen is in the x direction, yy for the y direction
//Post: a new ball is constructed and initialized
x = 150;
y = 82;
dir_x = true;
dir_y = true;
bound_x = xx;
speed = 7;
bound_y = (yy);
setBackground (Color.white);
}
Constructor; set up the instance variables and set the screen set.
public void run ()
{ //run method, starts when "Bounce" button is pressed
moveBall ();
}


public void stopBall ()
{ //to pause the thread in the moveball method, stopped must be true
//this stops the loop in moveball
stopped = true;
}

Methods that are called from Bouncer. They change the state of the moveBall method - either starting it or stopping it.
public void drawBall ()
{
repaint ();
}


/** draw the ball on the screen
*/
public void paint (Graphics g)
{
//Draw a white square on screen to erase old ball
g.setColor (Color.white);
g.fillRect (x - 2 * speed, y - 2 * speed, 4 * speed, 4 * speed);
//Choose a colour based on position
int b = (int) x / 2;
int gr = (int) y / 3;
g.setColor (new Color (0, b, gr));
//Draw the new ball
g.fillOval (x - 5, y - 5, 12, 12);
}

Paints the ball on the screen based on its current location.

  • Erases old ball
  • Sets new colour
  • Draw new ball
public void moveBall ()
{ //calculates the new position of the ball and moves it
//repeats until the user clicks the stop button.
stopped = false;

while (!stopped)
{

drawBall ();

//choose new position
if (dir_x) //moving right
{
if (x < (bound_x - 12))
x += speed + 2;
else
{
dir_x = false;
x += 4;
}
}
else //moving left
{
if (x > 5)
x -= speed;
else
{
dir_x = true;
x += speed;
}
}

if (dir_y) //moving up
{
if (y < (bound_y - 12))
y += speed;
else
dir_y = false;
}
else //moving down
{
if (y > 5)
y -= speed;
else
{
dir_y = true;
y += 2;
}
}


//sleep for a bit after choosing new position
try
{
Thread.sleep (50);
}
catch (InterruptedException x)
{
;
}

}
}

Redraws the ball.

Calculates a new position for the ball.

Sleeps for a bit and then repeats!