This page was saved using WebZIP 6.0.8.918 (Unregistered) on 01/20/05 오후 3:27:46.
Address: http://www.leepoint.net/notes-java/45examples/40animation/40BouncingBall/bouncingball.html
Title: Java: Example - Bouncing Ball  •  Size: 11427  •  Last Modified: Fri, 14 Jan 2005 00:25:28 GMT

Java: Example - Bouncing Ball

This program does a simple animation. Animation is done by creating a timer which calls an ActionListener at fixed intervals (eg, every 30 milliseconds). The listener makes some changes (eg, the ball coordinates) and calls the JPanel repaint() (which calls our paintComponent() method indirectly), which uses the updated coordinates to redraw the ball.

BBDemo.java - The main program and window creation

  1 
  2 
  3 
  4 
  5 
  6 
  7 
  8 
  9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
// animation/bb/BBDemo.java - ball bouncing in a box.
//  -- Fred Swartz, December 2004
// Possible extensions: faster/slower button, ...

import javax.swing.JFrame;

///////////////////////////////////////////////////////////////////// BBDemo
public class BBDemo {
    //================================================================= main
    public static void main(String[] args) {
        JFrame win = new JFrame("Bouncing Ball Demo");
        win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        win.setContentPane(new BBPanel());
        win.pack();
        win.setVisible(true); 
    }//endmethod main
}//endclass BBDemo

BBPanel.java - The JPanel which organizes the GUI

  1 
  2 
  3 
  4 
  5 
  6 
  7 
  8 
  9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 33 
 34 
 35 
 36 
 37 
 38 
 39 
 40 
 41 
 42 
 43 
 44 
 45 
 46 
 47 
 48 
 49 
 50 
 51 
// animation/bb/BBPanel.java - Panel with buttons and box.
// Fred Swartz - December 2004

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

/////////////////////////////////////////////////////////////////// BBPanel
class BBPanel extends JPanel {
    BallInBox m_bb;   // The bouncing ball panel
    
    //========================================================== constructor
    /** Creates a panel with the controls and bouncing ball display. */
    BBPanel() {
        //-- Create components
        m_bb = new BallInBox();        
        JButton startButton = new JButton("Start");        
        JButton stopButton  = new JButton("Stop");
        
        //-- Layout inner panel with two buttons horizontally
        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new FlowLayout());
        buttonPanel.add(startButton);
        buttonPanel.add(stopButton);
        
        //-- Layout outer panel with button panel above bouncing ball
        this.setLayout(new BorderLayout());
        this.add(buttonPanel, BorderLayout.NORTH);
        this.add(m_bb       , BorderLayout.CENTER);
        
        //-- Add Listeners
        startButton.addActionListener(new StartAction());
        stopButton.addActionListener(new StopAction());
    }//end constructor
    
    
    ////////////////////////////////////// inner listener class StartAction
    class StartAction implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            m_bb.setAnimation(true);
        }
    }//end inner listener class StartAction
    
    
    //////////////////////////////////////// inner listener class StopAction
    class StopAction implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            m_bb.setAnimation(false);
        }
    }//end inner listener class StartAction
}//endclass BBPanel

BallInBox.java - The graphics panel that does the animation.

  1 
  2 
  3 
  4 
  5 
  6 
  7 
  8 
  9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 33 
 34 
 35 
 36 
 37 
 38 
 39 
 40 
 41 
 42 
 43 
 44 
 45 
 46 
 47 
 48 
 49 
 50 
 51 
 52 
 53 
 54 
 55 
 56 
 57 
 58 
 59 
 60 
 61 
 62 
 63 
 64 
 65 
 66 
 67 
 68 
 69 
 70 
 71 
 72 
 73 
 74 
 75 
 76 
 77 
 78 
 79 
 80 
 81 
 82 
 83 
 84 
 85 
 86 
 87 
 88 
 89 
 90 
 91 
 92 
 93 
 94 
 95 
 96 
 97 
// animation/bb/BouncingBall.java - A ball bouncing in a box.
//   Fred Swartz - December 2004
// Animation is done by changing instance variables
// in a timer's actionListener, then calling repaint().
// * This panel has a simple model for movement: changing
//   the x and y values each time the timer fires.
// * Flicker can be reduced by drawing into a BufferedImage, 
//   and/or using a clip region.
// * The edge of the oval could be antialiased (using Graphics2).

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

