/** MVCFramework.java -- standalone application demonstrating MVC (V2) */ import java.awt.*; import java.util.*; // The Shape classes, representing the "Model" abstract class Shape { public int centerX; public int centerY; Shape(int x, int y) { centerX = x; centerY = y; } // shapes know if a point is inside them or not abstract boolean inside(int x, int y); // shapes respond to draw methods through multiple polymorphism abstract void draw(View v, Graphics g); } class Rect extends Shape { public int width; public int height; Rect(int x, int y, int w, int h) { super(x, y); width = w; height = h; } public boolean inside(int x, int y) { return (x > centerX-width/2 && x < centerX+width/2 && y > centerY-height/2 && y < centerY+height/2); } // responds to draw operation calling the specific draw routine void draw(View v, Graphics g) { v.draw((Rect)this, g); } } class Circle extends Shape { public int radius; Circle(int x, int y, int r) { super(x, y); radius = r; } public boolean inside(int x, int y) { float xdist = x - centerX; float ydist = y - centerY; return Math.sqrt(xdist*xdist + ydist*ydist) < radius; } void draw(View v, Graphics g) { v.draw((Circle)this, g); } } class ShapeCanvas extends Canvas { private MVCFramework parent; public ShapeCanvas(MVCFramework p) { parent = p; } public boolean mouseDown(Event e, int x, int y) { parent.mousePressed(x, y); return true; } } // The standard shape Controller. Event handling is implemented here. class Controller { protected Shape shape; protected View view; Controller(Shape s, View v) { shape = s; view = v; } void pick(int x, int y) { view.toggleSelect(); } } // The standard shape View. Drawing operations are implemented here. abstract class View { private Shape shape; protected boolean selected; View(Shape s) { shape = s; } void toggleSelect() { selected = !selected; } // call the draw on the shape, passing 'this' as a parameter void draw(Graphics g) { shape.draw(this, g); } // shapes' draw methods call back the specific draw routine abstract void draw(Rect r, Graphics g); abstract void draw(Circle c, Graphics g); } class DisplayView extends View { DisplayView(Shape s) { super(s); } // implement the specific draw routines for the display view void draw(Rect r, Graphics g) { if (selected) g.fillRect(r.centerX-r.width/2, r.centerY-r.height/2, r.width, r.height); else g.drawRect(r.centerX-r.width/2, r.centerY-r.height/2, r.width, r.height); } void draw(Circle c, Graphics g) { if (selected) g.fillOval(c.centerX-c.radius, c.centerY-c.radius,2*c.radius,2*c.radius); else g.drawOval(c.centerX-c.radius, c.centerY-c.radius,2*c.radius,2*c.radius); } } // The AWT "Frame"work abstract class MVCFramework extends Frame { private Canvas canvas; private Vector shapes; // list of Shapes private Vector views; // list of Views private Hashtable controllers; // table of Controllers public MVCFramework() { // create the Frame with title. super("MVC Demo"); // Add a menubar, with a File menu, with a Quit button. MenuBar menubar = new MenuBar(); Menu file = new Menu("File", true); menubar.add(file); file.add("Quit"); file.add("Refresh"); setMenuBar(menubar); // make the Canvas and shape list canvas = new ShapeCanvas(this); shapes = new Vector(); views = new Vector(); controllers = new Hashtable(); add("Center", canvas); resize(300, 300); startup(); // pop up window show(); draw(); } // redraw entire screen void draw() { canvas.getGraphics().clearRect(0, 0, 300, 300); for (int i=0; i