Template pattern in Java
/* The Design Patterns Java Companion Copyright (C) 1998, by James W. Cooper IBM Thomas J. Watson Research Center */ import java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Vector; import javax.swing.JFrame; import javax.swing.JPanel; public class TriangleDrawing extends JFrame { stdTriangle t, t1; IsocelesTriangle it; public TriangleDrawing() { super("Draw triangles"); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); TPanel tp = new TPanel(); t = new stdTriangle(new Point(10, 10), new Point(150, 50), new Point( 100, 75)); it = new IsocelesTriangle(new Point(150, 100), new Point(240, 40), new Point(175, 150)); t1 = new stdTriangle(new Point(150, 100), new Point(240, 40), new Point(175, 150)); tp.addTriangle(t); tp.addTriangle(it); // tp.addTriangle(t1); getContentPane().add(tp); setSize(300, 200); setBackground(Color.white); setVisible(true); } public static void main(String[] arg) { new TriangleDrawing(); } } class TPanel extends JPanel { Vector triangles; public TPanel() { triangles = new Vector(); } public void addTriangle(Triangle t) { triangles.addElement(t); } public void paint(Graphics g) { for (int i = 0; i < triangles.size(); i++) { Triangle tngl = (Triangle) triangles.elementAt(i); tngl.draw(g); } } } abstract class Triangle { Point p1, p2, p3; public Triangle(Point a, Point b, Point c) { //save p1 = a; p2 = b; p3 = c; } public void draw(Graphics g) { //This routine draws a general triangle drawLine(g, p1, p2); Point current = draw2ndLine(g, p2, p3); closeTriangle(g, current); } public void drawLine(Graphics g, Point a, Point b) { g.drawLine(a.x, a.y, b.x, b.y); } //this routine is the "Hook" that has to be implemented //for each triangle type. abstract public Point draw2ndLine(Graphics g, Point a, Point b); public void closeTriangle(Graphics g, Point c) { //draw back to first point g.drawLine(c.x, c.y, p1.x, p1.y); } } class stdTriangle extends Triangle { public stdTriangle(Point a, Point b, Point c) { super(a, b, c); } public Point draw2ndLine(Graphics g, Point a, Point b) { g.drawLine(a.x, a.y, b.x, b.y); return b; } } class IsocelesTriangle extends Triangle { Point newc; int newcx, newcy; int incr; public IsocelesTriangle(Point a, Point b, Point c) { super(a, b, c); double dx1 = b.x - a.x; double dy1 = b.y - a.y; double dx2 = c.x - b.x; double dy2 = c.y - b.y; double side1 = calcSide(dx1, dy1); double side2 = calcSide(dx2, dy2); if (side2 < side1) incr = -1; else incr = 1; double slope = dy2 / dx2; double intercept = c.y - slope * c.x; //move point c so that this is an isoceles triangle newcx = c.x; newcy = c.y; while (Math.abs(side1 - side2) > 1) { newcx += incr; //iterate a pixel at a time until close newcy = (int) (slope * newcx + intercept); dx2 = newcx - b.x; dy2 = newcy - b.y; side2 = calcSide(dx2, dy2); } newc = new Point(newcx, newcy); } //calculate length of side private double calcSide(double dx, double dy) { return Math.sqrt(dx * dx + dy * dy); } //draws 2nd line using saved new point public Point draw2ndLine(Graphics g, Point b, Point c) { g.drawLine(b.x, b.y, newc.x, newc.y); return newc; } }
1. | Template Method Pattern |