1
28 package demo.view.realizer;
29
30
31 import java.awt.Color;
32 import java.awt.Graphics2D;
33 import java.awt.Stroke;
34 import java.awt.geom.GeneralPath;
35 import java.io.IOException;
36 import java.io.ObjectInputStream;
37 import java.io.ObjectOutputStream;
38
39 import y.util.YVersion;
40 import y.view.LineType;
41 import y.view.NodeRealizer;
42 import y.view.ShapeNodeRealizer;
43 import y.io.graphml.graph2d.ShapeNodeRealizerSerializer;
44 import y.io.graphml.input.GraphMLParseContext;
45 import y.io.graphml.input.GraphMLParseException;
46 import y.io.graphml.output.XmlWriter;
47 import y.io.graphml.output.GraphMLWriteContext;
48 import org.w3c.dom.Node;
49 import org.w3c.dom.Element;
50
51
60 public class StateNodeRealizer extends ShapeNodeRealizer
61 {
62
66 public static final byte INITIAL_STATE = 0;
67
68
72 public static final byte TRANSITION_STATE = 1;
73
74
78 public static final byte FINAL_STATE = 2;
79
80
81 private byte state;
82
83
87 public StateNodeRealizer(byte state)
88 {
89 super();
90 this.state = state;
91 this.setShapeType(ELLIPSE);
92 }
93
94
97 public StateNodeRealizer()
98 {
99 this(INITIAL_STATE);
100 }
101
102
106 public StateNodeRealizer(NodeRealizer r)
107 {
108 super(r);
109 if(r instanceof StateNodeRealizer)
110 {
111 StateNodeRealizer sr = (StateNodeRealizer)r;
112 state = sr.state;
113 }
114 else
115 {
116 state = INITIAL_STATE;
117 }
118 }
119
120
125 public void setState(byte state)
126 {
127 this.state = state;
128 }
129
130
135 public byte getState()
136 {
137 return this.state;
138 }
139
140
141
146 public void paintNode(Graphics2D gfx)
147 {
148 super.paintNode(gfx);
150
151 if(getState() != INITIAL_STATE)
152 {
153 Stroke oldStroke = gfx.getStroke();
156 Color oldColor = gfx.getColor();
157 if(state == TRANSITION_STATE) {
158 gfx.setStroke(LineType.DASHED_1);
159 } else if(getState() == FINAL_STATE) {
160 gfx.setStroke(LineType.LINE_1);
161 }
162 double oldWidth = getWidth();
163 double oldHeight = getHeight();
164 if(oldWidth > 10.0 && oldHeight > 10.0)
165 {
166 setSize(oldWidth- 10.0,oldHeight- 10.0);
167 gfx.draw(shape);
168 setSize(oldWidth,oldHeight);
169 }
170
171 gfx.setColor(oldColor);
172 gfx.setStroke(oldStroke);
173 }
174 }
175
176
187 public NodeRealizer createCopy(NodeRealizer r)
188 {
189 return new StateNodeRealizer(r);
190 }
191
192
195 public static final byte CUSTOM_SHAPE = -1;
196
197
200 public void setShapeType(byte type)
201 {
202 if(type == CUSTOM_SHAPE)
203 {
204 updateCustomShape();
205 }
206 super.setShapeType(type);
207 }
208
209 void updateCustomShape()
210 {
211 GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD,5);
212 float x = (float)getX();
213 float y = (float)getY();
214 float w = (float)getWidth();
215 float h = (float)getHeight();
216 path.moveTo(x, y + h);
217 path.lineTo(x, y);
218 float dx = Math.min(h*0.2f,w);
219 path.lineTo(x+w-dx,y);
220 path.lineTo(x+w,y+0.5f*h);
221 path.lineTo(x+w-dx,y+h);
222 path.closePath();
223 shape = path;
224 }
225
226
229 public void setSize(double x, double y)
230 {
231 if(getShapeType() == CUSTOM_SHAPE)
232 {
233 shape = null;
234 super.setSize(x,y);
235 updateCustomShape();
236 }
237 else
238 {
239 super.setSize(x,y);
240 }
241 }
242
243
244
251 public void write(ObjectOutputStream out) throws IOException
252 {
253 out.writeByte(YVersion.VERSION_1);
257 super.write(out);
259 out.writeByte(state);
261 }
262
263
271 public void read(ObjectInputStream in) throws IOException,
272 ClassNotFoundException
273 {
274 switch(in.readByte()) {
275 case YVersion.VERSION_1:
276 super.read(in);
277 state = in.readByte();
278 break;
279 default:
280 }
282 }
283
284
288 static class StateNodeRealizerSerializer extends ShapeNodeRealizerSerializer {
289 public String getName() {
290 return "StateNode";
291 }
292
293 public String getNamespaceURI() {
294 return "demo.view.realizer";
295 }
296
297 public Class getRealizerClass() {
298 return StateNodeRealizer.class;
299 }
300
301 public void parse(NodeRealizer realizer, Node domNode, GraphMLParseContext context) throws GraphMLParseException {
302 super.parse(realizer, domNode, context);
303 StateNodeRealizer snr = (StateNodeRealizer) realizer;
304 String state = ((Element) domNode).getAttribute("state");
305
306 if("initial".equals(state)) {
307 snr.setState(INITIAL_STATE);
308 }
309 else if("transition".equals(state)) {
310 snr.setState(TRANSITION_STATE);
311 }
312 else if("final".equals(state)) {
313 snr.setState(FINAL_STATE);
314 }
315 }
316
317
318 protected byte decodeShapeType(String s, GraphMLParseContext context) {
319 if("custom".equals(s)) {
320 return CUSTOM_SHAPE;
321 }
322 return super.decodeShapeType(s, context);
323 }
324
325 protected String encodeShapeType(ShapeNodeRealizer snr, GraphMLWriteContext context) {
326 if(snr.getShapeType() == CUSTOM_SHAPE) {
327 return "custom";
328 }
329 return super.encodeShapeType(snr, context);
330 }
331
332 public void writeAttributes(NodeRealizer nr, XmlWriter writer, GraphMLWriteContext context) {
333 super.writeAttributes(nr, writer, context);
334 StateNodeRealizer snr = (StateNodeRealizer) nr;
335 switch(snr.getState()) {
336 case INITIAL_STATE:
337 writer.writeAttribute("state", "initial");
338 break;
339 case TRANSITION_STATE:
340 writer.writeAttribute("state", "transition");
341 break;
342 case FINAL_STATE:
343 writer.writeAttribute("state", "final");
344 break;
345 }
346 }
347 }
348 }
349
350