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