1  /*
  2   *  File:  MovingSquares.java
  3   *
  4   *  A moving square with boundary checking
  5   *
  6   *  Copyright:  Northeast Parallel Architectures Center
  7   *
  8   */
  9  
 10  import java.applet.Applet;
 11  import java.awt.*;
 12  
 13  public class MovingSquares extends Applet implements Runnable {
 14  
 15    // A reference to a square:
 16    private Square square1, square2;
 17    
 18    // Override java.applet.Applet.init:
 19    public void init () {
 20  
 21      setBackground( Color.black );
 22      setForeground( Color.white );
 23      
 24      // Instantiate two squares:
 25      square1 = new Square( 75, 25, 50 );
 26      square1.setColor( Color.red );
 27      square2 = new Square( 25, 75, 50 );
 28      square2.setColor( Color.blue );
 29      
 30    }
 31  
 32    // A thread of execution:
 33    private Thread thread;
 34      
 35    // Override java.applet.Applet.start:
 36    public void start() {
 37      if ( thread == null ) {
 38        thread = new Thread( this );
 39        thread.start();
 40      }
 41    }
 42    
 43    // Override java.applet.Applet.stop:
 44    public void stop() {
 45      if ( thread != null ) {
 46        thread.stop();
 47        thread = null;
 48      }
 49    }
 50    
 51    // Implement java.lang.Runnable.run:
 52    public void run() {
 53      while ( thread != null ) {
 54        try {
 55          Thread.sleep( 20 );
 56        } catch ( InterruptedException e ) {
 57          // do nothing   
 58        }
 59        repaint();
 60      }
 61    }
 62  
 63    // Initially, the squares move two pixels down and to the right:
 64    int dx1 = 2, dy1 = 2;
 65    int dx2 = 2, dy2 = 2;
 66    
 67    // Override java.awt.Component.paint:
 68    public void paint( Graphics g ) {
 69    
 70      // Check if either square is out of bounds:
 71      checkBounds1( this.getBounds() );
 72      checkBounds2( this.getBounds() );
 73      
 74      // Move and fill square1:
 75      square1.translate( dx1, dy1 );
 76      square1.fill( g );
 77      
 78      // Move and fill square2:
 79      square2.translate( dx2, dy2 );
 80      square2.fill( g );
 81      
 82    }
 83    
 84    private void checkBounds1( java.awt.Rectangle r ) {
 85  
 86      // Get the bounding box of square1:
 87      java.awt.Rectangle bb = square1.getBounds();
 88  
 89      // Compute the dimensions of square1:
 90      int w = bb.width, h = bb.height;
 91      int new_x = bb.x + dx1, new_y = bb.y + dy1;
 92      
 93      // If square1 is out of bounds, reverse direction:
 94      if ( ( new_x < r.x ) || ( new_x + w > r.x + r.width ) )  dx1 *= -1;
 95      if ( ( new_y < r.y ) || ( new_y + h > r.y + r.height ) )  dy1 *= -1;
 96  
 97    }
 98  
 99    private void checkBounds2( java.awt.Rectangle r ) {
100  
101      // Get the bounding box of square2:
102      java.awt.Rectangle bb = square2.getBounds();
103  
104      // Compute the dimensions of square2:
105      int w = bb.width, h = bb.height;
106      int new_x = bb.x + dx2, new_y = bb.y + dy2;
107      
108      // If square2 is out of bounds, reverse direction:
109      if ( ( new_x < r.x ) || ( new_x + w > r.x + r.width ) )  dx2 *= -1;
110      if ( ( new_y < r.y ) || ( new_y + h > r.y + r.height ) )  dy2 *= -1;
111  
112    }
113  
114  }