| StateNodeRealizer.java |
1 /****************************************************************************
2 **
3 ** This file is part of yFiles-2.6.
4 **
5 ** yWorks proprietary/confidential. Use is subject to license terms.
6 **
7 ** Redistribution of this file or of an unauthorized byte-code version
8 ** of this file is strictly forbidden.
9 **
10 ** Copyright (c) 2000-2008 by yWorks GmbH, Vor dem Kreuzberg 28,
11 ** 72070 Tuebingen, Germany. All rights reserved.
12 **
13 ***************************************************************************/
14 package demo.view.realizer;
15
16
17 import java.awt.Color;
18 import java.awt.Graphics2D;
19 import java.awt.Stroke;
20 import java.awt.geom.GeneralPath;
21 import java.io.IOException;
22 import java.io.ObjectInputStream;
23 import java.io.ObjectOutputStream;
24
25 import y.util.YVersion;
26 import y.view.LineType;
27 import y.view.NodeRealizer;
28 import y.view.ShapeNodeRealizer;
29
30 /**
31 * This class represents a custom NodeRealizer with its own paint,
32 * copy and serialisation routines.
33 * <br>
34 * This realizer will be used in the demo
35 * {@link demo.view.realizer.StateNodeRealizerDemo}.
36 */
37 public class StateNodeRealizer extends ShapeNodeRealizer
38 {
39 /**
40 * State specifier constant. A node with this state will be drawn
41 * like an ordinary ShapeNodeRealizer.
42 */
43 public final static byte INITIAL_STATE = 0;
44
45 /**
46 * State specifier constant. A node with this state will be drawn
47 * with an additional dashed line.
48 */
49 public final static byte TRANSITION_STATE = 1;
50
51 /**
52 * State specifier constant. A node with this state will be drawn
53 * with an additional solid line.
54 */
55 public final static byte FINAL_STATE = 2;
56
57
58 private byte state;
59
60 /**
61 * Instantiates a new StateNodeRealizer with the given state.
62 * @see #setState(byte)
63 */
64 public StateNodeRealizer(byte state)
65 {
66 super();
67 this.state = state;
68 this.setShapeType(ELLIPSE);
69 }
70
71 /**
72 * Instantiates a new StateNodeRealizer.
73 */
74 public StateNodeRealizer()
75 {
76 this(INITIAL_STATE);
77 }
78
79 /**
80 * Instantiates a new StateNodeRealizer as a copy of
81 * the given NodeRealizer.
82 */
83 public StateNodeRealizer(NodeRealizer r)
84 {
85 super(r);
86 if(r instanceof StateNodeRealizer)
87 {
88 StateNodeRealizer sr = (StateNodeRealizer)r;
89 state = sr.state;
90 }
91 else
92 {
93 state = INITIAL_STATE;
94 }
95 }
96
97 /**
98 * Sets the state of this realizer.
99 * @param state on of {@link #INITIAL_STATE}, {@link #TRANSITION_STATE}
100 * or {@link #FINAL_STATE}.
101 */
102 public void setState(byte state)
103 {
104 this.state = state;
105 }
106
107 /**
108 * Returns the state of this realizer.
109 * By default {@link #INITIAL_STATE} will be returned.
110 * @see #setState(byte)
111 */
112 public byte getState()
113 {
114 return this.state;
115 }
116
117
118 /**
119 * Paints the node on the given graphics context.
120 * Depending on the state of the realizer the node will be
121 * drawn differently
122 */
123 public void paintNode(Graphics2D gfx)
124 {
125 //first paint the shape node realzier
126 super.paintNode(gfx);
127
128 if(getState() != INITIAL_STATE)
129 {
130 //then draw an additional state marker
131 //on top of the node.
132 Stroke oldStroke = gfx.getStroke();
133 Color oldColor = gfx.getColor();
134 if(state == TRANSITION_STATE)
135 gfx.setStroke(LineType.DASHED_1);
136 else if(getState() == FINAL_STATE)
137 gfx.setStroke(LineType.LINE_1);
138 double oldWidth = getWidth();
139 double oldHeight = getHeight();
140 if(oldWidth > 10 && oldHeight > 10)
141 {
142 setSize(oldWidth-10,oldHeight-10);
143 gfx.draw(shape);
144 setSize(oldWidth,oldHeight);
145 }
146
147 gfx.setColor(oldColor);
148 gfx.setStroke(oldStroke);
149 }
150 }
151
152 /**
153 * Creates a copy of the given realizer that has type
154 * StateNodeRealizer. It is important to implement this method properly
155 * if the realizer should be able to act as a template for
156 * other realizers, e.g. if it is used as default ndoe realizer
157 * in a Graph2D.
158 * The canonic way to implement this method is to return the result
159 * of a copy constructor.
160 * @see y.view.Graph2D#setDefaultNodeRealizer(y.view.NodeRealizer)
161 * @see #StateNodeRealizer(NodeRealizer)
162 */
163 public NodeRealizer createCopy(NodeRealizer r)
164 {
165 return new StateNodeRealizer(r);
166 }
167
168 /**
169 * A custom shape type specifier.
170 */
171 public final static byte CUSTOM_SHAPE = -1;
172
173 /**
174 * Demonstrates how to define custom shapes.
175 */
176 public void setShapeType(byte type)
177 {
178 if(type == CUSTOM_SHAPE)
179 {
180 updateCustomShape();
181 }
182 super.setShapeType(type);
183 }
184
185 void updateCustomShape()
186 {
187 GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD,5);
188 float x = (float)getX();
189 float y = (float)getY();
190 float w = (float)getWidth();
191 float h = (float)getHeight();
192 path.moveTo(x, y + h);
193 path.lineTo(x, y);
194 float dx = Math.min(h*0.2f,w);
195 path.lineTo(x+w-dx,y);
196 path.lineTo(x+w,y+0.5f*h);
197 path.lineTo(x+w-dx,y+h);
198 path.closePath();
199 shape = path;
200 }
201
202 /**
203 * adjust custom shape when size changes. Overrides default scaling operation.
204 */
205 public void setSize(double x, double y)
206 {
207 if(getShapeType() == CUSTOM_SHAPE)
208 {
209 shape = null;
210 super.setSize(x,y);
211 updateCustomShape();
212 }
213 else
214 {
215 super.setSize(x,y);
216 }
217 }
218
219
220 /**
221 * Writes out this realizer in a serialized form. This method
222 * will be used by YGFIOHandler to serialize this NodeRealizer.
223 */
224 public void write(ObjectOutputStream out) throws IOException
225 {
226 //write out a version tag. version tags help to provide future
227 //serialization compatibility when node realizer features
228 //change.
229 out.writeByte(YVersion.VERSION_1);
230 //write out the shape node realzier features
231 super.write(out);
232 //write out the state variable
233 out.writeByte(state);
234 }
235
236 /**
237 * Reads in the serialized form of this realizer. The realizer must have been
238 * written out before by it's {@link #write(ObjectOutputStream)} method.
239 * This method will be used by YGFIOHandler to deserialize this NodeRealizer.
240 */
241 public void read(ObjectInputStream in) throws IOException,
242 ClassNotFoundException
243 {
244 switch(in.readByte()) {
245 case YVersion.VERSION_1:
246 super.read(in);
247 state = in.readByte();
248 break;
249 default:
250 //trouble
251 }
252 }
253 }
254
255