1  /*
  2   *  File:  DrawCanvas.java
  3   *
  4   *  DrawCanvas class, a subclass of java.awt.Canvas
  5   *
  6   *  Copyright:  Northeast Parallel Architectures Center
  7   *  
  8   */
  9  
 10  import java.awt.*;
 11  import java.awt.event.*;
 12  
 13  public class DrawCanvas extends Canvas {
 14  
 15    // Note:  All instance variables should be private in this
 16    // case, but a longstanding bug with respect to inner classes in
 17    // Java 1.1 prevents this.  (See page 103 of the "Tiger" book.) 
 18    
 19    // Instance variables:
 20    String tools[] = { "Rectangle", "RoundRect", "Oval", "Line" };
 21    String tool = tools[0];
 22    boolean fill = true;
 23    int numObj = 0;
 24    DrawableObject curObj;
 25    final int maxObj = 100;  // maximum number of objects
 26    DrawableObject objList[] = new DrawableObject[ maxObj ];
 27    Graphics g;
 28  
 29    // Accessors and mutators:
 30    public void setMode( String new_mode ) {
 31      tool = new_mode;
 32    }
 33    public void setFill( boolean new_fill ) {
 34      fill = new_fill;
 35    }
 36    public int getNumObj() { return numObj; }
 37    public String getTool() { return tool; }
 38    public String[] getTools() { return tools; }
 39  
 40    // Constructor:
 41    public DrawCanvas() {
 42      
 43      setBackground(Color.blue);  // default canvas color
 44      
 45      // The following class, a type of inner class called a 
 46      // "local class", is a subclass of MouseAdapter.  Only 
 47      // two methods from the MouseAdapter class are being 
 48      // overridden:
 49      class MouseHandler extends MouseAdapter {
 50      
 51        public void mousePressed( MouseEvent e ) {
 52          int x = e.getX();
 53          int y = e.getY();
 54          
 55          if ( tool.equals( "Line" ) ) 
 56            curObj = new DrawableLine( x, y, x, y );
 57          else if ( tool.equals( "Rectangle" ) ) 
 58            curObj = new DrawableRectangle( x, y, x, y );
 59          else if ( tool.equals( "RoundRect" ) ) 
 60            curObj = new DrawableRoundRect( x, y, x, y );
 61          else if ( tool.equals( "Oval" ) ) 
 62            curObj = new DrawableOval( x, y, x, y );
 63          // else throw an exception
 64          
 65          // Set draw mode for rubberbanding:
 66          curObj.setFill( false );
 67        }
 68  
 69        public void mouseReleased( MouseEvent e ) {
 70          g = getGraphics();
 71          
 72          // Since XOR mode is still in effect, the following
 73          // statement will erase the current object:
 74          curObj.paint(g);
 75          
 76          int X = e.getX(), Y = e.getY();
 77          // Ignore a degenerate object (i.e., a point):
 78          if ( !( X == curObj.getX() && Y == curObj.getY() ) ) {
 79            // Turn XOR mode off and paint the final object:
 80            g.setPaintMode();
 81            curObj.setEndpoint( X, Y );
 82            curObj.setFill( fill );
 83            curObj.paint(g);
 84            // Save the first maxObj number of objects:
 85            if ( numObj < maxObj )
 86              objList[ numObj++ ] = curObj;
 87          }
 88        }
 89        
 90      }  // end class MouseHandler
 91      
 92      // This local class overrides a method from the 
 93      // MouseMotionAdapter class:
 94      class MouseMotionHandler extends MouseMotionAdapter {
 95      
 96        public void mouseDragged( MouseEvent e ) {
 97          g = getGraphics();
 98          
 99          // Erase the current object:
100          g.setXORMode( Color.white );
101          curObj.paint(g);
102          
103          // Paint a new object:
104          curObj.setEndpoint( e.getX(), e.getY() );
105          curObj.paint(g);
106        }
107        
108      }  // end class MouseMotionHandler
109      
110      // Listen for MouseEvents:
111      addMouseListener( new MouseHandler() );
112      addMouseMotionListener( new MouseMotionHandler() );
113  
114    }  // end DrawCanvas constructor
115    
116    public void clear() {
117      numObj = 0;
118      repaint();
119    }
120  
121    // Override Canvas paint method:
122    public void paint( Graphics g ) {
123      for ( int i = 0; i < numObj; i++ ) {
124        objList[i].paint(g);
125      }
126    }
127    
128  }  // end class DrawCanvas