1
28 package demo.view.anim;
29
30 import demo.view.DemoDefaults;
31 import y.anim.AnimationEvent;
32 import y.anim.AnimationFactory;
33 import y.anim.AnimationListener;
34 import y.anim.AnimationObject;
35 import y.anim.AnimationPlayer;
36 import y.anim.CompositeAnimationObject;
37 import y.base.Edge;
38 import y.base.EdgeCursor;
39 import y.base.EdgeMap;
40 import y.base.GraphEvent;
41 import y.base.GraphListener;
42 import y.base.Node;
43 import y.base.NodeCursor;
44 import y.option.GuiFactory;
45 import y.option.ResourceBundleGuiFactory;
46 import y.util.DefaultMutableValue2D;
47 import y.util.Value2D;
48 import y.view.Arrow;
49 import y.view.EdgeRealizer;
50 import y.view.EditMode;
51 import y.view.Graph2D;
52 import y.view.Graph2DViewRepaintManager;
53 import y.view.LineType;
54 import y.view.NodeRealizer;
55 import y.view.PolyLineEdgeRealizer;
56 import y.view.PopupMode;
57 import y.view.ViewAnimationFactory;
58
59 import javax.swing.AbstractAction;
60 import javax.swing.Action;
61 import javax.swing.ActionMap;
62 import javax.swing.InputMap;
63 import javax.swing.JButton;
64 import javax.swing.JComponent;
65 import javax.swing.JFrame;
66 import javax.swing.JOptionPane;
67 import javax.swing.JPopupMenu;
68 import javax.swing.JRootPane;
69 import javax.swing.KeyStroke;
70 import java.awt.Color;
71 import java.awt.EventQueue;
72 import java.awt.event.ActionEvent;
73 import java.awt.event.KeyEvent;
74 import java.awt.geom.GeneralPath;
75 import java.util.MissingResourceException;
76
77
91 public final class AnimationEffectsDemo extends AnimationEffectsDemoBase {
92 private static final long LONG_DURATION = 2000;
93 private static final long SHORT_DURATION = 500;
94 private static final long DEFAULT_DURATION = 1000;
95 private static final long PREFERRED_DURATION_CAMERA = 10000;
96 private static final long PREFERRED_DURATION_GRAPH = 5000;
97 private static final long PREFERRED_DURATION_TRAVERSAL = 2000;
98
99 private final AnimationPlayer player;
100 private final EndHandler endHandler;
101 private final ViewAnimationFactory unmanagedFactory;
102
103
106 public AnimationEffectsDemo() {
107 this(createGuiFactory(), false);
108 }
109
110
113 private AnimationEffectsDemo(
114 final GuiFactory i18n,
115 final boolean wantsRadioButtons
116 ) {
117 super(i18n, wantsRadioButtons);
118 this.endHandler = new EndHandler();
119 this.player = new AnimationPlayer();
120 this.player.setFps(240);
121 this.player.addAnimationListener(endHandler);
122 this.player.setBlocking(false);
123 this.unmanagedFactory = new ViewAnimationFactory(view);
124
125 configureDefaultRealizers();
126
127 EdgeRealizer edgeRealizer = view.getGraph2D().getDefaultEdgeRealizer();
128 edgeRealizer.setLineColor(Color.LIGHT_GRAY);
129 edgeRealizer.setTargetArrow(Arrow.NONE);
130 edgeRealizer.setLineType(LineType.DASHED_2);
131 }
132
133 protected void configureDefaultRealizers() {
134 DemoDefaults.configureDefaultRealizers(view);
135 }
136
137
138
141 void animate() {
142 if (player.isPlaying()) {
143 return;
144 }
145
146 switch (((Byte) oh.get("misc", "animation")).byteValue()) {
147 case NO_ANIM:
148 break;
149 case ANIMATED_LOAD:
150 animatedLoad();
151 break;
152 case ANIMATED_CLEAR:
153 animatedClear();
154 break;
155 case TRAVERSE_EDGE:
156 animateTraverseEdge();
157 break;
158 case ZOOM:
159 animateZoom();
160 break;
161 case MOVE_CAMERA:
162 animateMoveCamera();
163 break;
164 case MORPH:
165 animateMorph();
166 break;
167 case RESIZE:
168 animateResize();
169 break;
170 case BLINK:
171 animateBlink();
172 break;
173 }
174 }
175
176
179 private void animatedLoad() {
180 compoundAction = true;
181
182 openGraph(i18n.getString(DEMO_NAME + ".RESOURCE.graph." +
183 oh.get("misc", "animateLoad_graph")));
184
185 final Graph2D graph = view.getGraph2D();
186
187 if (graph.nodeCount() > 0) {
188 final ViewAnimationFactory factory = createManagedAnimationFactory();
189 play(factory.fadeIn(graph,
190 (ViewAnimationFactory.NodeOrder) oh.get("misc", "animateLoad_nodeOrder"),
191 oh.getBool("misc", "animateLoad_obeyEdgeDirection"),
192 oh.getDouble("misc", "animateLoad_ratio"),
193 PREFERRED_DURATION_GRAPH),
194 factory.getRepaintManager());
195
196 }
197
198 compoundAction = false;
199 }
200
201
204 private void animatedClear() {
205 compoundAction = true;
206
207 final Graph2D graph = view.getGraph2D();
208 if (graph.nodeCount() < 1) {
209 openGraph(i18n.getString(DEMO_NAME + ".RESOURCE.graph.big"));
210 }
211
212 if (graph.nodeCount() > 0) {
213 final ViewAnimationFactory factory = createManagedAnimationFactory();
214 factory.setQuality(ViewAnimationFactory.HIGH_QUALITY);
215 endHandler.setClear(true);
216 play(factory.fadeOut(graph,
217 (ViewAnimationFactory.NodeOrder) oh.get("misc", "animateClear_nodeOrder"),
218 oh.getBool("misc", "animateClear_obeyEdgeDirection"),
219 oh.getDouble("misc", "animateClear_ratio"),
220 PREFERRED_DURATION_GRAPH),
221 factory.getRepaintManager());
222 }
223
224 compoundAction = false;
225 }
226
227
230 private void animateTraverseEdge() {
231 final Graph2D graph = view.getGraph2D();
232 final ViewAnimationFactory factory = createManagedAnimationFactory();
233
234 final CompositeAnimationObject traversal = AnimationFactory.createConcurrency();
237
238 EdgeCursor edgesToTraverse = graph.selectedEdges();
239 if (!edgesToTraverse.ok()) {
240 edgesToTraverse = graph.edges();
241 }
242 for (EdgeCursor ec = edgesToTraverse; ec.ok(); ec.next()) {
243 final EdgeRealizer er = graph.getRealizer(ec.edge());
245 er.setVisible(true);
246
247 final EdgeRealizer bak = er.createCopy();
248
249 final EdgeRealizer unvisited1 = er.createCopy();
252 unvisited1.setLineColor((Color) oh.get("misc", "colorUnvisited"));
253
256 final EdgeRealizer unvisited2 = er.createCopy();
257 unvisited2.setLineColor((Color) oh.get("misc", "colorVisited"));
258 unvisited2.setLineType(LineType.LINE_2);
259 unvisited2.setSourceArrow(Arrow.NONE);
260 unvisited2.setTargetArrow(Arrow.NONE);
261
262 final EdgeRealizer visited1 = er.createCopy();
265 visited1.setLineColor(unvisited2.getLineColor());
266 visited1.setLineType(LineType.LINE_2);
267 visited1.setSourceArrow(Arrow.NONE);
268 visited1.setTargetArrow(Arrow.NONE);
269
270 final EdgeRealizer visited2 = er.createCopy();
271 visited2.setLineColor(unvisited1.getLineColor());
272
275 final CompositeAnimationObject seq = AnimationFactory.createLazySequence();
279 seq.addAnimation(
280 factory.traverseEdge(er, visited1, unvisited1, true,
281 ViewAnimationFactory.RESET_EFFECT,
282 PREFERRED_DURATION_TRAVERSAL));
283
284 seq.addAnimation(new AnimationObject() {
286 public void initAnimation() {
287 er.setLineType(visited1.getLineType());
288 er.setLineColor(visited1.getLineColor());
289 }
290
291 public void calcFrame(double time) {
292 }
294
295 public void disposeAnimation() {
296 }
298
299 public long preferredDuration() {
300 return 0;
301 }
302 });
303 seq.addAnimation(AnimationFactory.createPause(500));
304 seq.addAnimation(
305 factory.traverseEdge(er, visited2, unvisited2, false,
306 ViewAnimationFactory.APPLY_EFFECT,
307 PREFERRED_DURATION_TRAVERSAL));
308
309 seq.addAnimation(new AnimationObject() {
311 public void initAnimation() {
312 }
314
315 public void calcFrame(double time) {
316 }
318
319 public void disposeAnimation() {
320 er.setSelected(bak.isSelected());
321 er.setLineColor(bak.getLineColor());
322 er.setLineType(bak.getLineType());
323 er.setSourceArrow(bak.getSourceArrow());
324 er.setTargetArrow(bak.getTargetArrow());
325 }
326
327 public long preferredDuration() {
328 return 0;
329 }
330 });
331 traversal.addAnimation(seq);
332 }
333
334 if (!traversal.isEmpty()) {
335 play(traversal, factory.getRepaintManager());
336 } else {
337 JOptionPane.showMessageDialog(null, i18n.getString(DEMO_NAME + ".message.selectEdge"));
338 }
339 }
340
341
344 private void animateZoom() {
345 final ViewAnimationFactory factory = createUnmanagedAnimationFactory();
346 final double newZoom = oh.getDouble("misc", "zoom_factor");
347 play(factory.zoom(newZoom, ViewAnimationFactory.APPLY_EFFECT, DEFAULT_DURATION), null);
348 }
349
350
353 private void animateMoveCamera() {
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 final Graph2D graph = view.getGraph2D();
381 {
382 final CompositeAnimationObject morph = AnimationFactory.createConcurrency();
384 final ViewAnimationFactory factory = createManagedAnimationFactory();
385
386 NodeCursor nodesToMorph = graph.selectedNodes();
387 if (!nodesToMorph.ok()) {
388 nodesToMorph = graph.nodes();
389 }
390 for (NodeCursor nc = nodesToMorph; nc.ok(); nc.next()) {
391 final NodeRealizer nr = graph.getRealizer(nc.node());
392
393 final NodeRealizer morphTarget = nr.createCopy();
395 morphTarget.moveBy(oh.getDouble("misc", "translateX"),
396 oh.getDouble("misc", "translateY"));
397 morphTarget.setSize(oh.getDouble("misc", "width"),
398 oh.getDouble("misc", "height"));
399 morphTarget.setLineColor((Color) oh.get("misc", "lineColor"));
400 morphTarget.setFillColor((Color) oh.get("misc", "fillColor"));
401 morphTarget.setFillColor2((Color) oh.get("misc", "fillColor2"));
402
403 morph.addAnimation(
404 factory.morph(
405 nr, morphTarget, ViewAnimationFactory.APPLY_EFFECT,
406 DEFAULT_DURATION));
407 }
408 if (!morph.isEmpty()) {
409 play(morph, factory.getRepaintManager());
410 } else {
411 JOptionPane.showMessageDialog(null, i18n.getString(DEMO_NAME + ".message.selectNode"));
412 }
413 }
414 }
415
416
419 private void animateResize() {
420 final Graph2D graph = view.getGraph2D();
421 final ViewAnimationFactory factory = createManagedAnimationFactory();
422
423 final CompositeAnimationObject resize = AnimationFactory.createConcurrency();
425
426 NodeCursor nodesToResize = graph.selectedNodes();
427 if (!nodesToResize.ok()) {
428 nodesToResize = graph.nodes();
429 }
430 for (NodeCursor nc = nodesToResize; nc.ok(); nc.next()) {
431 final Value2D size =
433 DefaultMutableValue2D.create(oh.getDouble("misc", "resize_width"),
434 oh.getDouble("misc", "resize_height"));
435
436 resize.addAnimation(
437 factory.resize(
438 graph.getRealizer(nc.node()), size,
439 ViewAnimationFactory.APPLY_EFFECT, SHORT_DURATION));
440 }
441 if (!resize.isEmpty()) {
442 play(resize, factory.getRepaintManager());
443 } else {
444 JOptionPane.showMessageDialog(null, i18n.getString(DEMO_NAME + ".message.selectNode"));
445 }
446 }
447
448
451 private void animateBlink() {
452 final Graph2D graph = view.getGraph2D();
453 final ViewAnimationFactory factory = createManagedAnimationFactory();
454
455 final CompositeAnimationObject blink = AnimationFactory.createConcurrency();
457
458 NodeCursor nodesToBlink = graph.selectedNodes();
459 if (!nodesToBlink.ok()) {
460 nodesToBlink = graph.nodes();
461 }
462 for (NodeCursor nc = nodesToBlink; nc.ok(); nc.next()) {
463 final int repetitions = oh.getInt("misc", "repetitions");
465 if (repetitions > 1) {
466 blink.addAnimation(
467 AnimationFactory.createRepetition(
468 factory.blink(graph.getRealizer(nc.node()),
469 SHORT_DURATION),
470 repetitions, false));
471 } else {
472 blink.addAnimation(
473 factory.blink(graph.getRealizer(nc.node()), SHORT_DURATION));
474 }
475 }
476
477 if (!blink.isEmpty()) {
478 play(blink, factory.getRepaintManager());
479 } else {
480 JOptionPane.showMessageDialog(null, i18n.getString(DEMO_NAME + ".message.selectNode"));
481 }
482 }
483
484
488 private void animateCreate(final NodeRealizer nr) {
489 nr.setVisible(false);
490
491 final ViewAnimationFactory factory = createManagedAnimationFactory();
492
493 switch (((Byte) oh.get("elements", "createNode")).byteValue()) {
495 case NO_ANIM:
496 nr.setVisible(true);
497 break;
498 case BLUR_IN:
499 play(factory.blurIn(nr, DEFAULT_DURATION),
500 factory.getRepaintManager());
501 break;
502 case FADE_IN:
503 play(factory.fadeIn(nr, DEFAULT_DURATION),
504 factory.getRepaintManager());
505 break;
506 case IMPLODE:
507 play(factory.implode(nr, DEFAULT_DURATION),
508 factory.getRepaintManager());
509 break;
510 case WHIRL_IN:
511 play(factory.whirlIn(nr, DEFAULT_DURATION),
512 factory.getRepaintManager());
513 break;
514 }
515 }
516
517
521 private void animateCreate(final EdgeRealizer er) {
522 er.setVisible(false);
523
524 final ViewAnimationFactory factory = createManagedAnimationFactory();
525
526 switch (((Byte) oh.get("elements", "createEdge")).byteValue()) {
528 case NO_ANIM:
529 er.setVisible(true);
530 break;
531 case BLUR_IN:
532 play(factory.blurIn(er, DEFAULT_DURATION),
533 factory.getRepaintManager());
534 break;
535 case FADE_IN:
536 play(factory.fadeIn(er, DEFAULT_DURATION),
537 factory.getRepaintManager());
538 break;
539 case IMPLODE:
540 play(factory.implode(er, DEFAULT_DURATION),
541 factory.getRepaintManager());
542 break;
543 case EXTRACT:
544 play(factory.extract(er, DEFAULT_DURATION),
545 factory.getRepaintManager());
546 break;
547 }
548 }
549
550
554 private void animateDelete(final NodeRealizer nr) {
555 final Graph2D graph = view.getGraph2D();
556 final ViewAnimationFactory factory = createManagedAnimationFactory();
557
558 final CompositeAnimationObject deletes =
559 AnimationFactory.createLazySequence();
560 final CompositeAnimationObject deleteEdges =
561 AnimationFactory.createConcurrency();
562
563 for (EdgeCursor ec = nr.getNode().edges(); ec.ok(); ec.next()) {
565 final EdgeRealizer er = graph.getRealizer(ec.edge());
566
567 switch (((Byte) oh.get("elements", "deleteEdge")).byteValue()) {
569 case NO_ANIM:
570 deleteEdges.addAnimation(new RemoveEdge(er, factory.getRepaintManager()));
571 break;
572 case BLUR_OUT:
573 deleteEdges.addAnimation(
574 factory.blurOut(er, ViewAnimationFactory.APPLY_EFFECT,
575 SHORT_DURATION));
576 break;
577 case FADE_OUT:
578 deleteEdges.addAnimation(
579 factory.fadeOut(er, ViewAnimationFactory.APPLY_EFFECT,
580 SHORT_DURATION));
581 break;
582 case EXPLODE:
583 deleteEdges.addAnimation(
584 factory.explode(er, ViewAnimationFactory.APPLY_EFFECT,
585 SHORT_DURATION));
586 break;
587 case RETRACT:
588 deleteEdges.addAnimation(
589 factory.retract(er, ViewAnimationFactory.APPLY_EFFECT,
590 SHORT_DURATION));
591 break;
592 }
593 }
594 if (deleteEdges.preferredDuration() > 0) {
595 deletes.addAnimation(deleteEdges);
596 }
597
598 switch (((Byte) oh.get("elements", "deleteNode")).byteValue()) {
600 case NO_ANIM:
601 deletes.addAnimation(new RemoveNode(nr, factory.getRepaintManager()));
602 break;
603 case BLUR_OUT:
604 deletes.addAnimation(
605 factory.blurOut(nr, ViewAnimationFactory.APPLY_EFFECT,
606 DEFAULT_DURATION));
607 break;
608 case FADE_OUT:
609 deletes.addAnimation(
610 factory.fadeOut(nr, ViewAnimationFactory.APPLY_EFFECT,
611 DEFAULT_DURATION));
612 break;
613 case EXPLODE:
614 deletes.addAnimation(
615 factory.explode(nr, ViewAnimationFactory.APPLY_EFFECT,
616 DEFAULT_DURATION));
617 break;
618 case WHIRL_OUT:
619 deletes.addAnimation(
620 factory.whirlOut(nr, ViewAnimationFactory.APPLY_EFFECT,
621 DEFAULT_DURATION));
622 break;
623 }
624 play(deletes, factory.getRepaintManager());
625 }
626
627
631 private void animateDelete(final EdgeRealizer er) {
632 final ViewAnimationFactory factory = createManagedAnimationFactory();
633
634 switch (((Byte) oh.get("elements", "deleteEdge")).byteValue()) {
636 case NO_ANIM:
637 play(new RemoveEdge(er, factory.getRepaintManager()),
638 factory.getRepaintManager());
639 break;
640 case BLUR_OUT:
641 play(factory.blurOut(er, ViewAnimationFactory.APPLY_EFFECT,
642 DEFAULT_DURATION),
643 factory.getRepaintManager());
644 break;
645 case FADE_OUT:
646 play(factory.fadeOut(er, ViewAnimationFactory.APPLY_EFFECT,
647 SHORT_DURATION),
648 factory.getRepaintManager());
649 break;
650 case EXPLODE:
651 play(factory.explode(er, ViewAnimationFactory.APPLY_EFFECT,
652 DEFAULT_DURATION),
653 factory.getRepaintManager());
654 break;
655 case RETRACT:
656 play(factory.retract(er, ViewAnimationFactory.APPLY_EFFECT,
657 SHORT_DURATION),
658 factory.getRepaintManager());
659 break;
660 }
661 }
662
663
666 private void animateDeleteSelection() {
667 final ViewAnimationFactory factory = createManagedAnimationFactory();
668
669 final Graph2D graph = view.getGraph2D();
670
671 final byte animatedEdgeDelete =
672 ((Byte) oh.get("elements", "deleteEdge")).byteValue();
673
674 final byte animatedNodeDelete =
675 ((Byte) oh.get("elements", "deleteNode")).byteValue();
676
677 final CompositeAnimationObject deleteEdges =
680 AnimationFactory.createConcurrency();
681
682 final EdgeMap markAsScheduled = graph.createEdgeMap();
683
684 for (EdgeCursor ec = graph.selectedEdges(); ec.ok(); ec.next()) {
686 final EdgeRealizer er = graph.getRealizer(ec.edge());
687
688 switch (animatedEdgeDelete) {
690 case NO_ANIM:
691 deleteEdges.addAnimation(new RemoveEdge(er, factory.getRepaintManager()));
692 break;
693 case BLUR_OUT:
694 deleteEdges.addAnimation(
695 factory.blurOut(er, ViewAnimationFactory.APPLY_EFFECT,
696 SHORT_DURATION));
697 break;
698 case FADE_OUT:
699 deleteEdges.addAnimation(
700 factory.fadeOut(er, ViewAnimationFactory.APPLY_EFFECT,
701 SHORT_DURATION));
702 break;
703 case EXPLODE:
704 deleteEdges.addAnimation(
705 factory.explode(er, ViewAnimationFactory.APPLY_EFFECT,
706 SHORT_DURATION));
707 break;
708 case RETRACT:
709 deleteEdges.addAnimation(
710 factory.retract(er, ViewAnimationFactory.APPLY_EFFECT,
711 SHORT_DURATION));
712 break;
713 }
714 markAsScheduled.setBool(ec.edge(), true);
715 }
716
717 for (NodeCursor nc = graph.selectedNodes(); nc.ok(); nc.next()) {
719 for (EdgeCursor ec = nc.node().edges(); ec.ok(); ec.next()) {
720 if (!markAsScheduled.getBool(ec.edge())) {
721 final EdgeRealizer er = graph.getRealizer(ec.edge());
722
723 switch (animatedEdgeDelete) {
725 case NO_ANIM:
726 deleteEdges.addAnimation(new RemoveEdge(er, factory.getRepaintManager()));
727 break;
728 case BLUR_OUT:
729 deleteEdges.addAnimation(
730 factory.blurOut(er, ViewAnimationFactory.APPLY_EFFECT,
731 SHORT_DURATION));
732 break;
733 case FADE_OUT:
734 deleteEdges.addAnimation(
735 factory.fadeOut(er, ViewAnimationFactory.APPLY_EFFECT,
736 SHORT_DURATION));
737 break;
738 case EXPLODE:
739 deleteEdges.addAnimation(
740 factory.explode(er, ViewAnimationFactory.APPLY_EFFECT,
741 SHORT_DURATION));
742 break;
743 case RETRACT:
744 deleteEdges.addAnimation(
745 factory.retract(er, ViewAnimationFactory.APPLY_EFFECT,
746 SHORT_DURATION));
747 break;
748 }
749 markAsScheduled.setBool(ec.edge(), true);
750 }
751 }
752 }
753
754 graph.disposeEdgeMap(markAsScheduled);
755
756 final CompositeAnimationObject deleteNodes =
759 AnimationFactory.createConcurrency();
760
761 for (NodeCursor nc = graph.selectedNodes(); nc.ok(); nc.next()) {
762 final NodeRealizer nr = graph.getRealizer(nc.node());
763
764 switch (animatedNodeDelete) {
766 case NO_ANIM:
767 deleteNodes.addAnimation(new RemoveNode(nr, factory.getRepaintManager()));
768 break;
769 case BLUR_OUT:
770 deleteNodes.addAnimation(
771 factory.blurOut(nr, ViewAnimationFactory.APPLY_EFFECT,
772 DEFAULT_DURATION));
773 break;
774 case FADE_OUT:
775 deleteNodes.addAnimation(
776 factory.fadeOut(nr, ViewAnimationFactory.APPLY_EFFECT,
777 DEFAULT_DURATION));
778 break;
779 case EXPLODE:
780 deleteNodes.addAnimation(
781 factory.explode(nr, ViewAnimationFactory.APPLY_EFFECT,
782 LONG_DURATION));
783 break;
784 case WHIRL_OUT:
785 deleteNodes.addAnimation(
786 factory.whirlOut(nr, ViewAnimationFactory.APPLY_EFFECT,
787 DEFAULT_DURATION));
788 break;
789 }
790 }
791
792
794 final CompositeAnimationObject deletes = AnimationFactory.createLazySequence();
797
798 if (!deleteEdges.isEmpty()) {
799 deletes.addAnimation(deleteEdges);
800 }
801 if (!deleteNodes.isEmpty()) {
802 deletes.addAnimation(deleteNodes);
803 }
804 if (!deletes.isEmpty()) {
805 play(deletes, factory.getRepaintManager());
806 }
807 }
808
809
813 private void play(final AnimationObject ao, final Graph2DViewRepaintManager arm) {
814 player.addAnimationListener(new AutoRemoveListener(arm != null
815 ? (AnimationListener) arm
816 : view));
817 player.setSpeed(oh.getDouble("global", "speed"));
818 player.animate(ao);
819 }
820
821
822
825 private ViewAnimationFactory createUnmanagedAnimationFactory() {
826 return unmanagedFactory;
827 }
828
829
833 private ViewAnimationFactory createManagedAnimationFactory() {
834 final ViewAnimationFactory factory =
835 new ViewAnimationFactory(new Graph2DViewRepaintManager(view));
836 factory.setQuality(ViewAnimationFactory.HIGH_QUALITY);
837 return factory;
838 }
839
840
844 private Action createCreateEdgeAction() {
845 final Action create = new AbstractAction() {
846 public void actionPerformed(final ActionEvent e) {
847 final Graph2D graph = view.getGraph2D();
848
849 Node lastNode = null;
850 for (NodeCursor nc = graph.selectedNodes(); nc.ok(); nc.next()) {
851 if (lastNode != null) {
852 final EdgeRealizer er = new PolyLineEdgeRealizer();
853 er.setVisible(false);
854 graph.createEdge(lastNode, nc.node(), er);
855 animateCreate(er);
856 }
857 lastNode = nc.node();
858 }
859
860 if (lastNode == null) {
861 JOptionPane.showMessageDialog(null, i18n.getString(DEMO_NAME + ".message.selectNodes"));
862 }
863 }
864 };
865 localizeAction(create, DEMO_NAME + ".action.CreateEdge");
866
867 return create;
868 }
869
870
874 private Action createDeleteSelectionAction() {
875 final Action delete = new AbstractAction() {
876 public void actionPerformed(final ActionEvent e) {
877 animateDeleteSelection();
878 }
879 };
880 localizeAction(delete, DEMO_NAME + ".action.DeleteSelection");
881
882 return delete;
883 }
884
885
889 private Action createDeleteNodeAction() {
890 final Action delete = new AbstractAction() {
891 public void actionPerformed(final ActionEvent e) {
892 final Graph2D graph = view.getGraph2D();
893 final NodeCursor nc = graph.selectedNodes();
894 if (nc.ok()) {
895 animateDelete(graph.getRealizer(nc.node()));
896 }
898 }
899 };
900 localizeAction(delete, DEMO_NAME + ".action.DeleteNode");
901
902 return delete;
903 }
904
905
909 private Action createDeleteEdgeAction() {
910 final Action delete = new AbstractAction() {
911 public void actionPerformed(final ActionEvent e) {
912 final Graph2D graph = view.getGraph2D();
913 final EdgeCursor ec = graph.selectedEdges();
914 if (ec.ok()) {
915 animateDelete(graph.getRealizer(ec.edge()));
916 }
917 }
918 };
919 localizeAction(delete, DEMO_NAME + ".action.DeleteEdge");
920
921 return delete;
922 }
923
924
925
929 private void registerGraphListener() {
930 final Graph2D graph = view.getGraph2D();
931 graph.addGraphListener(new GraphListener() {
932 public void onGraphEvent(final GraphEvent e) {
933 if (GraphEvent.NODE_CREATION == e.getType() && !compoundAction) {
934 animateCreate(graph.getRealizer((Node) e.getData()));
935 } else if (GraphEvent.EDGE_CREATION == e.getType() && !compoundAction) {
936 EdgeRealizer edgeRealizer = graph.getRealizer((Edge) e.getData());
937 edgeRealizer.setLineColor((Color) oh.get("misc", "colorUnvisited"));
938 edgeRealizer.setTargetArrow(Arrow.STANDARD);
939 edgeRealizer.setLineType(LineType.LINE_1);
940 animateCreate(edgeRealizer);
941 }
942 }
943 });
944 }
945
946
950 private void registerEditMode() {
951 EditMode editMode = new EditMode();
952 editMode.allowMovingWithPopup(true);
953
954 PopupMode popupMode = new PopupMode() {
955 private final Action createEdge = createCreateEdgeAction();
956 private final Action deleteNode = createDeleteNodeAction();
957 private final Action deleteEdge = createDeleteEdgeAction();
958
959 public JPopupMenu getSelectionPopup(double x, double y) {
960 final JPopupMenu menu = new JPopupMenu();
961 menu.add(createEdge);
962 return menu;
963 }
964
965 public JPopupMenu getNodePopup(final Node v) {
966 final JPopupMenu menu = new JPopupMenu();
967 menu.add(deleteNode);
968 return menu;
969 }
970
971 public JPopupMenu getEdgePopup(final Edge e) {
972 final JPopupMenu menu = new JPopupMenu();
973 menu.add(deleteEdge);
974 return menu;
975 }
976 };
977 editMode.setPopupMode(popupMode);
978 view.addViewMode(editMode);
979 }
980
981
984 private void registerActions() {
985 final ActionMap amap = new ActionMap();
986 amap.put("DELETE_SELECTION", createDeleteSelectionAction());
987 final InputMap imap = new InputMap();
988 imap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "DELETE_SELECTION");
989 view.getCanvasComponent().setActionMap(amap);
990 view.getCanvasComponent().setInputMap(JComponent.WHEN_FOCUSED, imap);
991 }
992
993
994 public void addContentTo(final JRootPane rootPane) {
995 openGraph(i18n.getString(DEMO_NAME + ".RESOURCE.graph.small"));
996 registerGraphListener();
997 registerEditMode();
998 registerActions();
999 rootPane.setContentPane(createContentPane());
1000 }
1001
1002 public static void main(String[] args) {
1003 EventQueue.invokeLater(new Runnable() {
1004 public void run() {
1005 DemoDefaults.initLnF();
1006 final GuiFactory gf = createGuiFactory();
1007 final AnimationEffectsDemo demo = new AnimationEffectsDemo(gf, true);
1008 final JFrame frame = new JFrame(gf.getString(DEMO_NAME + ".title"));
1009 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
1010 demo.addContentTo(frame.getRootPane());
1011 frame.pack();
1012 frame.setLocationRelativeTo(null);
1013 frame.setVisible(true);
1014 }
1015 });
1016 }
1017
1018 private static GuiFactory createGuiFactory() {
1019 try {
1020 final ResourceBundleGuiFactory i18n = new ResourceBundleGuiFactory();
1021 i18n.addBundle(AnimationEffectsDemo.class.getName());
1022 return i18n;
1023 }
1024 catch (final MissingResourceException mre) {
1025 System.err.println("Could not find resources! " + mre);
1026 return new GuiFactory() {
1027 public JButton createButton(final String action) {
1028 return new JButton(action);
1029 }
1030
1031 public String getString(final String key) {
1032 return key;
1033 }
1034
1035 public Action createHelpAction(final String helpKey) {
1036 return null;
1037 }
1038 };
1039 }
1040 }
1041
1042
1046 private final class AutoRemoveListener implements AnimationListener {
1047 private final AnimationListener delegate;
1048
1049 AutoRemoveListener(final AnimationListener delegate) {
1050 this.delegate = delegate;
1051 }
1052
1053 public void animationPerformed(final AnimationEvent e) {
1054 delegate.animationPerformed(e);
1055 if (AnimationEvent.END == e.getHint()) {
1056 player.removeAnimationListener(this);
1057 }
1058 }
1059 }
1060
1061
1065 private final class EndHandler implements AnimationListener {
1066 private boolean clear;
1067
1068 EndHandler() {
1069 this.clear = false;
1070 }
1071
1072 void setClear(final boolean clear) {
1073 this.clear = clear;
1074 }
1075
1076 public void animationPerformed(final AnimationEvent e) {
1077 if (AnimationEvent.END == e.getHint()) {
1078 if (clear) {
1079 view.getGraph2D().clear();
1080 view.fitContent();
1081 clear = false;
1082 }
1083 view.updateView();
1084 }
1085 }
1086 }
1087
1088
1094 private static final class RemoveNode implements AnimationObject {
1095 private NodeRealizer realizer;
1096 private Graph2DViewRepaintManager manager;
1097
1098 public RemoveNode(final NodeRealizer realizer,
1099 final Graph2DViewRepaintManager manager) {
1100 this.realizer = realizer;
1101 this.manager = manager;
1102 }
1103
1104 public void initAnimation() {
1105 if (manager != null) {
1106 manager.add(realizer);
1107 }
1108 }
1109
1110 public void calcFrame(final double time) {
1111 }
1112
1113 public void disposeAnimation() {
1114 final Node node = realizer.getNode();
1115 node.getGraph().removeNode(node);
1116
1117 if (manager != null) {
1118 manager.remove(realizer);
1119 manager = null;
1120 }
1121
1122 realizer = null;
1123 }
1124
1125 public long preferredDuration() {
1126 return 10;
1127 }
1128 }
1129
1130
1136 private static final class RemoveEdge implements AnimationObject {
1137 private EdgeRealizer realizer;
1138 private Graph2DViewRepaintManager manager;
1139
1140 public RemoveEdge(final EdgeRealizer realizer,
1141 final Graph2DViewRepaintManager manager) {
1142 this.realizer = realizer;
1143 this.manager = manager;
1144 }
1145
1146 public void initAnimation() {
1147 if (manager != null) {
1148 manager.add(realizer);
1149 }
1150 }
1151
1152 public void calcFrame(final double time) {
1153 }
1154
1155 public void disposeAnimation() {
1156 final Edge edge = realizer.getEdge();
1157 edge.getGraph().removeEdge(edge);
1158
1159 if (manager != null) {
1160 manager.remove(realizer);
1161 manager = null;
1162 }
1163
1164 realizer = null;
1165 }
1166
1167 public long preferredDuration() {
1168 return 10;
1169 }
1170 }
1171}
1172