1  /*
  2   *  MouseEvents2.java
  3   *
  4   *  MouseEvents, movable objects, and inner classes
  5   *
  6   *  Note: The private modifier was removed from some of the
  7   *        variables so that the inner classes have access.  
  8   *        Evidently this is a longstanding bug in JDK 1.1
  9   *        (see page 103 of the tiger book).
 10   */
 11  
 12  import java.applet.*;
 13  import java.awt.*;
 14  import java.awt.event.*;
 15  
 16  public class MouseEvents2 extends Applet {
 17                            
 18    // Instance variables:
 19    /* private */ int numObj = 3;   // number of movable objects
 20    /* private */ MovableObject object[];  // array of movable objects
 21    private Image buffer;           // image object for double buffering
 22    private Graphics gOffScreen;    // graphics object for double buffering
 23    
 24    // Mouse handling variables:
 25    /* private */ int current = -1;
 26    /* private */ int hit = -1;
 27    /* private */ int xoffset = 0;
 28    /* private */ int yoffset = 0;
 29    
 30    // Colors:
 31    /* private */ Color objColor = Color.cyan;
 32    /* private */ Color objColorSelect = Color.red;
 33    private Color bgColor = Color.black;
 34    private Color fgColor = Color.white;
 35  
 36    public void init() {
 37      setBackground( bgColor );
 38      setForeground( fgColor );
 39  
 40      // Instantiate object array:
 41      object = new MovableObject[ numObj ];
 42  
 43      // Instantiate a rectangle:
 44      object[0] = new MovableRectangle( 10, 10, 100, 100 );
 45      object[0].setColor( objColor );
 46  
 47      // Instantiate a circle:
 48      object[1] = new MovableOval( 200, 10, 100, 100 );
 49      object[1].setColor( objColor );
 50  
 51      // Instantiate a triangle:
 52      object[2] = new MovableTriangle( 10, 200, 100, 100 );
 53      object[2].setColor( objColor );
 54  
 55      // Create an off-screen image for double buffering:
 56      buffer = createImage( getSize().width, getSize().height );
 57      // Get off-screen graphics context:
 58      gOffScreen = buffer.getGraphics(); 
 59  
 60      // Register the applet to listen for MouseEvents via
 61      // an inner class (defined below):
 62      this.addMouseMotionListener( new MouseMotionHandler() );
 63      
 64      // Register the applet to listen for MouseEvents via
 65      // an *anonymous* inner class:
 66      this.addMouseListener(
 67        new MouseAdapter() {
 68    
 69          public void mousePressed( MouseEvent e ) {
 70            current = hit;
 71            if ( current != -1 ) {
 72              xoffset = object[ current ].getX() - e.getX();
 73              yoffset = object[ current ].getY() - e.getY();
 74            }
 75          }
 76        
 77          public void mouseReleased( MouseEvent e ) {
 78            current = -1;
 79          }
 80          
 81        }
 82      );
 83    
 84    }  // end method init()
 85    
 86    // A type of inner class called a "member class" (if it were
 87    // defined *inside* init(), it would be called a "local class"):
 88    class MouseMotionHandler extends MouseMotionAdapter {
 89  
 90      public void mouseMoved( MouseEvent e ) {
 91        // Determine which object contains the cursor (if any):
 92        hit = -1;
 93        for ( int i = 0; i < numObj; i++ ) {
 94          if ( object[i].contains( e.getX(), e.getY() ) ) {
 95            hit = i;
 96            break;
 97          }
 98        }
 99        // Color all objects:
100        Color color;
101        for ( int i = 0; i < numObj; i++ ) {
102          color = ( i == hit ) ? objColorSelect : objColor;
103          object[i].setColor( color );
104        }
105        repaint();
106      }
107    
108      public void mouseDragged( MouseEvent e ) {
109        if ( current != -1 ) {
110          int x = e.getX() + xoffset;
111          int y = e.getY() + yoffset;
112          object[ current ].setLocation( x, y );
113          repaint();
114        }
115      }
116      
117    }
118  
119    // Override java.awt.Component.update:
120    public void update( Graphics g ) {
121      // Fill background:
122      gOffScreen.setColor( getBackground() );
123      gOffScreen.fillRect( 1, 1, getSize().width - 2, getSize().height - 2 );
124      // Draw boundary:
125      gOffScreen.setColor( getForeground() );
126      gOffScreen.drawRect( 0, 0, getSize().width - 1, getSize().height - 1 );
127      paint( gOffScreen );
128      
129      // Draw the buffer in the applet window:
130      g.drawImage( buffer, 0, 0, this );
131    }
132    
133    // Override java.awt.Component.paint:
134    public void paint( Graphics g ) {
135      // Paint each object:
136      for ( int i = 0; i < numObj; i++ )
137        object[i].paint(g);
138    }
139  
140  }
141