1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package org.dishevelled.piccolo.identify;
25
26 import java.awt.Component;
27 import java.awt.Image;
28 import java.awt.Font;
29
30 import java.awt.geom.Dimension2D;
31
32 import java.beans.PropertyChangeEvent;
33 import java.beans.PropertyChangeListener;
34
35 import java.net.URL;
36
37 import org.piccolo2d.PNode;
38
39 import org.piccolo2d.event.PBasicInputEventHandler;
40 import org.piccolo2d.event.PInputEvent;
41 import org.piccolo2d.event.PDragSequenceEventHandler;
42
43 import org.piccolo2d.nodes.PImage;
44 import org.piccolo2d.nodes.PText;
45
46 import org.apache.commons.scxml.env.SimpleErrorHandler;
47
48 import org.apache.commons.scxml.model.SCXML;
49
50 import org.apache.commons.scxml.io.SCXMLParser;
51
52 import org.dishevelled.iconbundle.IconBundle;
53 import org.dishevelled.iconbundle.IconSize;
54 import org.dishevelled.iconbundle.IconState;
55 import org.dishevelled.iconbundle.IconTextDirection;
56
57 import org.dishevelled.identify.IdentifyUtils;
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96 public abstract class AbstractIdNode
97 extends PNode
98 {
99
100 private Object value;
101
102
103 private IconSize iconSize;
104
105
106 private IconState iconState;
107
108
109 private IconTextDirection iconTextDirection;
110
111
112 private final IconBundleImageNode iconBundleImageNode;
113
114
115 private final NameTextNode nameTextNode;
116
117
118 private static SCXML stateMachine;
119
120
121 private final StateMachineSupport stateMachineSupport;
122
123
124 public static final IconSize DEFAULT_ICON_SIZE = IconSize.DEFAULT_32X32;
125
126
127 public static final IconState DEFAULT_ICON_STATE = IconState.NORMAL;
128
129
130 public static final IconTextDirection DEFAULT_ICON_TEXT_DIRECTION = IconTextDirection.LEFT_TO_RIGHT;
131
132
133 private DragHandler dragHandler;
134
135
136 private MouseoverHandler mouseoverHandler;
137
138
139
140
141
142
143
144 protected AbstractIdNode(final Object value)
145 {
146 this.value = value;
147 iconSize = DEFAULT_ICON_SIZE;
148 iconState = DEFAULT_ICON_STATE;
149 iconTextDirection = DEFAULT_ICON_TEXT_DIRECTION;
150 iconBundleImageNode = new IconBundleImageNode();
151 nameTextNode = new NameTextNode();
152
153 dragHandler = new DragHandler();
154 mouseoverHandler = new MouseoverHandler();
155 addInputEventListener(dragHandler);
156 addInputEventListener(mouseoverHandler);
157
158 if (stateMachine == null)
159 {
160 try
161 {
162 URL stateChart = getClass().getResource("stateChart.xml");
163 stateMachine = SCXMLParser.parse(stateChart, new SimpleErrorHandler());
164 }
165 catch (Exception e)
166 {
167
168 }
169 }
170 stateMachineSupport = new StateMachineSupport(this, stateMachine);
171 }
172
173
174
175
176
177
178
179 public final Object getValue()
180 {
181 return value;
182 }
183
184
185
186
187
188
189
190
191 public final void setValue(final Object value)
192 {
193 Object oldValue = this.value;
194 this.value = value;
195 firePropertyChange(-1, "value", oldValue, this.value);
196 }
197
198
199
200
201
202
203
204 public final IconSize getIconSize()
205 {
206 return iconSize;
207 }
208
209
210
211
212
213
214
215
216 public final void setIconSize(final IconSize iconSize)
217 {
218 if (iconSize == null)
219 {
220 throw new IllegalArgumentException("iconSize must not be null");
221 }
222 IconSize oldIconSize = this.iconSize;
223 this.iconSize = iconSize;
224 firePropertyChange(-1, "iconSize", oldIconSize, this.iconSize);
225 }
226
227
228
229
230
231
232
233 public final IconState getIconState()
234 {
235 return iconState;
236 }
237
238
239
240
241
242
243
244
245 public final void setIconState(final IconState iconState)
246 {
247 if (iconState == null)
248 {
249 throw new IllegalArgumentException("iconState must not be null");
250 }
251 IconState oldIconState = this.iconState;
252 this.iconState = iconState;
253 firePropertyChange(-1, "iconState", oldIconState, this.iconState);
254 }
255
256
257
258
259
260
261
262 public final IconTextDirection getIconTextDirection()
263 {
264 return iconTextDirection;
265 }
266
267
268
269
270
271
272
273
274 public final void setIconTextDirection(final IconTextDirection iconTextDirection)
275 {
276 if (iconTextDirection == null)
277 {
278 throw new IllegalArgumentException("iconTextDirection must not be null");
279 }
280 IconTextDirection oldIconTextDirection = this.iconTextDirection;
281 this.iconTextDirection = iconTextDirection;
282 firePropertyChange(-1, "iconTextDirection", oldIconTextDirection, this.iconTextDirection);
283 }
284
285
286
287
288
289
290 public final void setFont(final Font font)
291 {
292
293 nameTextNode.setFont(font);
294 }
295
296
297
298
299
300
301 protected final IconBundleImageNode getIconBundleImageNode()
302 {
303 return iconBundleImageNode;
304 }
305
306
307
308
309
310
311 protected final NameTextNode getNameTextNode()
312 {
313 return nameTextNode;
314 }
315
316
317
318
319
320
321 public final DragHandler getDragHandler()
322 {
323 return dragHandler;
324 }
325
326
327
328
329
330
331 public final MouseoverHandler getMouseoverHandler()
332 {
333 return mouseoverHandler;
334 }
335
336
337
338
339 protected final void resetStateMachine()
340 {
341 stateMachineSupport.resetStateMachine();
342 }
343
344
345
346
347
348
349 private void fireStateMachineEvent(final String eventName)
350 {
351 stateMachineSupport.fireStateMachineEvent(eventName);
352 }
353
354
355
356
357 public final void reverseVideo()
358 {
359 fireStateMachineEvent("reverseVideo");
360 }
361
362
363
364
365 public final void enable()
366 {
367 fireStateMachineEvent("enable");
368 }
369
370
371
372
373 public final void disable()
374 {
375 fireStateMachineEvent("disable");
376 }
377
378
379
380
381 public final void mouseEntered()
382 {
383 fireStateMachineEvent("mouseEntered");
384 }
385
386
387
388
389 public final void mouseExited()
390 {
391 fireStateMachineEvent("mouseExited");
392 }
393
394
395
396
397 public final void mouseReleased()
398 {
399 fireStateMachineEvent("mouseReleased");
400 }
401
402
403
404
405 public final void mousePressed()
406 {
407 fireStateMachineEvent("mousePressed");
408 }
409
410
411
412
413 public final void select()
414 {
415 fireStateMachineEvent("select");
416 }
417
418
419
420
421 public final void deselect()
422 {
423 fireStateMachineEvent("deselect");
424 }
425
426
427
428
429 public final void startDrag()
430 {
431 fireStateMachineEvent("startDrag");
432 }
433
434
435
436
437 public final void endDrag()
438 {
439 fireStateMachineEvent("endDrag");
440 }
441
442
443
444
445 protected final class IconBundleImageNode
446 extends PImage
447 implements PropertyChangeListener
448 {
449
450
451
452
453 IconBundleImageNode()
454 {
455 super();
456 update();
457 AbstractIdNode.this.addPropertyChangeListener("value", this);
458 AbstractIdNode.this.addPropertyChangeListener("iconSize", this);
459 AbstractIdNode.this.addPropertyChangeListener("iconState", this);
460 AbstractIdNode.this.addPropertyChangeListener("iconTextDirection", this);
461 }
462
463
464
465
466
467 private void update()
468 {
469 IconBundle iconBundle = IdentifyUtils.getIconBundleFor(value);
470 if (iconBundle == null)
471 {
472 setWidth(0.0d);
473 setHeight(0.0d);
474 }
475 else
476 {
477 Image image = iconBundle.getImage(null, iconTextDirection, iconState, iconSize);
478 setImage(image);
479 setWidth(iconSize.getWidth());
480 setHeight(iconSize.getHeight());
481 }
482 }
483
484 @Override
485 public void propertyChange(final PropertyChangeEvent event)
486 {
487 update();
488 }
489 }
490
491
492
493
494 protected final class NameTextNode
495 extends PText
496 implements PropertyChangeListener
497 {
498
499
500
501
502 NameTextNode()
503 {
504 super();
505 setHorizontalAlignment(Component.CENTER_ALIGNMENT);
506 update();
507 AbstractIdNode.this.addPropertyChangeListener("value", this);
508
509 }
510
511
512
513
514
515 private void update()
516 {
517 String name = IdentifyUtils.getNameFor(value);
518 setText(name);
519 }
520
521 @Override
522 public void propertyChange(final PropertyChangeEvent event)
523 {
524 update();
525 }
526 }
527
528
529
530
531 private final class DragHandler extends PDragSequenceEventHandler
532 {
533
534
535
536 private DragHandler()
537 {
538 super();
539 setMinDragStartDistance(4.0d);
540 }
541
542 @Override
543 protected void drag(final PInputEvent event)
544 {
545 Dimension2D delta = event.getDeltaRelativeTo(AbstractIdNode.this);
546 AbstractIdNode.this.translate(delta.getWidth(), delta.getHeight());
547 event.setHandled(true);
548 }
549
550 @Override
551 protected void startDrag(final PInputEvent event)
552 {
553 AbstractIdNode.this.raiseToTop();
554 AbstractIdNode.this.startDrag();
555 super.startDrag(event);
556 }
557
558 @Override
559 protected void endDrag(final PInputEvent event)
560 {
561 AbstractIdNode.this.endDrag();
562 super.endDrag(event);
563 }
564
565 @Override
566 public void mousePressed(final PInputEvent event)
567 {
568 AbstractIdNode.this.mousePressed();
569 super.mousePressed(event);
570 }
571
572 @Override
573 public void mouseReleased(final PInputEvent event)
574 {
575 AbstractIdNode.this.mouseReleased();
576 super.mouseReleased(event);
577 }
578 }
579
580
581
582
583 private final class MouseoverHandler extends PBasicInputEventHandler
584 {
585 @Override
586 public void mouseEntered(final PInputEvent event)
587 {
588 AbstractIdNode.this.mouseEntered();
589 }
590
591 @Override
592 public void mouseExited(final PInputEvent event)
593 {
594 AbstractIdNode.this.mouseExited();
595 }
596 }
597 }