1
14 package demo.view.anim;
15
16 import demo.view.DemoDefaults;
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.GuiFactory;
31 import y.option.ResourceBundleGuiFactory;
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.JButton;
50 import javax.swing.JComponent;
51 import javax.swing.JFrame;
52 import javax.swing.JOptionPane;
53 import javax.swing.JPopupMenu;
54 import javax.swing.JRootPane;
55 import javax.swing.KeyStroke;
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
77 public final class AnimationEffectsDemo extends AnimationEffectsDemoBase {
78 private static final long LONG_DURATION = 2000;
79 private static final long SHORT_DURATION = 500;
80 private static final long DEFAULT_DURATION = 1000;
81 private static final long PREFERRED_DURATION_CAMERA = 10000;
82 private static final long PREFERRED_DURATION_GRAPH = 5000;
83 private static final long PREFERRED_DURATION_TRAVERSAL = 2000;
84
85 private final AnimationPlayer player;
86 private final EndHandler endHandler;
87 private final ViewAnimationFactory unmanagedFactory;
88
89
92 public AnimationEffectsDemo() {
93 this(createGuiFactory(), false);
94 }
95
96
99 private AnimationEffectsDemo(
100 final GuiFactory i18n,
101 final boolean wantsRadioButtons
102 ) {
103 super(i18n, wantsRadioButtons);
104 this.endHandler = new EndHandler();
105 this.player = new AnimationPlayer();
106 this.player.setFps(240);
107 this.player.addAnimationListener(endHandler);
108 this.player.setBlocking(false);
109 this.unmanagedFactory = new ViewAnimationFactory(view);
110
111 configureDefaultRealizers();
112
113 EdgeRealizer edgeRealizer = view.getGraph2D().getDefaultEdgeRealizer();
114 edgeRealizer.setLineColor(Color.LIGHT_GRAY);
115 edgeRealizer.setTargetArrow(Arrow.NONE);
116 edgeRealizer.setLineType(LineType.DASHED_2);
117 }
118
119 protected void configureDefaultRealizers() {
120 DemoDefaults.configureDefaultRealizers(view);
121 }
122
123
124
127 void animate() {
128 if (player.isPlaying()) {
129 return;
130 }
131
132 switch (((Byte) oh.get("misc", "animation")).byteValue()) {
133 case NO_ANIM:
134 break;
135 case ANIMATED_LOAD:
136 animatedLoad();
137 break;
138 case ANIMATED_CLEAR:
139 animatedClear();
140 break;
141 case TRAVERSE_EDGE:
142 animateTraverseEdge();
143 break;
144 case ZOOM:
145 animateZoom();
146 break;
147 case MOVE_CAMERA:
148 animateMoveCamera();
149 break;
150 case MORPH:
151 animateMorph();
152 break;
153 case RESIZE:
154 animateResize();
155 break;
156 case BLINK:
157 animateBlink();
158 break;
159 }
160 }
161
162
165 private void animatedLoad() {
166 compoundAction = true;
167
168 openGraph(i18n.getString(DEMO_NAME + ".RESOURCE.graph." +
169 oh.get("misc", "animateLoad_graph")));
170
171 final Graph2D graph = view.getGraph2D();
172
173 if (graph.nodeCount() > 0) {
174 final ViewAnimationFactory factory = createManagedAnimationFactory();
175 play(factory.fadeIn(graph,
176 (ViewAnimationFactory.NodeOrder) oh.get("misc", "animateLoad_nodeOrder"),
177 oh.getBool("misc", "animateLoad_obeyEdgeDirection"),
178 oh.getDouble("misc", "animateLoad_ratio"),
179 PREFERRED_DURATION_GRAPH),
180 factory.getRepaintManager());
181
182 }
183
184 compoundAction = false;
185 }
186
187
190 private void animatedClear() {
191 compoundAction = true;
192
193 final Graph2D graph = view.getGraph2D();
194 if (graph.nodeCount() < 1) {
195 openGraph(i18n.getString(DEMO_NAME + ".RESOURCE.graph.big"));
196 }
197
198 if (graph.nodeCount() > 0) {
199 final ViewAnimationFactory factory = createManagedAnimationFactory();
200 factory.setQuality(ViewAnimationFactory.HIGH_QUALITY);
201 endHandler.setClear(true);
202 play(factory.fadeOut(graph,
203 (ViewAnimationFactory.NodeOrder) oh.get("misc", "animateClear_nodeOrder"),
204 oh.getBool("misc", "animateClear_obeyEdgeDirection"),
205 oh.getDouble("misc", "animateClear_ratio"),
206 PREFERRED_DURATION_GRAPH),
207 factory.getRepaintManager());
208 }
209
210 compoundAction = false;
211 }
212
213
216 private void animateTraverseEdge() {
217 final Graph2D graph = view.getGraph2D();
218 final ViewAnimationFactory factory = createManagedAnimationFactory();
219
220 final CompositeAnimationObject traversal = AnimationFactory.createConcurrency();
223
224 EdgeCursor edgesToTraverse = graph.selectedEdges();
225 if (!edgesToTraverse.ok()) {
226 edgesToTraverse = graph.edges();
227 }
228 for (EdgeCursor ec = edgesToTraverse; ec.ok(); ec.next()) {
229 final EdgeRealizer er = graph.getRealizer(ec.edge());
231 er.setVisible(true);
232
233 final EdgeRealizer bak = er.createCopy();
234
235 final EdgeRealizer unvisited1 = er.createCopy();
238 unvisited1.setLineColor((Color) oh.get("misc", "colorUnvisited"));
239
242 final EdgeRealizer unvisited2 = er.createCopy();
243 unvisited2.setLineColor((Color) oh.get("misc", "colorVisited"));
244 unvisited2.setLineType(LineType.LINE_2);
245 unvisited2.setSourceArrow(Arrow.NONE);
246 unvisited2.setTargetArrow(Arrow.NONE);
247
248 final EdgeRealizer visited1 = er.createCopy();
251 visited1.setLineColor(unvisited2.getLineColor());
252 visited1.setLineType(LineType.LINE_2);
253 visited1.setSourceArrow(Arrow.NONE);
254 visited1.setTargetArrow(Arrow.NONE);
255
256 final EdgeRealizer visited2 = er.createCopy();
257 visited2.setLineColor(unvisited1.getLineColor());
258
261 final CompositeAnimationObject seq = AnimationFactory.createLazySequence();
265 seq.addAnimation(
266 factory.traverseEdge(er, visited1, unvisited1, true,
267 ViewAnimationFactory.RESET_EFFECT,
268 PREFERRED_DURATION_TRAVERSAL));
269
270 seq.addAnimation(new AnimationObject() {
272 public void initAnimation() {
273 er.setLineType(visited1.getLineType());
274 er.setLineColor(visited1.getLineColor());
275 }
276
277 public void calcFrame(double time) {
278 }
280
281 public void disposeAnimation() {
282 }
284
285 public long preferredDuration() {
286 return 0;
287 }
288 });
289 seq.addAnimation(AnimationFactory.createPause(500));
290 seq.addAnimation(
291 factory.traverseEdge(er, visited2, unvisited2, false,
292 ViewAnimationFactory.APPLY_EFFECT,
293 PREFERRED_DURATION_TRAVERSAL));
294
295 seq.addAnimation(new AnimationObject() {
297 public void initAnimation() {
298 }
300
301 public void calcFrame(double time) {
302 }
304
305 public void disposeAnimation() {
306 er.setSelected(bak.isSelected());
307 er.setLineColor(bak.getLineColor());
308 er.setLineType(bak.getLineType());
309 er.setSourceArrow(bak.getSourceArrow());
310 er.setTargetArrow(bak.getTargetArrow());
311 }
312
313 public long preferredDuration() {
314 return 0;
315 }
316 });
317 traversal.addAnimation(seq);
318 }
319
320 if (!traversal.isEmpty()) {
321 play(traversal, factory.getRepaintManager());
322 } else {
323 JOptionPane.showMessageDialog(null, i18n.getString(DEMO_NAME + ".message.selectEdge"));
324 }
325 }
326
327
330 private void animateZoom() {
331 final ViewAnimationFactory factory = createUnmanagedAnimationFactory();
332 final double newZoom = oh.getDouble("misc", "zoom_factor");
333 play(factory.zoom(newZoom, ViewAnimationFactory.APPLY_EFFECT, DEFAULT_DURATION), null);
334 }
335
336
339 private void animateMoveCamera() {
340 final double x1 = view.toWorldCoordX(0);
341 final double x2 = view.toWorldCoordX(view.getWidth());
342 final double y1 = view.toWorldCoordY(0);
343 final double y2 = view.toWorldCoordY(view.getHeight());
344
345 final GeneralPath path = new GeneralPath();
347 path.moveTo((float) ((x1 + x2) * 0.5), (float) ((y1 + y2) * 0.5));
348 path.lineTo((float) (x1 + 0.15 * (x2 - x1)), (float) (y1 + 0.15 * (y2 - y1)));
349 path.lineTo((float) (x2 - 0.15 * (x2 - x1)), (float) (y1 + 0.15 * (y2 - y1)));
350 path.lineTo((float) ((x1 + x2) * 0.5), (float) ((y1 + y2) * 0.5));
351 path.lineTo((float) (x2 - 0.15 * (x2 - x1)), (float) (y2 - 0.15 * (y2 - y1)));
352 path.lineTo((float) (x1 + 0.15 * (x2 - x1)), (float) (y2 - 0.15 * (y2 - y1)));
353 path.quadTo((float) ((x1 + x2) * 0.5), (float) ((y1 + y2) * 0.5),
354 (float) (x1 + 0.15 * (x2 - x1)), (float) (y1 + 0.25 * (y2 - y1)));
355 path.quadTo((float) ((x1 + x2) * 0.5), (float) (y2 - 0.25 * (y2 - y1)),
356 (float) ((x1 + x2) * 0.5), (float) ((y1 + y2) * 0.5));
357
358 final ViewAnimationFactory factory = createUnmanagedAnimationFactory();
359 play(factory.moveCamera(path, PREFERRED_DURATION_CAMERA), null);
360 }
361
362
365 private void animateMorph() {
366 final Graph2D graph = view.getGraph2D();
367 {
368 final CompositeAnimationObject morph = AnimationFactory.createConcurrency();
370 final ViewAnimationFactory factory = createManagedAnimationFactory();
371
372 NodeCursor nodesToMorph = graph.selectedNodes();
373 if (!nodesToMorph.ok()) {
374 nodesToMorph = graph.nodes();
375 }
376 for (NodeCursor nc = nodesToMorph; nc.ok(); nc.next()) {
377 final NodeRealizer nr = graph.getRealizer(nc.node());
378
379 final NodeRealizer morphTarget = nr.createCopy();
381 morphTarget.moveBy(oh.getDouble("misc", "translateX"),
382 oh.getDouble("misc", "translateY"));
383 morphTarget.setSize(oh.getDouble("misc", "width"),
384 oh.getDouble("misc", "height"));
385 morphTarget.setLineColor((Color) oh.get("misc", "lineColor"));
386 morphTarget.setFillColor((Color) oh.get("misc", "fillColor"));
387 morphTarget.setFillColor2((Color) oh.get("misc", "fillColor2"));
388
389 morph.addAnimation(
390 factory.morph(
391 nr, morphTarget, ViewAnimationFactory.APPLY_EFFECT,
392 DEFAULT_DURATION));
393 }
394 if (!morph.isEmpty()) {
395 play(morph, factory.getRepaintManager());
396 } else {
397 JOptionPane.showMessageDialog(null, i18n.getString(DEMO_NAME + ".message.selectNode"));
398 }
399 }
400 }
401
402
405 private void animateResize() {
406 final Graph2D graph = view.getGraph2D();
407 final ViewAnimationFactory factory = createManagedAnimationFactory();
408
409 final CompositeAnimationObject resize = AnimationFactory.createConcurrency();
411
412 NodeCursor nodesToResize = graph.selectedNodes();
413 if (!nodesToResize.ok()) {
414 nodesToResize = graph.nodes();
415 }
416 for (NodeCursor nc = nodesToResize; nc.ok(); nc.next()) {
417 final Value2D size =
419 DefaultMutableValue2D.create(oh.getDouble("misc", "resize_width"),
420 oh.getDouble("misc", "resize_height"));
421
422 resize.addAnimation(
423 factory.resize(
424 graph.getRealizer(nc.node()), size,
425 ViewAnimationFactory.APPLY_EFFECT, SHORT_DURATION));
426 }
427 if (!resize.isEmpty()) {
428 play(resize, factory.getRepaintManager());
429 } else {
430 JOptionPane.showMessageDialog(null, i18n.getString(DEMO_NAME + ".message.selectNode"));
431 }
432 }
433
434
437 private void animateBlink() {
438 final Graph2D graph = view.getGraph2D();
439 final ViewAnimationFactory factory = createManagedAnimationFactory();
440
441 final CompositeAnimationObject blink = AnimationFactory.createConcurrency();
443
444 NodeCursor nodesToBlink = graph.selectedNodes();
445 if (!nodesToBlink.ok()) {
446 nodesToBlink = graph.nodes();
447 }
448 for (NodeCursor nc = nodesToBlink; nc.ok(); nc.next()) {
449 final int repetitions = oh.getInt("misc", "repetitions");
451 if (repetitions > 1) {
452 blink.addAnimation(
453 AnimationFactory.createRepetition(
454 factory.blink(graph.getRealizer(nc.node()),
455 SHORT_DURATION),
456 repetitions, false));
457 } else {
458 blink.addAnimation(
459 factory.blink(graph.getRealizer(nc.node()), SHORT_DURATION));
460 }
461 }
462
463 if (!blink.isEmpty()) {
464 play(blink, factory.getRepaintManager());
465 } else {
466 JOptionPane.showMessageDialog(null, i18n.getString(DEMO_NAME + ".message.selectNode"));
467 }
468 }
469
470
474 private void animateCreate(final NodeRealizer nr) {
475 nr.setVisible(false);
476
477 final ViewAnimationFactory factory = createManagedAnimationFactory();
478
479 switch (((Byte) oh.get("elements", "createNode")).byteValue()) {
481 case NO_ANIM:
482 nr.setVisible(true);
483 break;
484 case BLUR_IN:
485 play(factory.blurIn(nr, DEFAULT_DURATION),
486 factory.getRepaintManager());
487 break;
488 case FADE_IN:
489 play(factory.fadeIn(nr, DEFAULT_DURATION),
490 factory.getRepaintManager());
491 break;
492 case IMPLODE:
493 play(factory.implode(nr, DEFAULT_DURATION),
494 factory.getRepaintManager());
495 break;
496 case WHIRL_IN:
497 play(factory.whirlIn(nr, DEFAULT_DURATION),
498 factory.getRepaintManager());
499 break;
500 }
501 }
502
503
507 private void animateCreate(final EdgeRealizer er) {
508 er.setVisible(false);
509
510 final ViewAnimationFactory factory = createManagedAnimationFactory();
511
512 switch (((Byte) oh.get("elements", "createEdge")).byteValue()) {
514 case NO_ANIM:
515 er.setVisible(true);
516 break;
517 case BLUR_IN:
518 play(factory.blurIn(er, DEFAULT_DURATION),
519 factory.getRepaintManager());
520 break;
521 case FADE_IN:
522 play(factory.fadeIn(er, DEFAULT_DURATION),
523 factory.getRepaintManager());
524 break;
525 case IMPLODE:
526 play(factory.implode(er, DEFAULT_DURATION),
527 factory.getRepaintManager());
528 break;
529 case EXTRACT:
530 play(factory.extract(er, DEFAULT_DURATION),
531 factory.getRepaintManager());
532 break;
533 }
534 }
535
536
540 private void animateDelete(final NodeRealizer nr) {
541 final Graph2D graph = view.getGraph2D();
542 final ViewAnimationFactory factory = createManagedAnimationFactory();
543
544 final CompositeAnimationObject deletes =
545 AnimationFactory.createLazySequence();
546 final CompositeAnimationObject deleteEdges =
547 AnimationFactory.createConcurrency();
548
549 for (EdgeCursor ec = nr.getNode().edges(); ec.ok(); ec.next()) {
551 final EdgeRealizer er = graph.getRealizer(ec.edge());
552
553 switch (((Byte) oh.get("elements", "deleteEdge")).byteValue()) {
555 case NO_ANIM:
556 deleteEdges.addAnimation(new RemoveEdge(er, factory.getRepaintManager()));
557 break;
558 case BLUR_OUT:
559 deleteEdges.addAnimation(
560 factory.blurOut(er, ViewAnimationFactory.APPLY_EFFECT,
561 SHORT_DURATION));
562 break;
563 case FADE_OUT:
564 deleteEdges.addAnimation(
565 factory.fadeOut(er, ViewAnimationFactory.APPLY_EFFECT,
566 SHORT_DURATION));
567 break;
568 case EXPLODE:
569 deleteEdges.addAnimation(
570 factory.explode(er, ViewAnimationFactory.APPLY_EFFECT,
571 SHORT_DURATION));
572 break;
573 case RETRACT:
574 deleteEdges.addAnimation(
575 factory.retract(er, ViewAnimationFactory.APPLY_EFFECT,
576 SHORT_DURATION));
577 break;
578 }
579 }
580 if (deleteEdges.preferredDuration() > 0) {
581 deletes.addAnimation(deleteEdges);
582 }
583
584 switch (((Byte) oh.get("elements", "deleteNode")).byteValue()) {
586 case NO_ANIM:
587 deletes.addAnimation(new RemoveNode(nr, factory.getRepaintManager()));
588 break;
589 case BLUR_OUT:
590 deletes.addAnimation(
591 factory.blurOut(nr, ViewAnimationFactory.APPLY_EFFECT,
592 DEFAULT_DURATION));
593 break;
594 case FADE_OUT:
595 deletes.addAnimation(
596 factory.fadeOut(nr, ViewAnimationFactory.APPLY_EFFECT,
597 DEFAULT_DURATION));
598 break;
599 case EXPLODE:
600 deletes.addAnimation(
601 factory.explode(nr, ViewAnimationFactory.APPLY_EFFECT,
602 DEFAULT_DURATION));
603 break;
604 case WHIRL_OUT:
605 deletes.addAnimation(
606 factory.whirlOut(nr, ViewAnimationFactory.APPLY_EFFECT,
607 DEFAULT_DURATION));
608 break;
609 }
610 play(deletes, factory.getRepaintManager());
611 }
612
613
617 private void animateDelete(final EdgeRealizer er) {
618 final ViewAnimationFactory factory = createManagedAnimationFactory();
619
620 switch (((Byte) oh.get("elements", "deleteEdge")).byteValue()) {
622 case NO_ANIM:
623 play(new RemoveEdge(er, factory.getRepaintManager()),
624 factory.getRepaintManager());
625 break;
626 case BLUR_OUT:
627 play(factory.blurOut(er, ViewAnimationFactory.APPLY_EFFECT,
628 DEFAULT_DURATION),
629 factory.getRepaintManager());
630 break;
631 case FADE_OUT:
632 play(factory.fadeOut(er, ViewAnimationFactory.APPLY_EFFECT,
633 SHORT_DURATION),
634 factory.getRepaintManager());
635 break;
636 case EXPLODE:
637 play(factory.explode(er, ViewAnimationFactory.APPLY_EFFECT,
638 DEFAULT_DURATION),
639 factory.getRepaintManager());
640 break;
641 case RETRACT:
642 play(factory.retract(er, ViewAnimationFactory.APPLY_EFFECT,
643 SHORT_DURATION),
644 factory.getRepaintManager());
645 break;
646 }
647 }
648
649
652 private void animateDeleteSelection() {
653 final ViewAnimationFactory factory = createManagedAnimationFactory();
654
655 final Graph2D graph = view.getGraph2D();
656
657 final byte animatedEdgeDelete =
658 ((Byte) oh.get("elements", "deleteEdge")).byteValue();
659
660 final byte animatedNodeDelete =
661 ((Byte) oh.get("elements", "deleteNode")).byteValue();
662
663 final CompositeAnimationObject deleteEdges =
666 AnimationFactory.createConcurrency();
667
668 final EdgeMap markAsScheduled = graph.createEdgeMap();
669
670 for (EdgeCursor ec = graph.selectedEdges(); ec.ok(); ec.next()) {
672 final EdgeRealizer er = graph.getRealizer(ec.edge());
673
674 switch (animatedEdgeDelete) {
676 case NO_ANIM:
677 deleteEdges.addAnimation(new RemoveEdge(er, factory.getRepaintManager()));
678 break;
679 case BLUR_OUT:
680 deleteEdges.addAnimation(
681 factory.blurOut(er, ViewAnimationFactory.APPLY_EFFECT,
682 SHORT_DURATION));
683 break;
684 case FADE_OUT:
685 deleteEdges.addAnimation(
686 factory.fadeOut(er, ViewAnimationFactory.APPLY_EFFECT,
687 SHORT_DURATION));
688 break;
689 case EXPLODE:
690 deleteEdges.addAnimation(
691 factory.explode(er, ViewAnimationFactory.APPLY_EFFECT,
692 SHORT_DURATION));
693 break;
694 case RETRACT:
695 deleteEdges.addAnimation(
696 factory.retract(er, ViewAnimationFactory.APPLY_EFFECT,
697 SHORT_DURATION));
698 break;
699 }
700 markAsScheduled.setBool(ec.edge(), true);
701 }
702
703 for (NodeCursor nc = graph.selectedNodes(); nc.ok(); nc.next()) {
705 for (EdgeCursor ec = nc.node().edges(); ec.ok(); ec.next()) {
706 if (!markAsScheduled.getBool(ec.edge())) {
707 final EdgeRealizer er = graph.getRealizer(ec.edge());
708
709 switch (animatedEdgeDelete) {
711 case NO_ANIM:
712 deleteEdges.addAnimation(new RemoveEdge(er, factory.getRepaintManager()));
713 break;
714 case BLUR_OUT:
715 deleteEdges.addAnimation(
716 factory.blurOut(er, ViewAnimationFactory.APPLY_EFFECT,
717 SHORT_DURATION));
718 break;
719 case FADE_OUT:
720 deleteEdges.addAnimation(
721 factory.fadeOut(er, ViewAnimationFactory.APPLY_EFFECT,
722 SHORT_DURATION));
723 break;
724 case EXPLODE:
725 deleteEdges.addAnimation(
726 factory.explode(er, ViewAnimationFactory.APPLY_EFFECT,
727 SHORT_DURATION));
728 break;
729 case RETRACT:
730 deleteEdges.addAnimation(
731 factory.retract(er, ViewAnimationFactory.APPLY_EFFECT,
732 SHORT_DURATION));
733 break;
734 }
735 markAsScheduled.setBool(ec.edge(), true);
736 }
737 }
738 }
739
740 graph.disposeEdgeMap(markAsScheduled);
741
742 final CompositeAnimationObject deleteNodes =
745 AnimationFactory.createConcurrency();
746
747 for (NodeCursor nc = graph.selectedNodes(); nc.ok(); nc.next()) {
748 final NodeRealizer nr = graph.getRealizer(nc.node());
749
750 switch (animatedNodeDelete) {
752 case NO_ANIM:
753 deleteNodes.addAnimation(new RemoveNode(nr, factory.getRepaintManager()));
754 break;
755 case BLUR_OUT:
756 deleteNodes.addAnimation(
757 factory.blurOut(nr, ViewAnimationFactory.APPLY_EFFECT,
758 DEFAULT_DURATION));
759 break;
760 case FADE_OUT:
761 deleteNodes.addAnimation(
762 factory.fadeOut(nr, ViewAnimationFactory.APPLY_EFFECT,
763 DEFAULT_DURATION));
764 break;
765 case EXPLODE:
766 deleteNodes.addAnimation(
767 factory.explode(nr, ViewAnimationFactory.APPLY_EFFECT,
768 LONG_DURATION));
769 break;
770 case WHIRL_OUT:
771 deleteNodes.addAnimation(
772 factory.whirlOut(nr, ViewAnimationFactory.APPLY_EFFECT,
773 DEFAULT_DURATION));
774 break;
775 }
776 }
777
778
780 final CompositeAnimationObject deletes = AnimationFactory.createLazySequence();
783
784 if (!deleteEdges.isEmpty()) {
785 deletes.addAnimation(deleteEdges);
786 }
787 if (!deleteNodes.isEmpty()) {
788 deletes.addAnimation(deleteNodes);
789 }
790 if (!deletes.isEmpty()) {
791 play(deletes, factory.getRepaintManager());
792 }
793 }
794
795
799 private void play(final AnimationObject ao, final Graph2DViewRepaintManager arm) {
800 player.addAnimationListener(new AutoRemoveListener(arm != null
801 ? (AnimationListener) arm
802 : view));
803 player.setSpeed(oh.getDouble("global", "speed"));
804 player.animate(ao);
805 }
806
807
808
811 private ViewAnimationFactory createUnmanagedAnimationFactory() {
812 return unmanagedFactory;
813 }
814
815
819 private ViewAnimationFactory createManagedAnimationFactory() {
820 final ViewAnimationFactory factory =
821 new ViewAnimationFactory(new Graph2DViewRepaintManager(view));
822 factory.setQuality(ViewAnimationFactory.HIGH_QUALITY);
823 return factory;
824 }
825
826
830 private Action createCreateEdgeAction() {
831 final Action create = new AbstractAction() {
832 public void actionPerformed(final ActionEvent e) {
833 final Graph2D graph = view.getGraph2D();
834
835 Node lastNode = null;
836 for (NodeCursor nc = graph.selectedNodes(); nc.ok(); nc.next()) {
837 if (lastNode != null) {
838 final EdgeRealizer er = new PolyLineEdgeRealizer();
839 er.setVisible(false);
840 graph.createEdge(lastNode, nc.node(), er);
841 animateCreate(er);
842 }
843 lastNode = nc.node();
844 }
845
846 if (lastNode == null) {
847 JOptionPane.showMessageDialog(null, i18n.getString(DEMO_NAME + ".message.selectNodes"));
848 }
849 }
850 };
851 localizeAction(create, DEMO_NAME + ".action.CreateEdge");
852
853 return create;
854 }
855
856
860 private Action createDeleteSelectionAction() {
861 final Action delete = new AbstractAction() {
862 public void actionPerformed(final ActionEvent e) {
863 animateDeleteSelection();
864 }
865 };
866 localizeAction(delete, DEMO_NAME + ".action.DeleteSelection");
867
868 return delete;
869 }
870
871
875 private Action createDeleteNodeAction() {
876 final Action delete = new AbstractAction() {
877 public void actionPerformed(final ActionEvent e) {
878 final Graph2D graph = view.getGraph2D();
879 final NodeCursor nc = graph.selectedNodes();
880 if (nc.ok()) {
881 animateDelete(graph.getRealizer(nc.node()));
882 }
884 }
885 };
886 localizeAction(delete, DEMO_NAME + ".action.DeleteNode");
887
888 return delete;
889 }
890
891
895 private Action createDeleteEdgeAction() {
896 final Action delete = new AbstractAction() {
897 public void actionPerformed(final ActionEvent e) {
898 final Graph2D graph = view.getGraph2D();
899 final EdgeCursor ec = graph.selectedEdges();
900 if (ec.ok()) {
901 animateDelete(graph.getRealizer(ec.edge()));
902 }
903 }
904 };
905 localizeAction(delete, DEMO_NAME + ".action.DeleteEdge");
906
907 return delete;
908 }
909
910
911
915 private void registerGraphListener() {
916 final Graph2D graph = view.getGraph2D();
917 graph.addGraphListener(new GraphListener() {
918 public void onGraphEvent(final GraphEvent e) {
919 if (GraphEvent.NODE_CREATION == e.getType() && !compoundAction) {
920 animateCreate(graph.getRealizer((Node) e.getData()));
921 } else if (GraphEvent.EDGE_CREATION == e.getType() && !compoundAction) {
922 EdgeRealizer edgeRealizer = graph.getRealizer((Edge) e.getData());
923 edgeRealizer.setLineColor((Color) oh.get("misc", "colorUnvisited"));
924 edgeRealizer.setTargetArrow(Arrow.STANDARD);
925 edgeRealizer.setLineType(LineType.LINE_1);
926 animateCreate(edgeRealizer);
927 }
928 }
929 });
930 }
931
932
936 private void registerEditMode() {
937 EditMode editMode = new EditMode();
938 editMode.allowMovingWithPopup(true);
939
940 PopupMode popupMode = new PopupMode() {
941 private final Action createEdge = createCreateEdgeAction();
942 private final Action deleteNode = createDeleteNodeAction();
943 private final Action deleteEdge = createDeleteEdgeAction();
944
945 public JPopupMenu getSelectionPopup(double x, double y) {
946 final JPopupMenu menu = new JPopupMenu();
947 menu.add(createEdge);
948 return menu;
949 }
950
951 public JPopupMenu getNodePopup(final Node v) {
952 final JPopupMenu menu = new JPopupMenu();
953 menu.add(deleteNode);
954 return menu;
955 }
956
957 public JPopupMenu getEdgePopup(final Edge e) {
958 final JPopupMenu menu = new JPopupMenu();
959 menu.add(deleteEdge);
960 return menu;
961 }
962 };
963 editMode.setPopupMode(popupMode);
964 view.addViewMode(editMode);
965 }
966
967
970 private void registerActions() {
971 final ActionMap amap = new ActionMap();
972 amap.put("DELETE_SELECTION", createDeleteSelectionAction());
973 final InputMap imap = new InputMap();
974 imap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "DELETE_SELECTION");
975 view.getCanvasComponent().setActionMap(amap);
976 view.getCanvasComponent().setInputMap(JComponent.WHEN_FOCUSED, imap);
977 }
978
979
980 public void addContentTo(final JRootPane rootPane) {
981 openGraph(i18n.getString(DEMO_NAME + ".RESOURCE.graph.small"));
982 registerGraphListener();
983 registerEditMode();
984 registerActions();
985 rootPane.setContentPane(createContentPane());
986 }
987
988 public static void main(String[] args) {
989 EventQueue.invokeLater(new Runnable() {
990 public void run() {
991 DemoDefaults.initLnF();
992 final GuiFactory gf = createGuiFactory();
993 final AnimationEffectsDemo demo = new AnimationEffectsDemo(gf, true);
994 final JFrame frame = new JFrame(gf.getString(DEMO_NAME + ".title"));
995 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
996 demo.addContentTo(frame.getRootPane());
997 frame.pack();
998 frame.setLocationRelativeTo(null);
999 frame.setVisible(true);
1000 }
1001 });
1002 }
1003
1004 private static GuiFactory createGuiFactory() {
1005 try {
1006 final ResourceBundleGuiFactory i18n = new ResourceBundleGuiFactory();
1007 i18n.addBundle(AnimationEffectsDemo.class.getName());
1008 return i18n;
1009 }
1010 catch (final MissingResourceException mre) {
1011 System.err.println("Could not find resources! " + mre);
1012 return new GuiFactory() {
1013 public JButton createButton(final String action) {
1014 return new JButton(action);
1015 }
1016
1017 public String getString(final String key) {
1018 return key;
1019 }
1020
1021 public Action createHelpAction(final String helpKey) {
1022 return null;
1023 }
1024 };
1025 }
1026 }
1027
1028
1032 private final class AutoRemoveListener implements AnimationListener {
1033 private final AnimationListener delegate;
1034
1035 AutoRemoveListener(final AnimationListener delegate) {
1036 this.delegate = delegate;
1037 }
1038
1039 public void animationPerformed(final AnimationEvent e) {
1040 delegate.animationPerformed(e);
1041 if (AnimationEvent.END == e.getHint()) {
1042 player.removeAnimationListener(this);
1043 }
1044 }
1045 }
1046
1047
1051 private final class EndHandler implements AnimationListener {
1052 private boolean clear;
1053
1054 EndHandler() {
1055 this.clear = false;
1056 }
1057
1058 void setClear(final boolean clear) {
1059 this.clear = clear;
1060 }
1061
1062 public void animationPerformed(final AnimationEvent e) {
1063 if (AnimationEvent.END == e.getHint()) {
1064 if (clear) {
1065 view.getGraph2D().clear();
1066 view.fitContent();
1067 clear = false;
1068 }
1069 view.updateView();
1070 }
1071 }
1072 }
1073
1074
1080 private static final class RemoveNode implements AnimationObject {
1081 private NodeRealizer realizer;
1082 private Graph2DViewRepaintManager manager;
1083
1084 public RemoveNode(final NodeRealizer realizer,
1085 final Graph2DViewRepaintManager manager) {
1086 this.realizer = realizer;
1087 this.manager = manager;
1088 }
1089
1090 public void initAnimation() {
1091 if (manager != null) {
1092 manager.add(realizer);
1093 }
1094 }
1095
1096 public void calcFrame(final double time) {
1097 }
1098
1099 public void disposeAnimation() {
1100 final Node node = realizer.getNode();
1101 node.getGraph().removeNode(node);
1102
1103 if (manager != null) {
1104 manager.remove(realizer);
1105 manager = null;
1106 }
1107
1108 realizer = null;
1109 }
1110
1111 public long preferredDuration() {
1112 return 10;
1113 }
1114 }
1115
1116
1122 private static final class RemoveEdge implements AnimationObject {
1123 private EdgeRealizer realizer;
1124 private Graph2DViewRepaintManager manager;
1125
1126 public RemoveEdge(final EdgeRealizer realizer,
1127 final Graph2DViewRepaintManager manager) {
1128 this.realizer = realizer;
1129 this.manager = manager;
1130 }
1131
1132 public void initAnimation() {
1133 if (manager != null) {
1134 manager.add(realizer);
1135 }
1136 }
1137
1138 public void calcFrame(final double time) {
1139 }
1140
1141 public void disposeAnimation() {
1142 final Edge edge = realizer.getEdge();
1143 edge.getGraph().removeEdge(edge);
1144
1145 if (manager != null) {
1146 manager.remove(realizer);
1147 manager = null;
1148 }
1149
1150 realizer = null;
1151 }
1152
1153 public long preferredDuration() {
1154 return 10;
1155 }
1156 }
1157}
1158