1  /*
  2   *  File:  mInnerApplet.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 mInnerApplet extends Applet {
 17                            
 18    // Instance variables:
 19    /* private */ int numObj = 3;   // number of movable objects
 20    /* private */ mPoint 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 mPoint[ numObj ];
 42  
 43      // Instantiate a rectangle:
 44      object[0] = new mRectangle( 10, 10, 100, 100 );
 45      object[0].setColor( objColor );
 46  
 47      // Instantiate a circle:
 48      object[1] = new mOval( 200, 10, 100, 100 );
 49      object[1].setColor( objColor );
 50  
 51      // Instantiate a triangle:
 52      object[2] = new mTriangle( 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":
 87    class MouseMotionHandler extends MouseMotionAdapter {
 88  
 89      public void mouseMoved( MouseEvent e ) {
 90        // Determine which object contains the cursor (if any):
 91        hit = -1;
 92        for ( int i = 0; i < numObj; i++ ) {
 93          if ( object[i].isInside( e.getX(), e.getY() ) ) {
 94            hit = i;
 95            break;
 96          }
 97        }
 98        // Color all objects:
 99        Color color;
100        for ( int i = 0; i < numObj; i++ ) {
101          color = ( i == hit ) ? objColorSelect : objColor;
102          object[i].setColor( color );
103        }
104        repaint();
105      }
106    
107      public void mouseDragged( MouseEvent e ) {
108        if ( current != -1 ) {
109          int x = e.getX() + xoffset;
110          int y = e.getY() + yoffset;
111          object[ current ].setPoint( x, y );
112          repaint();
113        }
114      }
115      
116    }
117  
118    // Override java.awt.Component.update:
119    public void update( Graphics g ) {
120      // Fill background:
121      gOffScreen.setColor( getBackground() );
122      gOffScreen.fillRect( 1, 1, getSize().width - 2, getSize().height - 2 );
123      // Draw boundary:
124      gOffScreen.setColor( getForeground() );
125      gOffScreen.drawRect( 0, 0, getSize().width - 1, getSize().height - 1 );
126      paint( gOffScreen );
127      
128      // Draw the buffer in the applet window:
129      g.drawImage( buffer, 0, 0, this );
130    }
131    
132    // Override java.awt.Component.paint:
133    public void paint( Graphics g ) {
134      // Paint each object:
135      for ( int i = 0; i < numObj; i++ )
136        object[i].paint(g);
137    }
138  
139  }
140