1 /*
2  * Copyright 2008 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 package com.google.gwt.sample.showcase.client.content.lists;
17 
18 import com.google.gwt.core.client.GWT;
19 import com.google.gwt.core.client.RunAsyncCallback;
20 import com.google.gwt.event.logical.shared.OpenEvent;
21 import com.google.gwt.event.logical.shared.OpenHandler;
22 import com.google.gwt.i18n.client.Constants;
23 import com.google.gwt.sample.showcase.client.ContentWidget;
24 import com.google.gwt.sample.showcase.client.ShowcaseAnnotations.ShowcaseData;
25 import com.google.gwt.sample.showcase.client.ShowcaseAnnotations.ShowcaseSource;
26 import com.google.gwt.sample.showcase.client.ShowcaseAnnotations.ShowcaseStyle;
27 import com.google.gwt.user.client.Random;
28 import com.google.gwt.user.client.rpc.AsyncCallback;
29 import com.google.gwt.user.client.ui.DecoratorPanel;
30 import com.google.gwt.user.client.ui.Grid;
31 import com.google.gwt.user.client.ui.HasVerticalAlignment;
32 import com.google.gwt.user.client.ui.ScrollPanel;
33 import com.google.gwt.user.client.ui.Tree;
34 import com.google.gwt.user.client.ui.TreeItem;
35 import com.google.gwt.user.client.ui.Widget;
36 
37 /**
38  * Example file.
39  */
40 @ShowcaseStyle(".gwt-Tree")
41 public class CwTree extends ContentWidget {
42   /**
43    * The constants used in this Content Widget.
44    */
45   @ShowcaseSource
46   public static interface CwConstants extends Constants {
cwTreeBeethovenWorkConcertos()47     String[] cwTreeBeethovenWorkConcertos();
48 
cwTreeBeethovenWorkQuartets()49     String[] cwTreeBeethovenWorkQuartets();
50 
cwTreeBeethovenWorkSonatas()51     String[] cwTreeBeethovenWorkSonatas();
52 
cwTreeBeethovenWorkSymphonies()53     String[] cwTreeBeethovenWorkSymphonies();
54 
cwTreeBrahmsWorkConcertos()55     String[] cwTreeBrahmsWorkConcertos();
56 
cwTreeBrahmsWorkQuartets()57     String[] cwTreeBrahmsWorkQuartets();
58 
cwTreeBrahmsWorkSonatas()59     String[] cwTreeBrahmsWorkSonatas();
60 
cwTreeBrahmsWorkSymphonies()61     String[] cwTreeBrahmsWorkSymphonies();
62 
cwTreeComposers()63     String[] cwTreeComposers();
64 
cwTreeConcertos()65     String cwTreeConcertos();
66 
cwTreeDescription()67     String cwTreeDescription();
68 
cwTreeDynamicLabel()69     String cwTreeDynamicLabel();
70 
cwTreeItem()71     String cwTreeItem();
72 
cwTreeMozartWorkConcertos()73     String[] cwTreeMozartWorkConcertos();
74 
cwTreeName()75     String cwTreeName();
76 
cwTreeQuartets()77     String cwTreeQuartets();
78 
cwTreeSonatas()79     String cwTreeSonatas();
80 
cwTreeStaticLabel()81     String cwTreeStaticLabel();
82 
cwTreeSymphonies()83     String cwTreeSymphonies();
84   }
85 
86   /**
87    * An instance of the constants.
88    */
89   @ShowcaseData
90   private final CwConstants constants;
91 
92   /**
93    * Constructor.
94    *
95    * @param constants the constants
96    */
CwTree(CwConstants constants)97   public CwTree(CwConstants constants) {
98     super(constants.cwTreeName(), constants.cwTreeDescription(), true);
99     this.constants = constants;
100   }
101 
102   /**
103    * Initialize this example.
104    */
105   @ShowcaseSource
106   @Override
onInitialize()107   public Widget onInitialize() {
108     // Create a static tree and a container to hold it
109     Tree staticTree = createStaticTree();
110     staticTree.setAnimationEnabled(true);
111     staticTree.ensureDebugId("cwTree-staticTree");
112     ScrollPanel staticTreeWrapper = new ScrollPanel(staticTree);
113     staticTreeWrapper.ensureDebugId("cwTree-staticTree-Wrapper");
114     staticTreeWrapper.setSize("300px", "300px");
115 
116     // Wrap the static tree in a DecoratorPanel
117     DecoratorPanel staticDecorator = new DecoratorPanel();
118     staticDecorator.setWidget(staticTreeWrapper);
119 
120     // Create a dynamically generated tree and a container to hold it
121     final Tree dynamicTree = createDynamicTree();
122     dynamicTree.ensureDebugId("cwTree-dynamicTree");
123     ScrollPanel dynamicTreeWrapper = new ScrollPanel(dynamicTree);
124     dynamicTreeWrapper.ensureDebugId("cwTree-dynamicTree-Wrapper");
125     dynamicTreeWrapper.setSize("300px", "300px");
126 
127     // Wrap the dynamic tree in a DecoratorPanel
128     DecoratorPanel dynamicDecorator = new DecoratorPanel();
129     dynamicDecorator.setWidget(dynamicTreeWrapper);
130 
131     // Combine trees onto the page
132     Grid grid = new Grid(2, 3);
133     grid.setCellPadding(2);
134     grid.getRowFormatter().setVerticalAlign(1, HasVerticalAlignment.ALIGN_TOP);
135     grid.setHTML(0, 0, constants.cwTreeStaticLabel());
136     grid.setHTML(0, 1, "   ");
137     grid.setHTML(0, 2, constants.cwTreeDynamicLabel());
138     grid.setWidget(1, 0, staticDecorator);
139     grid.setHTML(1, 1, "   ");
140     grid.setWidget(1, 2, dynamicDecorator);
141 
142     // Wrap the trees in DecoratorPanels
143     return grid;
144   }
145 
146   @Override
asyncOnInitialize(final AsyncCallback<Widget> callback)147   protected void asyncOnInitialize(final AsyncCallback<Widget> callback) {
148     GWT.runAsync(CwTree.class, new RunAsyncCallback() {
149 
150       @Override
151       public void onFailure(Throwable caught) {
152         callback.onFailure(caught);
153       }
154 
155       @Override
156       public void onSuccess() {
157         callback.onSuccess(onInitialize());
158       }
159     });
160   }
161 
162   /**
163    * Add a new section of music created by a specific composer.
164    *
165    * @param parent the parent {@link TreeItem} where the section will be added
166    * @param label the label of the new section of music
167    * @param composerWorks an array of works created by the composer
168    */
169   @ShowcaseSource
addMusicSection( TreeItem parent, String label, String[] composerWorks)170   private void addMusicSection(
171       TreeItem parent, String label, String[] composerWorks) {
172     TreeItem section = parent.addTextItem(label);
173     for (String work : composerWorks) {
174       section.addTextItem(work);
175     }
176   }
177 
178   /**
179    * Create a dynamic tree that will add a random number of children to each
180    * node as it is clicked.
181    *
182    * @return the new tree
183    */
184   @ShowcaseSource
createDynamicTree()185   private Tree createDynamicTree() {
186     // Create a new tree
187     Tree dynamicTree = new Tree();
188 
189     // Add some default tree items
190     for (int i = 0; i < 5; i++) {
191       TreeItem item = dynamicTree.addTextItem(constants.cwTreeItem() + " " + i);
192 
193       // Temporarily add an item so we can expand this node
194       item.addTextItem("");
195     }
196 
197     // Add a handler that automatically generates some children
198     dynamicTree.addOpenHandler(new OpenHandler<TreeItem>() {
199       @Override
200       public void onOpen(OpenEvent<TreeItem> event) {
201         TreeItem item = event.getTarget();
202         if (item.getChildCount() == 1) {
203           // Close the item immediately
204           item.setState(false, false);
205 
206           // Add a random number of children to the item
207           String itemText = item.getText();
208           int numChildren = Random.nextInt(5) + 2;
209           for (int i = 0; i < numChildren; i++) {
210             TreeItem child = item.addTextItem(itemText + "." + i);
211             child.addTextItem("");
212           }
213 
214           // Remove the temporary item when we finish loading
215           item.getChild(0).remove();
216 
217           // Reopen the item
218           item.setState(true, false);
219         }
220       }
221     });
222 
223     // Return the tree
224     return dynamicTree;
225   }
226 
227   /**
228    * Create a static tree with some data in it.
229    *
230    * @return the new tree
231    */
232   @ShowcaseSource
createStaticTree()233   private Tree createStaticTree() {
234     // Create the tree
235     String[] composers = constants.cwTreeComposers();
236     String concertosLabel = constants.cwTreeConcertos();
237     String quartetsLabel = constants.cwTreeQuartets();
238     String sonatasLabel = constants.cwTreeSonatas();
239     String symphoniesLabel = constants.cwTreeSymphonies();
240     Tree staticTree = new Tree();
241 
242     // Add some of Beethoven's music
243     TreeItem beethovenItem = staticTree.addTextItem(composers[0]);
244     addMusicSection(beethovenItem, concertosLabel,
245         constants.cwTreeBeethovenWorkConcertos());
246     addMusicSection(
247         beethovenItem, quartetsLabel, constants.cwTreeBeethovenWorkQuartets());
248     addMusicSection(
249         beethovenItem, sonatasLabel, constants.cwTreeBeethovenWorkSonatas());
250     addMusicSection(beethovenItem, symphoniesLabel,
251         constants.cwTreeBeethovenWorkSymphonies());
252 
253     // Add some of Brahms's music
254     TreeItem brahmsItem = staticTree.addTextItem(composers[1]);
255     addMusicSection(
256         brahmsItem, concertosLabel, constants.cwTreeBrahmsWorkConcertos());
257     addMusicSection(
258         brahmsItem, quartetsLabel, constants.cwTreeBrahmsWorkQuartets());
259     addMusicSection(
260         brahmsItem, sonatasLabel, constants.cwTreeBrahmsWorkSonatas());
261     addMusicSection(
262         brahmsItem, symphoniesLabel, constants.cwTreeBrahmsWorkSymphonies());
263 
264     // Add some of Mozart's music
265     TreeItem mozartItem = staticTree.addTextItem(composers[2]);
266     addMusicSection(
267         mozartItem, concertosLabel, constants.cwTreeMozartWorkConcertos());
268 
269     // Return the tree
270     return staticTree;
271   }
272 }
273