1
2
3
4
5
6 package net.kwfgrid.gwui.graphview;
7
8 import de.fzi.wim.guibase.graphview.graph.Node;
9 import de.fzi.wim.guibase.graphview.view.JGraphPane;
10 import de.fzi.wim.guibase.graphview.view.Manipulator;
11 import de.fzi.wim.guibase.graphview.view.NodePainter;
12 import net.kwfgrid.gworkflowdl.structure.Place;
13 import net.kwfgrid.gworkflowdl.structure.Token;
14 import net.kwfgrid.gwui.ZoomGroup;
15 import org.glassbox.Theme;
16 import org.glassbox.graphview.*;
17 import org.glassbox.gui.Group;
18 import org.glassbox.gui.Member;
19 import org.jdom.Element;
20
21 import java.awt.*;
22
23 /***
24 * The painter for <code>PlaceNodes</code>.<br>
25 * This painter has the following properties which can be configured via the application's theme:
26 * <pre><ul>
27 * <li>kwfgrid.PlaceNodePainter.default.stroke</li>
28 * <li>kwfgrid.PlaceNodePainter.default.color</li>
29 * <li>kwfgrid.PlaceNodePainter.default.paint</li>
30 * <li>kwfgrid.PlaceNodePainter.default.size</li>
31 * <li>kwfgrid.PlaceNodePainter.default.token.paint</li>
32 * <li>kwfgrid.PlaceNodePainter.button.insets</li>
33 * </ul></pre>
34 */
35 public class PlaceNodePainter extends TextNodePainter2 implements Member {
36
37 private static final String[] EMPTY_TEXT = new String[0];
38
39 public static final String IDENTIFIER = "kwfgrid.PlaceNodePainter";
40
41 protected static final String SIZE_KEY = "kwfgrid.PlaceNodePainter.size";
42 protected static final String FONT_KEY = "kwfgrid.PlaceNodePainter.font";
43 protected static final String INSETS_KEY = "kwfgrid.PlaceNodePainter.insets";
44 protected static final String BORDER_STROKE_KEY = "kwfgrid.PlaceNodePainter.border.stroke";
45 protected static final String BORDER_ARC_SIZE_KEY = "kwfgrid.PlaceNodePainter.border.arc.size";
46 protected static final String BUTTON_INSETS_KEY = "kwfgrid.PlaceNodePainter.button.insets";
47
48 protected static final String BORDER_COLOR_KEY = "kwfgrid.PlaceNodePainter.default.border.color";
49 protected static final String BACKGROUND_COLOR_KEY = "kwfgrid.PlaceNodePainter.default.background.color";
50 protected static final String TOKEN_PAINT_KEY = "kwfgrid.PlaceNodePainter.default.token.paint";
51 protected static final String FAULTTOKEN_PAINT_KEY = "kwfgrid.PlaceNodePainter.default.faulttoken.paint";
52 protected static final String TEXT_COLOR_KEY = "kwfgrid.PlaceNodePainter.default.text.color";
53
54 protected static final String LABEL_FONT_KEY = "kwfgrid.PlaceNodePainter.label.font";
55 protected static final Font LABEL_FONT = Theme.getFont(LABEL_FONT_KEY);
56 protected static final String LABEL_COLOR_KEY = "kwfgrid.PlaceNodePainter.label.color";
57 protected static final Color LABEL_COLOR = Theme.getColor(LABEL_COLOR_KEY);
58
59
60 protected static final String DEAD_BORDER_COLOR_KEY = "kwfgrid.PlaceNodePainter.dead.border.color";
61 protected static final String DEAD_BACKGROUND_COLOR_KEY = "kwfgrid.PlaceNodePainter.dead.border.color";
62 protected static final String DEAD_TOKEN_PAINT_KEY = "kwfgrid.PlaceNodePainter.dead.token.paint";
63 protected static final String DEAD_TEXT_COLOR_KEY = "kwfgrid.PlaceNodePainter.dead.text.color";
64
65 protected static final Dimension SIZE = Theme.getSize(SIZE_KEY);
66 protected static final Font FONT = Theme.getFont(FONT_KEY);
67 protected static final FontMetrics FONT_METRICS = Toolkit.getDefaultToolkit().getFontMetrics(FONT);
68 protected static final Insets INSETS = Theme.getInsets(INSETS_KEY);
69 protected static final Stroke BORDER_STROKE = Theme.getStroke(BORDER_STROKE_KEY);
70 protected static final Dimension BORDER_ARC_SIZE = Theme.getSize(BORDER_ARC_SIZE_KEY);
71 protected static final Insets BUTTON_INSETS = Theme.getInsets(BUTTON_INSETS_KEY);
72
73 protected static final Paint TOKEN_PAINT = Theme.getPaint(TOKEN_PAINT_KEY);
74 protected static final Paint FAULTTOKEN_PAINT = Theme.getPaint(FAULTTOKEN_PAINT_KEY);
75
76 protected static final Color TEXT_COLOR = Theme.getColor(TEXT_COLOR_KEY);
77 protected static final Color BORDER_COLOR = Theme.getColor(BORDER_COLOR_KEY);
78 protected static final Color BACKGROUND_COLOR = Theme.getColor(BACKGROUND_COLOR_KEY);
79
80 protected static final Paint DEAD_TOKEN_PAINT = Theme.getPaint(DEAD_TOKEN_PAINT_KEY);
81 protected static final Color DEAD_TEXT_COLOR = Theme.getColor(DEAD_TEXT_COLOR_KEY);
82 protected static final Color DEAD_BORDER_COLOR = Theme.getColor(DEAD_BORDER_COLOR_KEY);
83 protected static final Color DEAD_BACKGROUND_COLOR = Theme.getColor(DEAD_BACKGROUND_COLOR_KEY);
84
85 /***
86 Inner class for painting the Token.
87 */
88 protected static class TokenPainter implements ZoomableNodePainter {
89 private int _w, _h;
90 private boolean _paintlabels;
91 private Rectangle _bounds;
92 private Color _textcolor;
93 private Paint _paint;
94
95 protected TokenPainter(Paint paint, Color textcolor) {
96 _paint = paint;
97 _textcolor = textcolor;
98 _bounds = new Rectangle();
99 setZoomFactor(1d);
100 }
101
102 public void setZoomFactor(double zf) {
103 _w = (int) ((double) (SIZE.width - INSETS.left - INSETS.right) * zf);
104 _h = (int) ((double) (SIZE.height - INSETS.top - INSETS.bottom) * zf);
105 _paintlabels = zf > 0.5d;
106 }
107
108 public void paintNode(JGraphPane gpane, Graphics2D g, Node node) {
109 PlaceNode pn = (PlaceNode) node;
110 Place p = pn.getPlace();
111 int tokn = p.getTokenNumber();
112 getNodeScreenBounds(gpane, node, _bounds);
113
114 if (tokn > 0) {
115 g.setPaint(_paint);
116 g.fillArc(_bounds.x,
117 _bounds.y,
118 _bounds.width - 1,
119 _bounds.height - 1,
120 0,
121 360);
122
123 if (tokn > 1 && _paintlabels) {
124 g.setColor(_textcolor);
125 g.setFont(FONT);
126 String s = "" + tokn;
127 int w = FONT_METRICS.stringWidth(s);
128 int h = FONT_METRICS.getHeight();
129 g.drawString(s, _bounds.x + (_bounds.width - w) / 2, _bounds.y + (_bounds.height - h) / 2 + h - 2);
130 }
131 }
132 }
133
134 public boolean isInNode(JGraphPane gpane, Node node, Point point) {
135 getNodeScreenBounds(gpane, node, _bounds);
136 return _bounds.contains(point);
137 }
138
139 public void getNodeScreenBounds(JGraphPane gpane, Node node, Rectangle bounds) {
140 Point p = gpane.getScreenPointForNode(node);
141 bounds.setBounds(p.x - _w / 2,
142 p.y - _h / 2,
143 _w,
144 _h);
145 }
146
147 public String getToolTipText(JGraphPane gpane, Node node, Point point) {
148 return null;
149 }
150 }
151
152 /***
153 Inner class for painting the Place (without probably attached icons).
154 */
155 protected static class PlacePainter implements ZoomableNodePainter {
156 /***
157 * Default Painter.
158 */
159 protected NodeBorder DEFAULT = new NodeBorder(new TokenPainter(TOKEN_PAINT, TEXT_COLOR),
160 INSETS,
161 BORDER_COLOR,
162 BACKGROUND_COLOR,
163 BORDER_STROKE,
164 BORDER_ARC_SIZE);
165
166 /***
167 * Painter for dead places.
168 */
169 protected NodeBorder DEAD = new NodeBorder(new TokenPainter(DEAD_TOKEN_PAINT, DEAD_TEXT_COLOR),
170 INSETS,
171 DEAD_BORDER_COLOR,
172 DEAD_BACKGROUND_COLOR,
173 BORDER_STROKE,
174 BORDER_ARC_SIZE);
175
176 /***
177 * Painter for SOAP Faults.
178 */
179 protected NodeBorder FAULT = new NodeBorder(
180 new TokenPainter(FAULTTOKEN_PAINT, TEXT_COLOR),
181 INSETS,
182 BORDER_COLOR,
183 BACKGROUND_COLOR,
184 BORDER_STROKE,
185 BORDER_ARC_SIZE);
186
187 protected NodePainter getState(PlaceNode node) {
188 if (!node.isQuasiLive()) {
189 return DEAD;
190 } else if (node.hasFault()) {
191 return FAULT;
192 } else {
193 return DEFAULT;
194 }
195 }
196
197 public void setZoomFactor(double zf) {
198 DEFAULT.setZoomFactor(zf);
199 DEAD.setZoomFactor(zf);
200 FAULT.setZoomFactor(zf);
201 }
202
203 public void paintNode(JGraphPane pane, Graphics2D g, Node node) {
204 Stroke oldstroke = g.getStroke();
205 Color oldcolor = g.getColor();
206 PlaceNode pn = (PlaceNode) node;
207 getState(pn).paintNode(pane, g, pn);
208 g.setStroke(oldstroke);
209 g.setColor(oldcolor);
210 }
211
212 public boolean isInNode(JGraphPane gpane, Node node, Point point) {
213 PlaceNode pn = (PlaceNode) node;
214 NodePainter state = getState(pn);
215 return state.isInNode(gpane, node, point);
216 }
217
218 public void getNodeScreenBounds(JGraphPane gpane, Node node, Rectangle bounds) {
219 PlaceNode pn = (PlaceNode) node;
220 NodePainter state = getState(pn);
221 state.getNodeScreenBounds(gpane, node, bounds);
222 }
223
224 public String getToolTipText(JGraphPane view, Node n, Point point) {
225 PlaceNode node = (PlaceNode) n;
226 StringBuffer t = new StringBuffer();
227 t.append("<html>");
228 String tokentype = node.getPlace().getTokenType();
229 if (tokentype != null && tokentype.length() > 0)
230 t.append(tokentype).append(" Place<br>");
231 t.append("ID: <b>").append(node.getPlace().getID()).append("</b>");
232 int tnum = node.getPlace().getTokenNumber();
233 if (tnum > 0)
234 t.append("<br>").append(tnum).append(" Token").append((tnum != 1 ? "s" : ""));
235 t.append("</html>");
236 return t.toString();
237 }
238 }
239
240 private ZoomGroup _group;
241 private boolean _paintlabels;
242
243 public PlaceNodePainter() {
244 super(new NodeButtonSet(IDENTIFIER,
245 new PlacePainter(),
246 BUTTON_INSETS,
247 NodeIconSet.HORIZONTAL,
248 NodeIconSet.RIGHT | NodeIconSet.OUTSIDE,
249 NodeIconSet.CENTER | NodeIconSet.INSIDE,
250 Cursor.getPredefinedCursor(Cursor.HAND_CURSOR),
251 PlaceNode.class),
252 LABEL_FONT,
253 LABEL_COLOR,
254 TextNodePainter2.BOTTOM,
255 2);
256
257 _group = null;
258 updateNodeSize();
259 }
260
261
262
263
264
265 public Manipulator getGraphManipulator() {
266 return (Manipulator) getDelegate();
267 }
268
269 /***
270 Add a button or icon
271 */
272 public void addButton(NodeIconSet.Icon icon) {
273 NodePainter np = getDelegate();
274 if (np instanceof NodeButtonSet) {
275 ((NodeButtonSet)np).addButton(icon);
276 }
277 }
278
279
280
281
282
283 private void updateNodeSize() {
284 double zf = 1d;
285 if (_group != null) {
286 zf = ((Double) _group.getProperty(ZoomGroup.ZOOM_FACTOR_KEY)).doubleValue();
287 }
288 setZoomFactor(zf);
289 _paintlabels = zf > 0.4d;
290 }
291
292
293
294
295
296 protected String[] getText(Node node) {
297 PlaceNode pnode = (PlaceNode)node;
298 return _paintlabels?pnode.getText():EMPTY_TEXT;
299 }
300
301
302
303
304
305 public Group getGroup() {
306 return _group;
307 }
308
309 public String getIdentifier() {
310 return IDENTIFIER;
311 }
312
313 public void groupPropertyChanged(String name, Object oldvalue, Object newvalue) {
314 if (ZoomGroup.ZOOM_FACTOR_KEY.equals(name)) {
315 updateNodeSize();
316 }
317 }
318
319 public void setGroup(Group group) throws IllegalArgumentException {
320 if (!(group == null || group instanceof ZoomGroup))
321 throw new IllegalArgumentException("PlaceNodePainter must be member of a ZoomGroup.");
322
323 _group = (ZoomGroup) group;
324
325 updateNodeSize();
326 }
327 }