1   /****************************************************************************
2    **
3    ** This file is part of yFiles-2.9. 
4    ** 
5    ** yWorks proprietary/confidential. Use is subject to license terms.
6    **
7    ** Redistribution of this file or of an unauthorized byte-code version
8    ** of this file is strictly forbidden.
9    **
10   ** Copyright (c) 2000-2011 by yWorks GmbH, Vor dem Kreuzberg 28, 
11   ** 72070 Tuebingen, Germany. All rights reserved.
12   **
13   ***************************************************************************/
14  package demo.view.anim;
15  
16  import y.io.GraphMLIOHandler;
17  import y.io.IOHandler;
18  import y.option.CompoundEditor;
19  import y.option.ConstraintManager;
20  import y.option.DefaultEditorFactory;
21  import y.option.Editor;
22  import y.option.EnumOptionItem;
23  import y.option.GuiFactory;
24  import y.option.ItemEditor;
25  import y.option.OptionGroup;
26  import y.option.OptionHandler;
27  import y.option.OptionItem;
28  import y.util.D;
29  import y.view.Graph2D;
30  import y.view.Graph2DView;
31  import y.view.ViewAnimationFactory;
32  
33  import javax.swing.AbstractAction;
34  import javax.swing.Action;
35  import javax.swing.BorderFactory;
36  import javax.swing.DefaultListCellRenderer;
37  import javax.swing.ImageIcon;
38  import javax.swing.JButton;
39  import javax.swing.JComponent;
40  import javax.swing.JList;
41  import javax.swing.JPanel;
42  import javax.swing.JTable;
43  import javax.swing.ListCellRenderer;
44  import javax.swing.table.DefaultTableCellRenderer;
45  import javax.swing.table.TableCellRenderer;
46  import java.awt.BorderLayout;
47  import java.awt.Color;
48  import java.awt.Component;
49  import java.awt.FlowLayout;
50  import java.awt.GridBagConstraints;
51  import java.awt.GridBagLayout;
52  import java.awt.event.ActionEvent;
53  import java.io.File;
54  import java.io.IOException;
55  import java.net.URL;
56  import java.net.URLDecoder;
57  import java.util.HashMap;
58  import java.util.Iterator;
59  import java.util.Map;
60  
61  /**
62   * Provides the GUI and option handling for <code>AnimationEffectsDemo</code>.
63   * Cannot be used for anything else.
64   *
65   * @see AnimationEffectsDemo
66   * @see <a href="http://docs.yworks.com/yfiles/doc/developers-guide/animation.html">Section Animations for Graph Elements</a> in the yFiles for Java Developer's Guide
67   */
68  abstract class AnimationEffectsDemoBase {
69    static final byte NO_ANIM = (byte) 0;
70  
71    static final byte BLUR_IN = (byte) 11;
72    static final byte FADE_IN = (byte) 12;
73    static final byte IMPLODE = (byte) 13;
74    static final byte WHIRL_IN = (byte) 14;
75  
76    static final byte EXTRACT = (byte) 15;
77  
78    static final byte BLUR_OUT = (byte) 21;
79    static final byte FADE_OUT = (byte) 22;
80    static final byte EXPLODE = (byte) 23;
81    static final byte WHIRL_OUT = (byte) 24;
82  
83    static final byte RETRACT = (byte) 25;
84  
85    static final byte TRAVERSE_EDGE = (byte) 31;
86    static final byte ZOOM = (byte) 32;
87    static final byte MOVE_CAMERA = (byte) 33;
88    static final byte MORPH = (byte) 34;
89    static final byte RESIZE = (byte) 35;
90    static final byte BLINK = (byte) 36;
91    static final byte ANIMATED_LOAD = (byte) 37;
92    static final byte ANIMATED_CLEAR = (byte) 38;
93  
94  
95    static final String DEMO_NAME;
96  
97    static {
98      String name = AnimationEffectsDemo.class.getName();
99      name = name.substring(name.lastIndexOf('.') + 1);
100     DEMO_NAME = name;
101   }
102 
103 
104   final Graph2DView view;
105   final GuiFactory i18n;
106   final OptionHandler oh;
107   boolean compoundAction;
108 
109   private final boolean wantsRadioButtons;
110 
111   /**
112    * Creates a new AnimationEffectsDemoBase.
113    * @param i18n   localization data
114    */
115   protected AnimationEffectsDemoBase(
116           final GuiFactory i18n,
117           final boolean wantsRadioButtons
118   ) {
119     this.wantsRadioButtons = wantsRadioButtons;
120     this.view = new Graph2DView();
121     this.view.setFitContentOnResize(true);
122     this.i18n = i18n;
123     this.oh = createOptionHandler();
124     this.compoundAction = false;
125   }
126 
127   abstract void animate();
128 
129   void selectAllEdges() {
130     final Graph2D graph = view.getGraph2D();
131     graph.setSelected(graph.edges(), true);
132   }
133 
134   void openGraph(final String resource) {
135     final URL url = getClass().getResource(resource);
136     if (url != null) {
137       final Graph2D graph = view.getGraph2D();
138       graph.clear();
139 
140       try {
141         final String name = URLDecoder.decode(url.getFile(), "UTF-8");
142         getIoHandler(name).read(graph, name);
143       }
144       catch (IOException ioe) {
145         D.show(ioe);
146       }
147 
148       view.fitContent();
149     } else {
150       final File file = new File(resource);
151       if (file.exists()) {
152         final Graph2D graph = view.getGraph2D();
153         graph.clear();
154 
155         try {
156           final String name = file.getAbsolutePath();
157           getIoHandler(name).read(graph, name);
158         }
159         catch (IOException ioe) {
160           D.show(ioe);
161         }
162 
163         view.fitContent();
164       } else {
165         D.show(new Exception("Cannot locate file: " + resource));
166       }
167     }
168   }
169 
170   void localizeAction(final Action action, final String key) {
171     action.putValue(Action.NAME, i18n.getString(key));
172     action.putValue(Action.SHORT_DESCRIPTION,
173         i18n.getString(key + ".shortDescription"));
174     final URL iconUrl =
175         getClass().getResource(i18n.getString(key + ".smallIcon"));
176     if (iconUrl != null) {
177       action.putValue(Action.SMALL_ICON, new ImageIcon(iconUrl));
178     }
179   }
180 
181 
182   /**
183    * Creates an OptionHandler.
184    */
185   private OptionHandler createOptionHandler() {
186     final OptionHandler optionHandler = new OptionHandler(DEMO_NAME);
187 
188     final ConstraintManager cm = new ConstraintManager(optionHandler);
189 
190     OptionGroup group;
191     OptionGroup section;
192     OptionItem item;
193 
194 
195     final Byte noAnim = new Byte(NO_ANIM);
196 
197 
198     optionHandler.useSection("elements");
199     section = new OptionGroup();
200     section.setAttribute(OptionGroup.ATTRIBUTE_TITLE, "elements");
201 
202     final Byte blurIn = new Byte(BLUR_IN);
203     final Byte fadeIn = new Byte(FADE_IN);
204     final Byte implode = new Byte(IMPLODE);
205     final Byte whirlIn = new Byte(WHIRL_IN);
206 
207     final Byte blurOut = new Byte(BLUR_OUT);
208     final Byte fadeOut = new Byte(FADE_OUT);
209     final Byte explode = new Byte(EXPLODE);
210     final Byte whirlOut = new Byte(WHIRL_OUT);
211 
212     final Byte extract = new Byte(EXTRACT);
213     final Byte retract = new Byte(RETRACT);
214 
215     final ElementsRenderer elementsRenderer = new ElementsRenderer();
216     item = optionHandler.addEnum("createNode", new Byte[]{noAnim, blurIn, fadeIn, implode, whirlIn}, 4);
217     item.setAttribute(EnumOptionItem.ATTRIBUTE_RENDERER, elementsRenderer);
218     section.addItem(item);
219     item = optionHandler.addEnum("deleteNode", new Byte[]{noAnim, blurOut, fadeOut, explode, whirlOut}, 1);
220     item.setAttribute(EnumOptionItem.ATTRIBUTE_RENDERER, elementsRenderer);
221     section.addItem(item);
222     item = optionHandler.addEnum("createEdge", new Byte[]{noAnim, blurIn, fadeIn, implode, extract}, 2);
223     item.setAttribute(EnumOptionItem.ATTRIBUTE_RENDERER, elementsRenderer);
224     section.addItem(item);
225     item = optionHandler.addEnum("deleteEdge", new Byte[]{noAnim, blurOut, fadeOut, explode, retract}, 4);
226     item.setAttribute(EnumOptionItem.ATTRIBUTE_RENDERER, elementsRenderer);
227     section.addItem(item);
228 
229     optionHandler.useSection("misc");
230     section = new OptionGroup();
231 
232     final Byte animatedClear = new Byte(ANIMATED_CLEAR);
233     final Byte animatedLoad = new Byte(ANIMATED_LOAD);
234     final Byte traverseEdge = new Byte(TRAVERSE_EDGE);
235     final Byte zoom = new Byte(ZOOM);
236     final Byte moveCamera = new Byte(MOVE_CAMERA);
237     final Byte morph = new Byte(MORPH);
238     final Byte resize = new Byte(RESIZE);
239     final Byte blink = new Byte(BLINK);
240 
241     item = optionHandler.addEnum("animation", new Byte[]{
242         animatedLoad, animatedClear,
243         traverseEdge, zoom, moveCamera,
244         morph, resize, blink
245     }, 2);
246     item.setAttribute(DefaultEditorFactory.ATTRIBUTE_CONTROLLER_ID,
247         DEMO_NAME + "Base.animation");
248     item.setAttribute(EnumOptionItem.ATTRIBUTE_RENDERER,
249         new AnimationRenderer());
250     item.setAttribute(DefaultEditorFactory.ATTRIBUTE_ENUM_STYLE,
251         wantsRadioButtons
252             ? DefaultEditorFactory.STYLE_RADIO_BUTTONS
253             : DefaultEditorFactory.STYLE_COMBO_BOX);
254     section.addItem(item);
255 
256     final OrderRenderer orderRenderer = new OrderRenderer();
257     final Object[] order = {
258         ViewAnimationFactory.LEFT_TO_RIGHT,
259         ViewAnimationFactory.RIGHT_TO_LEFT,
260         ViewAnimationFactory.CLOCKWISE,
261         ViewAnimationFactory.COUNTER_CLOCKWISE
262     };
263 
264     group = new OptionGroup();
265     group.setAttribute(OptionGroup.ATTRIBUTE_TITLE, "misc_animation_properties");
266     group.setAttribute(DefaultEditorFactory.ATTRIBUTE_CONTROLLER_ID,
267         DEMO_NAME + "Base.animation");
268     group.setAttribute(DefaultEditorFactory.ATTRIBUTE_CARD_ID, animatedLoad.toString());
269     item = optionHandler.addEnum("animateLoad_graph", new String[]{"big", "small"}, 0);
270     item.setAttribute(DefaultEditorFactory.ATTRIBUTE_ENUM_STYLE,
271         DefaultEditorFactory.STYLE_RADIO_BUTTONS);
272     item.setAttribute(DefaultEditorFactory.ATTRIBUTE_ENUM_ALIGNMENT,
273         DefaultEditorFactory.ALIGNMENT_HORIZONTAL);
274     group.addItem(item);
275     item = optionHandler.addEnum("animateLoad_nodeOrder", order, 0);
276     item.setAttribute(EnumOptionItem.ATTRIBUTE_RENDERER, orderRenderer);
277     group.addItem(item);
278     group.addItem(optionHandler.addBool("animateLoad_obeyEdgeDirection", false));
279     group.addItem(optionHandler.addDouble("animateLoad_ratio", 0.15, 0.1, 1.0));
280     cm.setEnabledOnValueEquals("animation", animatedLoad, group);
281 
282     group = new OptionGroup();
283     group.setAttribute(OptionGroup.ATTRIBUTE_TITLE, "misc_animation_properties");
284     group.setAttribute(DefaultEditorFactory.ATTRIBUTE_CONTROLLER_ID,
285         DEMO_NAME + "Base.animation");
286     group.setAttribute(DefaultEditorFactory.ATTRIBUTE_CARD_ID, animatedClear.toString());
287     item = optionHandler.addEnum("animateClear_nodeOrder", order, 0);
288     item.setAttribute(EnumOptionItem.ATTRIBUTE_RENDERER, orderRenderer);
289     group.addItem(item);
290     group.addItem(optionHandler.addBool("animateClear_obeyEdgeDirection", false));
291     group.addItem(optionHandler.addDouble("animateClear_ratio", 0.15, 0.1, 1.0));
292     cm.setEnabledOnValueEquals("animation", animatedClear, group);
293 
294     group = new OptionGroup();
295     group.setAttribute(OptionGroup.ATTRIBUTE_TITLE, "misc_animation_properties");
296     group.setAttribute(DefaultEditorFactory.ATTRIBUTE_CONTROLLER_ID,
297         DEMO_NAME + "Base.animation");
298     group.setAttribute(DefaultEditorFactory.ATTRIBUTE_CARD_ID, traverseEdge.toString());
299 
300     group.addItem(optionHandler.addColor("colorVisited", Color.RED, true, true, false, false));
301     group.addItem(optionHandler.addColor("colorUnvisited", Color.BLACK, true, true, false, false));
302     cm.setEnabledOnValueEquals("animation", traverseEdge, group);
303     addItems(group, section);
304 
305     group = new OptionGroup();
306     group.setAttribute(OptionGroup.ATTRIBUTE_TITLE, "misc_animation_properties");
307     group.setAttribute(DefaultEditorFactory.ATTRIBUTE_CONTROLLER_ID,
308         DEMO_NAME + "Base.animation");
309     group.setAttribute(DefaultEditorFactory.ATTRIBUTE_CARD_ID, zoom.toString());
310 
311     group.addItem(optionHandler.addDouble("zoom_factor", 1.0, 0.1, 16.0));
312     cm.setEnabledOnValueEquals("animation", zoom, group);
313 
314     group = new OptionGroup();
315     group.setAttribute(OptionGroup.ATTRIBUTE_TITLE, "misc_animation_properties");
316     group.setAttribute(DefaultEditorFactory.ATTRIBUTE_CONTROLLER_ID,
317         DEMO_NAME + "Base.animation");
318     group.setAttribute(DefaultEditorFactory.ATTRIBUTE_CARD_ID, morph.toString());
319 
320     group.addItem(optionHandler.addDouble("translateX", 50));
321     group.addItem(optionHandler.addDouble("translateY", 50));
322     group.addItem(optionHandler.addDouble("width", 100));
323     group.addItem(optionHandler.addDouble("height", 25));
324     group.addItem(optionHandler.addColor("fillColor", Color.RED, true, true, false, false));
325     group.addItem(optionHandler.addColor("fillColor2", Color.YELLOW, true, true, false, false));
326     group.addItem(optionHandler.addColor("lineColor", Color.BLACK, true, true, false, false));
327     cm.setEnabledOnValueEquals("animation", morph, group);
328     addItems(group, section);
329 
330     group = new OptionGroup();
331     group.setAttribute(OptionGroup.ATTRIBUTE_TITLE, "misc_animation_properties");
332     group.setAttribute(DefaultEditorFactory.ATTRIBUTE_CONTROLLER_ID,
333         DEMO_NAME + "Base.animation");
334     group.setAttribute(DefaultEditorFactory.ATTRIBUTE_CARD_ID, resize.toString());
335 
336     group.addItem(optionHandler.addDouble("resize_width", 100));
337     group.addItem(optionHandler.addDouble("resize_height", 100));
338     cm.setEnabledOnValueEquals("animation", resize, group);
339     addItems(group, section);
340 
341     group = new OptionGroup();
342     group.setAttribute(OptionGroup.ATTRIBUTE_TITLE, "misc_animation_properties");
343     group.setAttribute(DefaultEditorFactory.ATTRIBUTE_CONTROLLER_ID,
344         DEMO_NAME + "Base.animation");
345     group.setAttribute(DefaultEditorFactory.ATTRIBUTE_CARD_ID, blink.toString());
346 
347     group.addItem(optionHandler.addInt("repetitions", 1, 1, 25));
348     cm.setEnabledOnValueEquals("animation", blink, group);
349     addItems(group, section);
350 
351     optionHandler.useSection("global");
352     optionHandler.addDouble("speed", 2.0, 0.25, 4.0, 2);
353 
354     return optionHandler;
355   }
356 
357   private JComponent createControlPane() {
358     final DefaultEditorFactory editorFactory = new DefaultEditorFactory();
359     editorFactory.setGuiFactory(i18n);
360 
361     final Map attributes = new HashMap();
362     final Editor editor = editorFactory.createEditor(oh, attributes);
363     setAutoAdopt(true, editor);
364     setAutoCommit(true, editor);
365 
366     final JPanel buttonPane = new JPanel(new FlowLayout(FlowLayout.LEADING));
367     buttonPane.add(new JButton(createAnimateAction()));
368 
369     JPanel spacer = new JPanel();
370     final JPanel pane = new JPanel(new GridBagLayout());
371 
372     int row = 0;
373 
374     final GridBagConstraints gbc = new GridBagConstraints();
375     gbc.fill = GridBagConstraints.HORIZONTAL;
376     gbc.anchor = GridBagConstraints.WEST;
377 
378     {
379       final CompoundEditor ce = (CompoundEditor) editor;
380       for (int i = 0, n = ce.editorCount() - 2; i < n; ++i) {
381         gbc.gridy = row++;
382         pane.add(ce.getEditor(i).getComponent(), gbc);
383       }
384       // special case for last two editors:
385       // misc section and animation speed setting
386       {
387         final GridBagConstraints compoundConstraints = new GridBagConstraints();
388         final JPanel compoundPane = new JPanel(new GridBagLayout());
389         compoundPane.setBorder(
390             BorderFactory.createTitledBorder(
391                 i18n.getString(DEMO_NAME + ".GROUP.misc")));
392 
393         compoundConstraints.fill = GridBagConstraints.HORIZONTAL;
394         compoundConstraints.anchor = GridBagConstraints.NORTHWEST;
395         compoundConstraints.gridy = 0;
396         compoundConstraints.gridwidth = 2;
397         compoundConstraints.weightx = 1.0;
398         compoundPane.add(ce.getEditor(ce.editorCount() - 2).getComponent(),
399             compoundConstraints);
400 
401         compoundConstraints.fill = GridBagConstraints.BOTH;
402         compoundConstraints.anchor = GridBagConstraints.WEST;
403         compoundConstraints.gridy = 1;
404         compoundConstraints.weighty = 1.0;
405         compoundPane.add(spacer, compoundConstraints);
406 
407         compoundConstraints.gridy = 2;
408         compoundConstraints.gridwidth = 1;
409         compoundConstraints.anchor = GridBagConstraints.SOUTHWEST;
410         compoundPane.add(buttonPane, compoundConstraints);
411 
412         compoundConstraints.gridx = 1;
413         compoundPane.add(ce.getEditor(ce.editorCount() - 1).getComponent(),
414             compoundConstraints);
415 
416         gbc.gridy = row++;
417         pane.add(compoundPane, gbc);
418       }
419     }
420 
421     spacer = new JPanel();
422     gbc.fill = GridBagConstraints.BOTH;
423     gbc.gridy = row;
424     gbc.weighty = 0.75;
425     pane.add(spacer, gbc);
426 
427     return pane;
428   }
429 
430   JComponent createContentPane() {
431     final JPanel pane = new JPanel(new BorderLayout());
432     pane.add(createControlPane(), BorderLayout.WEST);
433     pane.add(view, BorderLayout.CENTER);
434     return pane;
435   }
436 
437   private Action createAnimateAction() {
438     final Action action = new AbstractAction() {
439       public void actionPerformed(final ActionEvent e) {
440         animate();
441       }
442     };
443     localizeAction(action, DEMO_NAME + ".action.Animate");
444 
445     return action;
446   }
447 
448   private IOHandler getIoHandler(final String filename) {
449     return new GraphMLIOHandler();
450   }
451 
452 
453   private static void addItems(final OptionGroup src, final OptionGroup tgt) {
454     for (Iterator it = src.items(); it.hasNext();) {
455       tgt.addItem((OptionItem) it.next());
456     }
457   }
458 
459   /**
460    * Sets the <code>autoCommit</code> property to the specified value,
461    * if the specified editor support setting said property.
462    */
463   private static void setAutoCommit(final boolean autoCommit,
464                                     final Editor editor) {
465     if (editor instanceof CompoundEditor) {
466       for (Iterator it = ((CompoundEditor) editor).editors(); it.hasNext();) {
467         setAutoCommit(autoCommit, (Editor) it.next());
468       }
469     }
470     if (editor instanceof ItemEditor) {
471       ((ItemEditor) editor).setAutoCommit(autoCommit);
472     }
473   }
474 
475   /**
476    * Sets the <code>autoAdopt</code> property for all items of the specified
477    * option handler.
478    */
479   private static void setAutoAdopt(final boolean autoAdopt,
480                                    final Editor editor) {
481     if (editor instanceof CompoundEditor) {
482       for (Iterator it = ((CompoundEditor) editor).editors(); it.hasNext();) {
483         setAutoAdopt(autoAdopt, (Editor) it.next());
484       }
485     }
486     if (editor instanceof ItemEditor) {
487       ((ItemEditor) editor).setAutoAdopt(autoAdopt);
488     }
489   }
490 
491 
492   private abstract static class I18nRenderer
493       implements ListCellRenderer, TableCellRenderer {
494     private final DefaultListCellRenderer listDelegate;
495     private final DefaultTableCellRenderer tableDelegate;
496 
497     protected I18nRenderer() {
498       this.listDelegate = new DefaultListCellRenderer();
499       this.tableDelegate = new DefaultTableCellRenderer();
500     }
501 
502     public Component getListCellRendererComponent(final JList list,
503                                                   final Object value,
504                                                   final int index,
505                                                   final boolean isSelected,
506                                                   final boolean hasFocus) {
507       return listDelegate.getListCellRendererComponent(list, toString(value),
508           index,
509           isSelected, hasFocus);
510     }
511 
512     public Component getTableCellRendererComponent(final JTable table,
513                                                    final Object value,
514                                                    final boolean isSelected,
515                                                    final boolean hasFocus,
516                                                    final int row,
517                                                    final int column) {
518       return tableDelegate.getTableCellRendererComponent(table, toString(value),
519           isSelected, hasFocus,
520           row, column);
521     }
522 
523     abstract String toString(final Object value);
524   }
525 
526   private final class ElementsRenderer extends I18nRenderer {
527     String toString(final Object animation) {
528       switch (((Byte) animation).byteValue()) {
529         case NO_ANIM:
530           return i18n.getString(DEMO_NAME + ".elements.VALUE.noAnimation");
531         case BLUR_IN:
532           return i18n.getString(DEMO_NAME + ".elements.VALUE.blurIn");
533         case FADE_IN:
534           return i18n.getString(DEMO_NAME + ".elements.VALUE.fadeIn");
535         case IMPLODE:
536           return i18n.getString(DEMO_NAME + ".elements.VALUE.implode");
537         case WHIRL_IN:
538           return i18n.getString(DEMO_NAME + ".elements.VALUE.whirlIn");
539         case EXTRACT:
540           return i18n.getString(DEMO_NAME + ".elements.VALUE.extract");
541         case BLUR_OUT:
542           return i18n.getString(DEMO_NAME + ".elements.VALUE.blurOut");
543         case FADE_OUT:
544           return i18n.getString(DEMO_NAME + ".elements.VALUE.fadeOut");
545         case EXPLODE:
546           return i18n.getString(DEMO_NAME + ".elements.VALUE.explode");
547         case WHIRL_OUT:
548           return i18n.getString(DEMO_NAME + ".elements.VALUE.whirlOut");
549         case RETRACT:
550           return i18n.getString(DEMO_NAME + ".elements.VALUE.retract");
551         default:
552           // this should never happen
553           return "";
554       }
555     }
556   }
557 
558   private final class AnimationRenderer extends I18nRenderer {
559     String toString(final Object animation) {
560       switch (((Byte) animation).byteValue()) {
561         case NO_ANIM:
562           return i18n.getString(DEMO_NAME + ".misc.animation.VALUE.noAnimation");
563         case TRAVERSE_EDGE:
564           return i18n.getString(DEMO_NAME + ".misc.animation.VALUE.traverseEdge");
565         case ZOOM:
566           return i18n.getString(DEMO_NAME + ".misc.animation.VALUE.zoom");
567         case MOVE_CAMERA:
568           return i18n.getString(DEMO_NAME + ".misc.animation.VALUE.moveCamera");
569         case MORPH:
570           return i18n.getString(DEMO_NAME + ".misc.animation.VALUE.morph");
571         case RESIZE:
572           return i18n.getString(DEMO_NAME + ".misc.animation.VALUE.resize");
573         case BLINK:
574           return i18n.getString(DEMO_NAME + ".misc.animation.VALUE.blink");
575         case ANIMATED_LOAD:
576           return i18n.getString(DEMO_NAME + ".misc.animation.VALUE.animatedLoad");
577         case ANIMATED_CLEAR:
578           return i18n.getString(DEMO_NAME + ".misc.animation.VALUE.animatedClear");
579         default:
580           return i18n.getString(DEMO_NAME + ".misc.animation.VALUE.noAnimation");
581       }
582     }
583   }
584 
585   private final class OrderRenderer extends I18nRenderer {
586     String toString(final Object nodeOrder) {
587       if (nodeOrder == ViewAnimationFactory.LEFT_TO_RIGHT) {
588         return i18n.getString("ViewAnimationFactory.LEFT_TO_RIGHT");
589       }
590       if (nodeOrder == ViewAnimationFactory.RIGHT_TO_LEFT) {
591         return i18n.getString("ViewAnimationFactory.RIGHT_TO_LEFT");
592       }
593       if (nodeOrder == ViewAnimationFactory.CLOCKWISE) {
594         return i18n.getString("ViewAnimationFactory.CLOCKWISE");
595       }
596       if (nodeOrder == ViewAnimationFactory.COUNTER_CLOCKWISE) {
597         return i18n.getString("ViewAnimationFactory.COUNTER_CLOCKWISE");
598       }
599       // this should never happen
600       return null;
601     }
602   }
603 }
604