/////////////////////////////////////////////////////////////// BouncingBall
public class BallInBox extends JPanel {
    //============================================== fields
    //... Instance variables representing the ball.
    private Ball m_ball         = new Ball(0, 0);
    private int  m_ballDiameter = m_ball.getDiameter(); 
    
    //... Instance variables for the animiation
    private int   m_velocityX = 2;   // Initial x velocity (pixels/interval)
    private int   m_velocityY = 3;   // Initial y velocity
    private int   m_interval  = 30;  // Milliseconds between updates.
    private Timer m_timer;           // Ball moves every time 

    //========================================================== constructor
    /** Sets panel size and creates timer. */
    public BallInBox() {
        setPreferredSize(new Dimension(200, 80));
        setBorder(BorderFactory.createLineBorder(Color.BLACK));
        m_timer = new Timer(m_interval, new TimerListener());
    }//end constructor
    
    //========================================================= setAnimation
    /** Turns the animation on or off.
     *@param turnOnOff Specifies state of animation.
     */
    public void setAnimation(boolean turnOnOff) {
        if (turnOnOff) {
            m_timer.start();  // start animation by starting the timer.
        } else {
            m_timer.stop();   // stop timer
        }
    }//end setAnimation

    //======================================================= paintComponent
    public void paintComponent(Graphics g) {
        super.paintComponent(g);  // Paint background, border
        m_ball.draw(g);           // Draw the ball.
    }//end method paintComponent
    
    //////////////////////////////////// inner listener class ActionListener
    class TimerListener implements ActionListener {
        //================================================== actionPerformed
        /** ActionListener of the timer.  Each time this is called,
         *  the ball's position is updated, creating the appearance of
         *  movement.
         *@param e This ActionEvent parameter is unused.
         */
        public void actionPerformed(ActionEvent e) {
            //... Get the the current size of the Panel, ball bounds.
            int rightBound = getWidth() - m_ballDiameter;
            int bottomBound= getHeight()- m_ballDiameter;
            
            //--- Compute new x position, check for passing over edge.
            int nextX = m_ball.getX() + m_velocityX; // Move in x direction.
            if (nextX < 0) {                // If at or beyond left side
                nextX       = 0;            // Place against edge and
                m_velocityX = -m_velocityX; // reverse direction.
                
            } else if (nextX > rightBound) { // If at or beyond right side
                nextX       = rightBound;    // Place against right edge.
                m_velocityX = -m_velocityX;  // Reverse direction.
            }
            
            //--- Compute new y position analogous to x above.
            int nextY = m_ball.getY() + m_velocityY;
            if (nextY < 0) {                 // if we're at top
                nextY       = 0;
                m_velocityY = -m_velocityY;
                
            } else if (nextY > bottomBound) { // if we're at bottom
                nextY       = bottomBound;
                m_velocityY = -m_velocityY;
            }
            
            //... Move ball to new position.
            m_ball.setPosition(nextX, nextY);
            
            // repaint() must be used to indirectly call paintComponent..
            repaint();     // Repaint the panel
        }//end actionPerformed
    }//end inner class listener
}//endclass

Ball.java - The logic/model of the ball.

This class holds the information about the ball, currently only its position and diamter, but other attributes are possible (eg, color). This ball knows nothing about animation, but it might be reasonable to move the velocity information from the animation code above into Ball.

  1 
  2 
  3 
  4 
  5 
  6 
  7 
  8 
  9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 33 
// animation/bb/BallModel.java - The logic / model of a ball.
// Fred Swartz - December 2004

import java.awt.*;

///////////////////////////////////////////////////////////////// BallModel
public class Ball {
    final static int DIAMETER = 21;
    int m_x;
    int m_y;
    
    //======================================================== constructor
    public Ball(int x, int y) {
        m_x = x;
        m_y = y;
    }
    
    //============================================================== draw
    public void draw(Graphics g) {
        g.fillOval(m_x, m_y, DIAMETER, DIAMETER);        
    }
    
    //============================================= getDiamter, getX, getY
    public int  getDiameter() { return DIAMETER;}
    public int  getX()        { return m_x;}
    public int  getY()        { return m_y;}
    
    //======================================================== setPosition
    public void setPosition(int x, int y) {
        m_x = x;
        m_y = y;
    }
}