Source code: com/port80/graph/impl/ShapeFactory.java
1 //
2 // Copyright(c) 2002, Chris Leung
3 //
4
5 package com.port80.graph.impl;
6
7 import java.util.*;
8 import java.awt.*;
9 import java.awt.geom.*;
10 import com.port80.util.*;
11 import com.port80.util.attr.*;
12 import com.port80.graph.*;
13
14 /** Shape attribute factory.
15 *
16 */
17 public class ShapeFactory implements IAttrFactory {
18
19 ////////////////////////////////////////////////////////////////////////
20
21 private static final String NAME = "ShapeFactory";
22 private static ShapeFactory instance = null;
23
24 private static final int NONE = 0;
25 private static final int LINE = 1;
26 private static final int TRIANGLE = 2;
27 private static final int SQUARE = 3;
28 private static final int BOX = 4;
29 private static final int ROUNDEDBOX = 5;
30 private static final int RECORD = 6;
31 private static final int DIAMOND = 7;
32 private static final int PENTAGON = 8;
33 private static final int HEXAGON = 9;
34 private static final int OCTAGON = 10;
35 private static final int PARALLELOGRAM = 11;
36 private static final int TRAPEZIUM = 12;
37 private static final int POLYGON = 13;
38 private static final int CIRCLE = 14;
39 private static final int EGG = 15;
40 private static final int OVAL = 16;
41 private static final int HOUSE = 17;
42 private static final int PLAINTEXT = 18;
43 //
44 private static final int MSQUARE = 19;
45 private static final int MRECORD = 20;
46 private static final int MDIAMOND = 21;
47 private static final int MCIRCLE = 22;
48 //
49 private static final int INVERTEDHOUSE = 23;
50 private static final int INVERTEDTRAPEZIUM = 24;
51 private static final int INVERTEDTRIANGLE = 25;
52 //
53 private static final int DOUBLECIRCLE = 26;
54 private static final int DOUBLEOCTAGON = 27;
55 private static final int TRIPLEOCTAGON = 28;
56 private static final int CUSTOM = 29;
57
58 private static final String[] nameTable = {
59 "none",
60 "line",
61 "triangle",
62 "square",
63 "box",
64 "roundedbox",
65 "record",
66 "diamond",
67 "pentagon",
68 "hexagon",
69 "octagon",
70 "parallelogram",
71 "trapezium",
72 "polygon",
73 "circle",
74 "egg",
75 "oval",
76 "house",
77 "plaintext",
78 //
79 "msquare",
80 "mrecord",
81 "mdiamond",
82 "mcircle",
83 //
84 "invertedhouse",
85 "invertedtrapezium",
86 "invertedtriangle",
87 //
88 "doublecircle",
89 "doubleoctagon",
90 "tripleoctagon",
91 "custom",
92 };
93 private static Map table;
94 static {
95 table = new HashMap();
96 table.put("none", null);
97 table.put("line", null);
98 table.put("triangle", new GraphShape("triangle", stockTriangle()));
99 table.put("square", new GraphShape("square", stockSquare()));
100 table.put("box", new GraphShape("box", stockRectangle()));
101 table.put("roundedbox", null);
102 table.put("record", null);
103 table.put("diamond", null);
104 table.put("pentagon", null);
105 table.put("hexagon", null);
106 table.put("octagon", null);
107 table.put("parallelogram", null);
108 table.put("trapezium", null);
109 table.put("polygon", null);
110 table.put("circle", new GraphShape("circle", stockCircle()));
111 table.put("egg", null);
112 table.put("oval", new GraphShape("oval", stockEllipse()));
113 table.put("house", null);
114 table.put("plaintext", null);
115 //
116 table.put("msquare", null);
117 table.put("mrecord", null);
118 table.put("mdiamond", null);
119 table.put("mcircle", null);
120 //
121 table.put("invertedhouse", null);
122 table.put("invertedtrapezium", null);
123 table.put("invertedtriangle", null);
124 //
125 table.put("doublecircle", null);
126 table.put("doubleoctagon", null);
127 table.put("tripleoctagon", null);
128 table.put("custom", null);
129 }
130
131 ////////////////////////////////////////////////////////////////////////
132
133 /** @return The singleton instance of the factory. */
134 public static ShapeFactory getInstance() {
135 if (instance == null) instance = new ShapeFactory();
136 return instance;
137 }
138
139 /** @return An instance of the specified shape with affinetransform applied. */
140 public static IGraphShape create(String stringvalue) {
141 if (instance == null) instance = new ShapeFactory();
142 return (IGraphShape)instance.createObject(stringvalue);
143 }
144
145 private ShapeFactory() {}
146
147 // Stock shapes ////////////////////////////////////////////////////////
148 //
149 // These stock shapes are scaled and positioned to make drawing of
150 // vertex label easier.
151 //
152 // . Client rectangle for the text lable is a unit square. The
153 // shape would be scaled later such that the label text fit into
154 // the client rectangle.
155 // . Origin (0,0) is always at the center of the client rectangle.
156
157 /** A triangle that enclose a unit square. */
158 private static IGraphShape stockTriangle() {
159 GeneralPath p = new GeneralPath();
160 double tan60 = Math.tan(Math.PI / 3);
161 double hw = 0.5f + 1 / tan60; // half width.
162 double h = 1.0f + tan60 / 2; // height.
163 p.moveTo((float) - hw, 0.5f);
164 p.lineTo((float)hw, 0.5f);
165 p.lineTo(0f, (float) - (h - 0.5f));
166 p.closePath();
167 return new GraphShape("stockTriangle",
168 p,
169 new Rectangle2D.Double( -0.5, -0.5, 1.0, 1.0),
170 false
171 );
172 }
173
174 /** A unit square. */
175 private static IGraphShape stockSquare() {
176 return new GraphShape("stockSquare",
177 new Rectangle2D.Double( -0.5, -0.5, 1.0, 1.0),
178 new Rectangle2D.Double( -0.5, -0.5, 1.0, 1.0),
179 true
180 );
181 }
182
183 /** A rectangle. */
184 private static IGraphShape stockRectangle() {
185 return new GraphShape("stockRectangle",
186 new Rectangle2D.Double( -0.5, -0.5, 1.0, 1.0),
187 new Rectangle2D.Double( -0.5, -0.5, 1.0, 1.0),
188 false
189 );
190 }
191
192 /** A circle. */
193 private static IGraphShape stockCircle() {
194 double radius = Math.sqrt(2) / 2;
195 return new GraphShape("stockCircle",
196 new Ellipse2D.Double( -radius, -radius, 2*radius, 2*radius),
197 new Rectangle2D.Double( -0.5, -0.5, 1.0, 1.0),
198 true
199 );
200 }
201
202 /** An ellipse. */
203 private static IGraphShape stockEllipse() {
204 double radius = Math.sqrt(2) / 2;
205 return new GraphShape("stockEllipse",
206 new Ellipse2D.Double( -radius, -radius, 2*radius, 2*radius),
207 new Rectangle2D.Double( -0.5, -0.5, 1.0, 1.0),
208 false
209 );
210 }
211
212 ////////////////////////////////////////////////////////////////////////
213 //
214
215 /** Get a reference to the stock shape without cloning. */
216 public IGraphShape getStock(String name) {
217 return (IGraphShape)((IGraphShape)table.get(name));
218 }
219
220 // IAttrFactory interface //////////////////////////////////////////////
221 //
222
223 /** Create an instance of the specified shape.
224 */
225 public Object createObject(String attrvalue) {
226 return ((IGraphShape)table.get(attrvalue)).clone();
227 }
228
229 public boolean isValid(Object a) {
230 return (a instanceof IGraphShape);
231 }
232
233 /** The String representation of an attribute value. */
234 public String toString(Object attr) {
235 return ((IGraphShape)attr).getName();
236 }
237
238 /** The String representation of attribute type itself. */
239 public String toString() {
240 return NAME;
241 }
242
243 /** Prompt user and present a user interface to obtain an
244 * attribute value from user. */
245 public Object promptUser(String prompt) {
246 return null;
247 }
248
249 ////////////////////////////////////////////////////////////////////////
250 }
251