1
14 package demo.view.anim;
15
16 import demo.view.DemoBase;
17 import y.anim.AnimationEvent;
18 import y.anim.AnimationFactory;
19 import y.anim.AnimationListener;
20 import y.anim.AnimationObject;
21 import y.anim.AnimationPlayer;
22 import y.anim.CompositeAnimationObject;
23 import y.base.Edge;
24 import y.base.EdgeCursor;
25 import y.base.EdgeMap;
26 import y.base.GraphEvent;
27 import y.base.GraphListener;
28 import y.base.Node;
29 import y.base.NodeCursor;
30 import y.option.ResourceBundleGuiFactory;
31 import y.option.GuiFactory;
32 import y.util.DefaultMutableValue2D;
33 import y.util.Value2D;
34 import y.view.Arrow;
35 import y.view.EdgeRealizer;
36 import y.view.EditMode;
37 import y.view.Graph2D;
38 import y.view.Graph2DViewRepaintManager;
39 import y.view.LineType;
40 import y.view.NodeRealizer;
41 import y.view.PolyLineEdgeRealizer;
42 import y.view.PopupMode;
43 import y.view.ViewAnimationFactory;
44
45 import javax.swing.AbstractAction;
46 import javax.swing.Action;
47 import javax.swing.ActionMap;
48 import javax.swing.InputMap;
49 import javax.swing.JComponent;
50 import javax.swing.JFrame;
51 import javax.swing.JOptionPane;
52 import javax.swing.JPopupMenu;
53 import javax.swing.JRootPane;
54 import javax.swing.KeyStroke;
55 import javax.swing.JButton;
56 import java.awt.Color;
57 import java.awt.EventQueue;
58 import java.awt.event.ActionEvent;
59 import java.awt.event.KeyEvent;
60 import java.awt.geom.GeneralPath;
61 import java.util.MissingResourceException;
62
63
75 public final class AnimationEffectsDemo extends AnimationEffectsDemoBase
76 {
77 private static final long LONG_DURATION = 2000;
78 private static final long SHORT_DURATION = 500;
79 private static final long DEFAULT_DURATION = 1000;
80 private static final long PREFERRED_DURATION_CAMERA = 10000;
81 private static final long PREFERRED_DURATION_GRAPH = 5000;
82 private static final long PREFERRED_DURATION_TRAVERSAL = 2000;
83
84 private final AnimationPlayer player;
85 private final EndHandler endHandler;
86 private final ViewAnimationFactory unmanagedFactory;
87
88
91 public AnimationEffectsDemo()
92 {
93 this(createGuiFactory(), false);
94 }
95
96
99 private AnimationEffectsDemo( final GuiFactory i18n,
100 final boolean wantsRadioButtons )
101 {
102 super(i18n, wantsRadioButtons);
103 this.endHandler = new EndHandler();
104 this.player = new AnimationPlayer();
105 this.player.setFps(240);
106 this.player.addAnimationListener(endHandler);
107 this.player.setBlocking(false);
108 this.unmanagedFactory = new ViewAnimationFactory(view);
109 }
110
111
112
115 void animate()
116 {
117 if (player.isPlaying())
118 {
119 return;
120 }
121
122 switch (((Byte)oh.get("misc", "animation")).byteValue())
123 {
124 case NO_ANIM:
125 break;
126 case ANIMATED_LOAD:
127 animatedLoad();
128 break;
129 case ANIMATED_CLEAR:
130 animatedClear();
131 break;
132 case TRAVERSE_EDGE:
133 animateTraverseEdge();
134 break;
135 case ZOOM:
136 animateZoom();
137 break;
138 case MOVE_CAMERA:
139 animateMoveCamera();
140 break;
141 case MORPH:
142 animateMorph();
143 break;
144 case RESIZE:
145 animateResize();
146 break;
147 case BLINK:
148 animateBlink();
149 break;
150 }
151 }
152
153
156 private void animatedLoad()
157 {
158 compoundAction = true;
159
160 openGraph(i18n.getString(DEMO_NAME + ".RESOURCE.graph." +
161 oh.get("misc", "animateLoad_graph")));
162
163 final Graph2D graph = view.getGraph2D();
164 if (graph.nodeCount() > 0)
165 {
166 final ViewAnimationFactory factory = createManagedAnimationFactory();
167 play(factory.fadeIn(graph,
168 (ViewAnimationFactory.NodeOrder)oh.get("misc", "animateLoad_nodeOrder"),
169 oh.getBool("misc", "animateLoad_obeyEdgeDirection"),
170 oh.getDouble("misc", "animateLoad_ratio"),
171 PREFERRED_DURATION_GRAPH),
172 factory.getRepaintManager());
173
174 }
175
176 compoundAction = false;
177 }
178
179
182 private void animatedClear()
183 {
184 compoundAction = true;
185
186 final Graph2D graph = view.getGraph2D();
187 if (graph.nodeCount() < 1)
188 {
189 openGraph(i18n.getString(DEMO_NAME + ".RESOURCE.graph.big"));
190 }
191
192 if (graph.nodeCount() > 0)
193 {
194 final ViewAnimationFactory factory = createManagedAnimationFactory();
195 factory.setQuality(ViewAnimationFactory.HIGH_QUALITY);
196 endHandler.setClear(true);
197 play(factory.fadeOut(graph,
198 (ViewAnimationFactory.NodeOrder)oh.get("misc", "animateClear_nodeOrder"),
199 oh.getBool("misc", "animateClear_obeyEdgeDirection"),
200 oh.getDouble("misc", "animateClear_ratio"),
201 PREFERRED_DURATION_GRAPH),
202 factory.getRepaintManager());
203 }
204
205 compoundAction = false;
206 }
207
208
211 private void animateTraverseEdge()
212 {
213 final Graph2D graph = view.getGraph2D();
214 final ViewAnimationFactory factory = createManagedAnimationFactory();
215
216 final CompositeAnimationObject traversal = AnimationFactory.createConcurrency();
219
220 EdgeCursor edgesToTraverse = graph.selectedEdges();
221 if (!edgesToTraverse.ok())
222 {
223 edgesToTraverse = graph.edges();
224 }
225 for (EdgeCursor ec = edgesToTraverse; ec.ok(); ec.next())
226 {
227 final EdgeRealizer er = graph.getRealizer(ec.edge());
229 er.setVisible(true);
230
231 final EdgeRealizer bak = er.createCopy();
232
233 final EdgeRealizer unvisited1 = er.createCopy();
236 unvisited1.setLineColor((Color)oh.get("misc", "colorUnvisited"));
237
240 final EdgeRealizer unvisited2 = er.createCopy();
241 unvisited2.setLineColor((Color)oh.get("misc", "colorVisited"));
242 unvisited2.setLineType(LineType.LINE_2);
243 unvisited2.setSourceArrow(Arrow.NONE);
244 unvisited2.setTargetArrow(Arrow.NONE);
245
246 final EdgeRealizer visited1 = er.createCopy();
249 visited1.setLineColor(unvisited2.getLineColor());
250 visited1.setLineType(LineType.LINE_2);
251 visited1.setSourceArrow(Arrow.NONE);
252 visited1.setTargetArrow(Arrow.NONE);
253
254 final EdgeRealizer visited2 = er.createCopy();
255 visited2.setLineColor(unvisited1.getLineColor());
256
259
260 final CompositeAnimationObject seq = AnimationFactory.createLazySequence();
264 seq.addAnimation(
265 factory.traverseEdge(er, visited1, unvisited1, true,
266 ViewAnimationFactory.RESET_EFFECT,
267 PREFERRED_DURATION_TRAVERSAL));
268
269 seq.addAnimation(new AnimationObject()
271 {
272 public void initAnimation()
273 {
274 er.setLineType(visited1.getLineType());
275 er.setLineColor(visited1.getLineColor());
276 }
277
278 public void calcFrame( double time )
279 {
280 }
282
283 public void disposeAnimation()
284 {
285 }
287
288 public long preferredDuration()
289 {
290 return 0;
291 }
292 });
293 seq.addAnimation(AnimationFactory.createPause(500));
294 seq.addAnimation(
295 factory.traverseEdge(er, visited2, unvisited2, false,
296 ViewAnimationFactory.APPLY_EFFECT,
297 PREFERRED_DURATION_TRAVERSAL));
298
299 seq.addAnimation(new AnimationObject()
301 {
302 public void initAnimation()
303 {
304 }
306
307 public void calcFrame( double time )
308 {
309 }
311
312 public void disposeAnimation()
313 {
314 er.setSelected(bak.isSelected());
315 er.setLineColor(bak.getLineColor());
316 er.setLineType(bak.getLineType());
317 er.setSourceArrow(bak.getSourceArrow());
318 er.setTargetArrow(bak.getTargetArrow());
319 }
320
321 public long preferredDuration()
322 {
323 return 0;
324 }
325 });
326 traversal.addAnimation(seq);
327 }
328
329 if (!traversal.isEmpty())
330 {
331 play(traversal, factory.getRepaintManager());
332 }
333 else
334 {
335 JOptionPane.showMessageDialog(null, i18n.getString(DEMO_NAME + ".message.selectEdge"));
336 }
337 }
338
339
342 private void animateZoom()
343 {
344 final ViewAnimationFactory factory = createUnmanagedAnimationFactory();
345 final double newZoom = oh.getDouble("misc", "zoom_factor");
346 play(factory.zoom(newZoom, ViewAnimationFactory.APPLY_EFFECT, DEFAULT_DURATION), null);
347 }
348
349
352 private void animateMoveCamera()
353 {
354 final double x1 = view.toWorldCoordX(0);
355 final double x2 = view.toWorldCoordX(view.getWidth());
356 final double y1 = view.toWorldCoordY(0);
357 final double y2 = view.toWorldCoordY(view.getHeight());
358
359 final GeneralPath path = new GeneralPath();
361 path.moveTo((float)((x1 + x2)*0.5), (float)((y1 + y2)*0.5));
362 path.lineTo((float)(x1 + 0.15*(x2-x1)), (float)(y1 + 0.15*(y2-y1)));
363 path.lineTo((float)(x2 - 0.15*(x2-x1)), (float)(y1 + 0.15*(y2-y1)));
364 path.lineTo((float)((x1 + x2)*0.5), (float)((y1 + y2)*0.5));
365 path.lineTo((float)(x2 - 0.15*(x2-x1)), (float)(y2 - 0.15*(y2-y1)));
366 path.lineTo((float)(x1 + 0.15*(x2-x1)), (float)(y2 - 0.15*(y2-y1)));
367 path.quadTo((float)((x1 + x2)*0.5), (float)((y1 + y2)*0.5),
368 (float)(x1 + 0.15*(x2-x1)), (float)(y1 + 0.25*(y2-y1)));
369 path.quadTo((float)((x1 + x2)*0.5), (float)(y2 - 0.25*(y2-y1)),
370 (float)((x1 + x2)*0.5), (float)((y1 + y2)*0.5));
371
372 final ViewAnimationFactory factory = createUnmanagedAnimationFactory();
373 play(factory.moveCamera(path, PREFERRED_DURATION_CAMERA), null);
374 }
375
376
379 private void animateMorph()
380 {
381 final Graph2D graph = view.getGraph2D();
382 {
383 final CompositeAnimationObject morph = AnimationFactory.createConcurrency();
385 final ViewAnimationFactory factory = createManagedAnimationFactory();
386
387 NodeCursor nodesToMorph = graph.selectedNodes();
388 if (!nodesToMorph.ok())
389 {
390 nodesToMorph = graph.nodes();
391 }
392 for (NodeCursor nc = nodesToMorph; nc.ok(); nc.next())
393 {
394 final NodeRealizer nr = graph.getRealizer(nc.node());
395
396 final NodeRealizer morphTarget = nr.createCopy();
398 morphTarget.moveBy(oh.getDouble("misc", "translateX"),
399 oh.getDouble("misc", "translateY"));
400 morphTarget.setSize(oh.getDouble("misc", "width"),
401 oh.getDouble("misc", "height"));
402 morphTarget.setLineColor((Color)oh.get("misc", "lineColor"));
403 morphTarget.setFillColor((Color)oh.get("misc", "fillColor"));
404 morphTarget.setFillColor2((Color)oh.get("misc", "fillColor2"));
405
406 morph.addAnimation(
407 factory.morph(
408 nr, morphTarget, ViewAnimationFactory.APPLY_EFFECT,
409 DEFAULT_DURATION));
410 }
411 if (!morph.isEmpty())
412 {
413 play(morph, factory.getRepaintManager());
414 }
415 else
416 {
417 JOptionPane.showMessageDialog(null, i18n.getString(DEMO_NAME + ".message.selectNode"));
418 }
419 }
420 }
421
422
425 private void animateResize()
426 {
427 final Graph2D graph = view.getGraph2D();
428 final ViewAnimationFactory factory = createManagedAnimationFactory();
429
430 final CompositeAnimationObject resize = AnimationFactory.createConcurrency();
432
433 NodeCursor nodesToResize = graph.selectedNodes();
434 if (!nodesToResize.ok())
435 {
436 nodesToResize = graph.nodes();
437 }
438 for (NodeCursor nc = nodesToResize; nc.ok(); nc.next())
439 {
440 final Value2D size =
442 DefaultMutableValue2D.create(oh.getDouble("misc", "resize_width"),
443 oh.getDouble("misc", "resize_height"));
444
445 resize.addAnimation(
446 factory.resize(
447 graph.getRealizer(nc.node()), size,
448 ViewAnimationFactory.APPLY_EFFECT, SHORT_DURATION));
449 }
450 if (!resize.isEmpty())
451 {
452 play(resize, factory.getRepaintManager());
453 }
454 else
455 {
456 JOptionPane.showMessageDialog(null, i18n.getString(DEMO_NAME + ".message.selectNode"));
457 }
458 }
459
460
463 private void animateBlink()
464 {
465 final Graph2D graph = view.getGraph2D();
466 final ViewAnimationFactory factory = createManagedAnimationFactory();
467
468 final CompositeAnimationObject blink = AnimationFactory.createConcurrency();
470
471 NodeCursor nodesToBlink = graph.selectedNodes();
472 if (!nodesToBlink.ok())
473 {
474 nodesToBlink = graph.nodes();
475 }
476 for (NodeCursor nc = nodesToBlink; nc.ok(); nc.next())
477 {
478 final int repetitions = oh.getInt("misc", "repetitions");
480 if (repetitions > 1)
481 {
482 blink.addAnimation(
483 AnimationFactory.createRepetition(
484 factory.blink(graph.getRealizer(nc.node()),
485 SHORT_DURATION),
486 repetitions, false));
487 }
488 else
489 {
490 blink.addAnimation(
491 factory.blink(graph.getRealizer(nc.node()), SHORT_DURATION));
492 }
493 }
494
495 if (!blink.isEmpty())
496 {
497 play(blink, factory.getRepaintManager());
498 }
499 else
500 {
501 JOptionPane.showMessageDialog(null, i18n.getString(DEMO_NAME + ".message.selectNode"));
502 }
503 }
504
505
509 private void animateCreate( final NodeRealizer nr )
510 {
511 nr.setVisible(false);
512
513 final ViewAnimationFactory factory = createManagedAnimationFactory();
514
515 switch (((Byte)oh.get("elements", "createNode")).byteValue())
517 {
518 case NO_ANIM:
519 nr.setVisible(true);
520 break;
521 case BLUR_IN:
522 play(factory.blurIn(nr, DEFAULT_DURATION),
523 factory.getRepaintManager());
524 break;
525 case FADE_IN:
526 play(factory.fadeIn(nr, DEFAULT_DURATION),
527 factory.getRepaintManager());
528 break;
529 case IMPLODE:
530 play(factory.implode(nr, DEFAULT_DURATION),
531 factory.getRepaintManager());
532 break;
533 case WHIRL_IN:
534 play(factory.whirlIn(nr, DEFAULT_DURATION),
535 factory.getRepaintManager());
536 break;
537 }
538 }
539
540
544 private void animateCreate( final EdgeRealizer er )
545 {
546 er.setVisible(false);
547
548 final ViewAnimationFactory factory = createManagedAnimationFactory();
549
550 switch (((Byte)oh.get("elements", "createEdge")).byteValue())
552 {
553 case NO_ANIM:
554 er.setVisible(true);
555 break;
556 case BLUR_IN:
557 play(factory.blurIn(er, DEFAULT_DURATION),
558 factory.getRepaintManager());
559 break;
560 case FADE_IN:
561 play(factory.fadeIn(er, DEFAULT_DURATION),
562 factory.getRepaintManager());
563 break;
564 case IMPLODE:
565 play(factory.implode(er, DEFAULT_DURATION),
566 factory.getRepaintManager());
567 break;
568 case EXTRACT:
569 play(factory.extract(er, DEFAULT_DURATION),
570 factory.getRepaintManager());
571 break;
572 }
573 }
574
575
579 private void animateDelete( final NodeRealizer nr )
580 {
581 final Graph2D graph = view.getGraph2D();
582 final ViewAnimationFactory factory = createManagedAnimationFactory();
583
584 final CompositeAnimationObject deletes =
585 AnimationFactory.createLazySequence();
586 final CompositeAnimationObject deleteEdges =
587 AnimationFactory.createConcurrency();
588
589 for (EdgeCursor ec = nr.getNode().edges(); ec.ok(); ec.next())
591 {
592 final EdgeRealizer er = graph.getRealizer(ec.edge());
593
594 switch (((Byte)oh.get("elements", "deleteEdge")).byteValue())
596 {
597 case NO_ANIM:
598 deleteEdges.addAnimation(new RemoveEdge(er, factory.getRepaintManager()));
599 break;
600 case BLUR_OUT:
601 deleteEdges.addAnimation(
602 factory.blurOut(er, ViewAnimationFactory.APPLY_EFFECT,
603 SHORT_DURATION));
604 break;
605 case FADE_OUT:
606 deleteEdges.addAnimation(
607 factory.fadeOut(er, ViewAnimationFactory.APPLY_EFFECT,
608 SHORT_DURATION));
609 break;
610 case EXPLODE:
611 deleteEdges.addAnimation(
612 factory.explode(er, ViewAnimationFactory.APPLY_EFFECT,
613 SHORT_DURATION));
614 break;
615 case RETRACT:
616 deleteEdges.addAnimation(
617 factory.retract(er, ViewAnimationFactory.APPLY_EFFECT,
618 SHORT_DURATION));
619 break;
620 }
621 }
622 if (deleteEdges.preferredDuration() > 0)
623 {
624 deletes.addAnimation(deleteEdges);
625 }
626
627 switch (((Byte)oh.get("elements", "deleteNode")).byteValue())
629 {
630 case NO_ANIM:
631 deletes.addAnimation(new RemoveNode(nr, factory.getRepaintManager()));
632 break;
633 case BLUR_OUT:
634 deletes.addAnimation(
635 factory.blurOut(nr, ViewAnimationFactory.APPLY_EFFECT,
636 DEFAULT_DURATION));
637 break;
638 case FADE_OUT:
639 deletes.addAnimation(
640 factory.fadeOut(nr, ViewAnimationFactory.APPLY_EFFECT,
641 DEFAULT_DURATION));
642 break;
643 case EXPLODE:
644 deletes.addAnimation(
645 factory.explode(nr, ViewAnimationFactory.APPLY_EFFECT,
646 DEFAULT_DURATION));
647 break;
648 case WHIRL_OUT:
649 deletes.addAnimation(
650 factory.whirlOut(nr, ViewAnimationFactory.APPLY_EFFECT,
651 DEFAULT_DURATION));
652 break;
653 }
654 play(deletes, factory.getRepaintManager());
655 }
656
657
661 private void animateDelete( final EdgeRealizer er )
662 {
663 final ViewAnimationFactory factory = createManagedAnimationFactory();
664
665 switch (((Byte)oh.get("elements", "deleteEdge")).byteValue())
667 {
668 case NO_ANIM:
669 play(new RemoveEdge(er, factory.getRepaintManager()),
670 factory.getRepaintManager());
671 break;
672 case BLUR_OUT:
673 play(factory.blurOut(er, ViewAnimationFactory.APPLY_EFFECT,
674 DEFAULT_DURATION),
675 factory.getRepaintManager());
676 break;
677 case FADE_OUT:
678 play(factory.fadeOut(er, ViewAnimationFactory.APPLY_EFFECT,
679 SHORT_DURATION),
680 factory.getRepaintManager());
681 break;
682 case EXPLODE:
683 play(factory.explode(er, ViewAnimationFactory.APPLY_EFFECT,
684 DEFAULT_DURATION),
685 factory.getRepaintManager());
686 break;
687 case RETRACT:
688 play(factory.retract(er, ViewAnimationFactory.APPLY_EFFECT,
689 SHORT_DURATION),
690 factory.getRepaintManager());
691 break;
692 }
693 }
694
695
698 private void animateDeleteSelection()
699 {
700 final ViewAnimationFactory factory = createManagedAnimationFactory();
701
702 final Graph2D graph = view.getGraph2D();
703
704 final byte animatedEdgeDelete =
705 ((Byte)oh.get("elements", "deleteEdge")).byteValue();
706
707 final byte animatedNodeDelete =
708 ((Byte)oh.get("elements", "deleteNode")).byteValue();
709
710
711 final CompositeAnimationObject deleteEdges =
714 AnimationFactory.createConcurrency();
715
716 final EdgeMap markAsScheduled = graph.createEdgeMap();
717
718 for (EdgeCursor ec = graph.selectedEdges(); ec.ok(); ec.next())
720 {
721 final EdgeRealizer er = graph.getRealizer(ec.edge());
722
723 switch (animatedEdgeDelete)
725 {
726 case NO_ANIM:
727 deleteEdges.addAnimation(new RemoveEdge(er, factory.getRepaintManager()));
728 break;
729 case BLUR_OUT:
730 deleteEdges.addAnimation(
731 factory.blurOut(er, ViewAnimationFactory.APPLY_EFFECT,
732 SHORT_DURATION));
733 break;
734 case FADE_OUT:
735 deleteEdges.addAnimation(
736 factory.fadeOut(er, ViewAnimationFactory.APPLY_EFFECT,
737 SHORT_DURATION));
738 break;
739 case EXPLODE:
740 deleteEdges.addAnimation(
741 factory.explode(er, ViewAnimationFactory.APPLY_EFFECT,
742 SHORT_DURATION));
743 break;
744 case RETRACT:
745 deleteEdges.addAnimation(
746 factory.retract(er, ViewAnimationFactory.APPLY_EFFECT,
747 SHORT_DURATION));
748 break;
749 }
750 markAsScheduled.setBool(ec.edge(), true);
751 }
752
753 for (NodeCursor nc = graph.selectedNodes(); nc.ok(); nc.next())
755 {
756 for (EdgeCursor ec = nc.node().edges(); ec.ok(); ec.next())
757 {
758 if (!markAsScheduled.getBool(ec.edge()))
759 {
760 final EdgeRealizer er = graph.getRealizer(ec.edge());
761
762 switch (animatedEdgeDelete)
764 {
765 case NO_ANIM:
766 deleteEdges.addAnimation(new RemoveEdge(er, factory.getRepaintManager()));
767 break;
768 case BLUR_OUT:
769 deleteEdges.addAnimation(
770 factory.blurOut(er, ViewAnimationFactory.APPLY_EFFECT,
771 SHORT_DURATION));
772 break;
773 case FADE_OUT:
774 deleteEdges.addAnimation(
775 factory.fadeOut(er, ViewAnimationFactory.APPLY_EFFECT,
776 SHORT_DURATION));
777 break;
778 case EXPLODE:
779 deleteEdges.addAnimation(
780 factory.explode(er, ViewAnimationFactory.APPLY_EFFECT,
781 SHORT_DURATION));
782 break;
783 case RETRACT:
784 deleteEdges.addAnimation(
785 factory.retract(er, ViewAnimationFactory.APPLY_EFFECT,
786 SHORT_DURATION));
787 break;
788 }
789 markAsScheduled.setBool(ec.edge(), true);
790 }
791 }
792 }
793
794 graph.disposeEdgeMap(markAsScheduled);
795
796
797 final CompositeAnimationObject deleteNodes =
800 AnimationFactory.createConcurrency();
801
802 for (NodeCursor nc = graph.selectedNodes(); nc.ok(); nc.next())
803 {
804 final NodeRealizer nr = graph.getRealizer(nc.node());
805
806 switch (animatedNodeDelete)
808 {
809 case NO_ANIM:
810 deleteNodes.addAnimation(new RemoveNode(nr, factory.getRepaintManager()));
811 break;
812 case BLUR_OUT:
813 deleteNodes.addAnimation(
814 factory.blurOut(nr, ViewAnimationFactory.APPLY_EFFECT,
815 DEFAULT_DURATION));
816 break;
817 case FADE_OUT:
818 deleteNodes.addAnimation(
819 factory.fadeOut(nr, ViewAnimationFactory.APPLY_EFFECT,
820 DEFAULT_DURATION));
821 break;
822 case EXPLODE:
823 deleteNodes.addAnimation(
824 factory.explode(nr, ViewAnimationFactory.APPLY_EFFECT,
825 LONG_DURATION));
826 break;
827 case WHIRL_OUT:
828 deleteNodes.addAnimation(
829 factory.whirlOut(nr, ViewAnimationFactory.APPLY_EFFECT,
830 DEFAULT_DURATION));
831 break;
832 }
833 }
834
835
836
838 final CompositeAnimationObject deletes = AnimationFactory.createLazySequence();
841
842 if (!deleteEdges.isEmpty())
843 {
844 deletes.addAnimation(deleteEdges);
845 }
846 if (!deleteNodes.isEmpty())
847 {
848 deletes.addAnimation(deleteNodes);
849 }
850 if (!deletes.isEmpty())
851 {
852 play(deletes, factory.getRepaintManager());
853 }
854 }
855
856
860 private void play( final AnimationObject ao, final Graph2DViewRepaintManager arm )
861 {
862 player.addAnimationListener(new AutoRemoveListener(arm != null
863 ? (AnimationListener)arm
864 : view));
865 player.setSpeed(oh.getDouble("global", "speed"));
866 player.animate(ao);
867 }
868
869
870
873 private ViewAnimationFactory createUnmanagedAnimationFactory()
874 {
875 return unmanagedFactory;
876 }
877
878
882 private ViewAnimationFactory createManagedAnimationFactory()
883 {
884 final ViewAnimationFactory factory =
885 new ViewAnimationFactory(new Graph2DViewRepaintManager(view));
886 factory.setQuality(ViewAnimationFactory.HIGH_QUALITY);
887 return factory;
888 }
889
890
894 private Action createCreateEdgeAction()
895 {
896 final Action create = new AbstractAction()
897 {
898 public void actionPerformed( final ActionEvent e )
899 {
900 final Graph2D graph = view.getGraph2D();
901
902 Node lastNode = null;
903 for (NodeCursor nc = graph.selectedNodes(); nc.ok(); nc.next())
904 {
905 if (lastNode != null)
906 {
907 final EdgeRealizer er = new PolyLineEdgeRealizer();
908 er.setVisible(false);
909 graph.createEdge(lastNode, nc.node(), er);
910 animateCreate(er);
911 }
912 lastNode = nc.node();
913 }
914
915 if (lastNode == null)
916 {
917 JOptionPane.showMessageDialog(null, i18n.getString(DEMO_NAME + ".message.selectNodes"));
918 }
919 }
920 };
921 localizeAction(create, DEMO_NAME + ".action.CreateEdge");
922
923 return create;
924 }
925
926
930 private Action createDeleteSelectionAction()
931 {
932 final Action delete = new AbstractAction()
933 {
934 public void actionPerformed( final ActionEvent e )
935 {
936 animateDeleteSelection();
937 }
938 };
939 localizeAction(delete, DEMO_NAME + ".action.DeleteSelection");
940
941 return delete;
942 }
943
944
948 private Action createDeleteNodeAction()
949 {
950 final Action delete = new AbstractAction()
951 {
952 public void actionPerformed( final ActionEvent e )
953 {
954 final Graph2D graph = view.getGraph2D();
955 final NodeCursor nc = graph.selectedNodes();
956 if (nc.ok())
957 {
958 animateDelete(graph.getRealizer(nc.node()));
959 }
961 }
962 };
963 localizeAction(delete, DEMO_NAME + ".action.DeleteNode");
964
965 return delete;
966 }
967
968
972 private Action createDeleteEdgeAction()
973 {
974 final Action delete = new AbstractAction()
975 {
976 public void actionPerformed( final ActionEvent e )
977 {
978 final Graph2D graph = view.getGraph2D();
979 final EdgeCursor ec = graph.selectedEdges();
980 if (ec.ok())
981 {
982 animateDelete(graph.getRealizer(ec.edge()));
983 }
984 }
985 };
986 localizeAction(delete, DEMO_NAME + ".action.DeleteEdge");
987
988 return delete;
989 }
990
991
992
996 private void registerGraphListener()
997 {
998 final Graph2D graph = view.getGraph2D();
999 graph.addGraphListener(new GraphListener()
1000 {
1001 public void onGraphEvent( final GraphEvent e )
1002 {
1003 if (GraphEvent.NODE_CREATION == e.getType() && !compoundAction)
1004 {
1005 animateCreate(graph.getRealizer((Node)e.getData()));
1006 }
1007 }
1008 });
1009 }
1010
1011
1015 private void registerEditMode()
1016 {
1017 EditMode editMode = new EditMode();
1018 PopupMode popupMode = new PopupMode() {
1019 private final Action createEdge = createCreateEdgeAction();
1020 private final Action deleteNode = createDeleteNodeAction();
1021 private final Action deleteEdge = createDeleteEdgeAction();
1022
1023 public JPopupMenu getSelectionPopup( double x, double y )
1024 {
1025 final JPopupMenu menu = new JPopupMenu();
1026 menu.add(createEdge);
1027 return menu;
1028 }
1029
1030 public JPopupMenu getNodePopup( final Node v )
1031 {
1032 final JPopupMenu menu = new JPopupMenu();
1033 menu.add(deleteNode);
1034 return menu;
1035 }
1036
1037 public JPopupMenu getEdgePopup( final Edge e )
1038 {
1039 final JPopupMenu menu = new JPopupMenu();
1040 menu.add(deleteEdge);
1041 return menu;
1042 }
1043 };
1044 editMode.setPopupMode(popupMode);
1045 view.addViewMode(editMode);
1046 }
1047
1048
1051 private void registerActions()
1052 {
1053 final ActionMap amap = new ActionMap();
1054 amap.put("DELETE_SELECTION", createDeleteSelectionAction());
1055 final InputMap imap = new InputMap();
1056 imap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,0), "DELETE_SELECTION");
1057 view.getCanvasComponent().setActionMap(amap);
1058 view.getCanvasComponent().setInputMap(JComponent.WHEN_FOCUSED, imap);
1059 }
1060
1061
1062 public void addContentTo( final JRootPane rootPane )
1063 {
1064 openGraph(i18n.getString(DEMO_NAME + ".RESOURCE.graph.small"));
1065 registerGraphListener();
1066 registerEditMode();
1067 registerActions();
1068 rootPane.setContentPane(createContentPane());
1069 }
1070
1071 public static void main( String[] args )
1072 {
1073 DemoBase.initLnF();
1074
1075 final GuiFactory gf = createGuiFactory();
1076 EventQueue.invokeLater(new Runnable()
1077 {
1078 public void run()
1079 {
1080 final AnimationEffectsDemo demo = new AnimationEffectsDemo(gf, true);
1081 final JFrame frame = new JFrame(gf.getString(DEMO_NAME + ".title"));
1082 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
1083 demo.addContentTo(frame.getRootPane());
1084 frame.pack();
1085 frame.setLocationRelativeTo(null);
1086 frame.setVisible(true);
1087 }
1088 });
1089 }
1090
1091 private static GuiFactory createGuiFactory()
1092 {
1093 try
1094 {
1095 final ResourceBundleGuiFactory i18n = new ResourceBundleGuiFactory();
1096 i18n.addBundle(AnimationEffectsDemo.class.getName());
1097 return i18n;
1098 }
1099 catch ( final MissingResourceException mre )
1100 {
1101 System.err.println( "Could not find resources! " + mre );
1102 return new GuiFactory()
1103 {
1104 public JButton createButton( final String action )
1105 {
1106 return new JButton(action);
1107 }
1108
1109 public String getString( final String key )
1110 {
1111 return key;
1112 }
1113
1114 public Action createHelpAction( final String helpKey )
1115 {
1116 return null;
1117 }
1118 };
1119 }
1120 }
1121
1122
1126 private final class AutoRemoveListener implements AnimationListener
1127 {
1128 private final AnimationListener delegate;
1129
1130 AutoRemoveListener( final AnimationListener delegate )
1131 {
1132 this.delegate = delegate;
1133 }
1134
1135 public void animationPerformed( final AnimationEvent e )
1136 {
1137 delegate.animationPerformed(e);
1138 if (AnimationEvent.END == e.getHint())
1139 {
1140 player.removeAnimationListener(this);
1141 }
1142 }
1143 }
1144
1145
1149 private final class EndHandler implements AnimationListener
1150 {
1151 private boolean clear;
1152
1153 EndHandler()
1154 {
1155 this.clear = false;
1156 }
1157
1158 void setClear( final boolean clear )
1159 {
1160 this.clear = clear;
1161 }
1162
1163 public void animationPerformed( final AnimationEvent e )
1164 {
1165 if (AnimationEvent.END == e.getHint())
1166 {
1167 if (clear)
1168 {
1169 view.getGraph2D().clear();
1170 view.fitContent();
1171 clear = false;
1172 }
1173 view.updateView();
1174 }
1175 }
1176 }
1177
1178
1184 private final static class RemoveNode implements AnimationObject
1185 {
1186 private NodeRealizer realizer;
1187 private Graph2DViewRepaintManager manager;
1188
1189 public RemoveNode( final NodeRealizer realizer,
1190 final Graph2DViewRepaintManager manager )
1191 {
1192 this.realizer = realizer;
1193 this.manager = manager;
1194 }
1195
1196 public void initAnimation()
1197 {
1198 if (manager != null)
1199 {
1200 manager.add(realizer);
1201 }
1202 }
1203
1204 public void calcFrame( final double time )
1205 {
1206 }
1207
1208 public void disposeAnimation()
1209 {
1210