KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > xml > schema > ui > basic > navigator > SchemaNavigatorContent


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.xml.schema.ui.basic.navigator;
21
22 import java.awt.BorderLayout JavaDoc;
23 import java.awt.Color JavaDoc;
24 import java.awt.EventQueue JavaDoc;
25 import java.beans.PropertyChangeEvent JavaDoc;
26 import java.beans.PropertyChangeListener JavaDoc;
27 import java.beans.PropertyVetoException JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.util.ArrayList JavaDoc;
30 import java.util.Enumeration JavaDoc;
31 import java.util.List JavaDoc;
32 import javax.swing.JPanel JavaDoc;
33 import javax.swing.JTree JavaDoc;
34 import javax.swing.SwingConstants JavaDoc;
35 import javax.swing.SwingUtilities JavaDoc;
36 import javax.swing.UIManager JavaDoc;
37 import org.netbeans.modules.xml.schema.model.SchemaComponent;
38 import org.netbeans.modules.xml.schema.model.SchemaModel;
39 import org.netbeans.modules.xml.schema.ui.basic.SchemaModelCookie;
40 import org.netbeans.modules.xml.schema.ui.basic.UIUtilities;
41 import org.netbeans.modules.xml.schema.ui.nodes.DefaultExpandedCookie;
42 import org.netbeans.modules.xml.schema.ui.nodes.SchemaNodeFactory;
43 import org.netbeans.modules.xml.schema.ui.nodes.ReadOnlyCookie;
44 import org.netbeans.modules.xml.schema.ui.nodes.categorized.CategorizedSchemaNodeFactory;
45 import org.netbeans.modules.xml.xam.Model.State;
46 import org.openide.explorer.ExplorerManager;
47 import org.openide.explorer.view.BeanTreeView;
48 import org.openide.explorer.view.TreeView;
49 import org.openide.loaders.DataObject;
50 import org.openide.nodes.Node;
51 import org.openide.util.Lookup;
52 import org.openide.util.NbBundle;
53 import org.openide.util.lookup.Lookups;
54 import org.openide.windows.TopComponent;
55
56 /**
57  * XML Schema Navigator component containing a tree of schema components.
58  *
59  * @author Nathan Fiedler
60  */

61 public class SchemaNavigatorContent extends JPanel JavaDoc
62         implements ExplorerManager.Provider, Runnable JavaDoc, PropertyChangeListener JavaDoc {
63     /** silence compiler warnings */
64     private static final long serialVersionUID = 1L;
65     /** The lookup for our component tree. */
66     private static Lookup lookup;
67     /** Explorer manager for the tree view. */
68     private ExplorerManager explorerManager;
69     /** Our schema component node tree view. */
70     private TreeView treeView;
71     /** Indicates that the tree view is not in the component hierarchy. */
72     private boolean treeInHierarchy;
73     /** indicator that currently listening to topcomponent.registry.activatednodes **/
74     private boolean listeningOnActivatedNodes = false;
75     private final javax.swing.JLabel JavaDoc notAvailableLabel = new javax.swing.JLabel JavaDoc(
76             NbBundle.getMessage(SchemaNavigatorContent.class, "MSG_NotAvailable")); //NOI18N
77

78     static {
79         // Present a read-only view of the schema components.
80
lookup = Lookups.singleton(new ReadOnlyCookie(true));
81     }
82     
83     /**
84      * Creates a new instance of SchemaNavigatorContent.
85      */

86     public SchemaNavigatorContent() {
87         setLayout(new BorderLayout JavaDoc());
88         explorerManager = new ExplorerManager();
89         treeView = new BeanTreeView();
90         explorerManager.addPropertyChangeListener(this);
91         //initialize the notAvailableLabel
92
notAvailableLabel.setHorizontalAlignment(SwingConstants.CENTER);
93         notAvailableLabel.setEnabled(false);
94         Color JavaDoc usualWindowBkg = UIManager.getColor("window"); //NOI18N
95
notAvailableLabel.setBackground(usualWindowBkg != null ? usualWindowBkg : Color.white);
96         // to ensure our background color will have effect
97
notAvailableLabel.setOpaque(true);
98     }
99     
100     /**
101      * Expand the nodes which should be expanded by default.
102      */

103     protected void expandDefaultNodes() {
104         Node rootNode = getExplorerManager().getRootContext();
105         // Need to prevent looping on malformed trees, so avoid going too
106
// deep when expanding the children of nodes with only one child.
107
int depth = 0;
108         do {
109             Node[] children = rootNode.getChildren().getNodes();
110             if (children.length == 1) {
111                 // Expand all nodes that have only a single child.
112
treeView.expandNode(children[0]);
113                 rootNode = children[0];
114                 depth++;
115             } else {
116                 // Expand all first-level children that are meant to be shown
117
// expanded by default.
118
for (Node child : children) {
119                     DefaultExpandedCookie cookie = (DefaultExpandedCookie)
120                     child.getCookie(DefaultExpandedCookie.class);
121                     if (cookie != null && cookie.isDefaultExpanded()) {
122                         treeView.expandNode(child);
123                     }
124                 }
125                 rootNode = null;
126             }
127         } while (rootNode != null && depth < 5);
128         
129         // The following code addresses two issues:
130
//
131
// 1. When viewing large schemas, expanding the default set of nodes
132
// generally means that the contents of the column are so long that
133
// copious amounts of scrolling are necessary to see it all. This is
134
// not desirable for the user's first experience with the document.
135
//
136
// 2. Because BasicTreeUI essentially ignores the scrollsOnExpand
137
// setting (or at least it does not work as documented), the tree
138
// is left scrolled to some random position.
139
//
140
// So, if scrolling is necessary, then collapse root's children.
141
JTree JavaDoc tree = (JTree JavaDoc) treeView.getViewport().getView();
142         if (tree.getRowCount() > tree.getVisibleRowCount()) {
143             rootNode = getExplorerManager().getRootContext();
144             Enumeration JavaDoc kids = rootNode.getChildren().nodes();
145             while (kids.hasMoreElements()) {
146                 Node kid = (Node) kids.nextElement();
147                 treeView.collapseNode(kid);
148             }
149         }
150     }
151     
152     public ExplorerManager getExplorerManager() {
153         return explorerManager;
154     }
155     
156     private SchemaModel getSchemaModel(DataObject dobj) {
157         try {
158             SchemaModelCookie modelCookie = (SchemaModelCookie)
159             dobj.getCookie(SchemaModelCookie.class);
160             assert modelCookie != null;
161             SchemaModel model = modelCookie.getModel();
162             if(model != null) {
163                 model.removePropertyChangeListener(this);
164                 model.addPropertyChangeListener(this);
165             }
166             return model;
167         } catch (IOException JavaDoc ioe) {
168             //will show blank page if there is an error.
169
}
170         
171         return null;
172     }
173     
174     
175     /**
176      * Show the data object in the navigator.
177      *
178      * @param dobj data object to show.
179      */

180     public void navigate(DataObject dobj) {
181         SchemaModel model = getSchemaModel(dobj);
182         if (model == null || model.getState() != SchemaModel.State.VALID) {
183             showError();
184         } else {
185             show(model);
186         }
187     }
188     
189     public boolean requestFocusInWindow() {
190         return treeView.requestFocusInWindow();
191     }
192     
193     public void run() {
194         expandDefaultNodes();
195         selectActivatedNodes();
196     }
197     
198     public void propertyChange(PropertyChangeEvent JavaDoc event) {
199         String JavaDoc property = event.getPropertyName();
200         if(SchemaModel.STATE_PROPERTY.equals(property)) {
201             onModelStateChanged(event);
202             return;
203         }
204         TopComponent tc = (TopComponent) SwingUtilities.
205                 getAncestorOfClass(TopComponent.class,this);
206         if (ExplorerManager.PROP_SELECTED_NODES.equals(property) &&
207                 tc == TopComponent.getRegistry().getActivated()) {
208             Node[] filteredNodes = (Node[])event.getNewValue();
209             if (filteredNodes != null && filteredNodes.length >= 1) {
210                 // Set the active nodes for the parent TopComponent.
211
tc.setActivatedNodes(filteredNodes);
212             }
213         } else if(TopComponent.getRegistry().PROP_ACTIVATED_NODES.equals(property) &&
214                 tc != null && tc !=TopComponent.getRegistry().getActivated()) {
215             EventQueue.invokeLater(new Runnable JavaDoc() {
216                 public void run() {
217                     selectActivatedNodes();
218                 }
219             });
220         } else if(TopComponent.getRegistry().PROP_ACTIVATED.equals(property) &&
221                 tc == TopComponent.getRegistry().getActivated()) {
222             tc.setActivatedNodes(getExplorerManager().getSelectedNodes());
223         }
224     }
225     
226     private void selectActivatedNodes() {
227         Node[] activated = TopComponent.getRegistry().getActivatedNodes();
228         List JavaDoc<Node> selNodes = new ArrayList JavaDoc<Node>();
229         for(Node n:activated) {
230             SchemaComponent sc = (SchemaComponent) n.getLookup().
231                     lookup(SchemaComponent.class);
232             if(sc!=null) {
233                 List JavaDoc<Node> path = UIUtilities.findPathFromRoot(
234                         getExplorerManager().getRootContext(),sc);
235                 if(path!=null&&!path.isEmpty())
236                     selNodes.add(path.get(path.size()-1));
237             }
238         }
239         try {
240             getExplorerManager().setSelectedNodes(
241                     selNodes.toArray(new Node[0]));
242         } catch (PropertyVetoException JavaDoc ex) {
243         }
244     }
245     
246     public void onModelStateChanged(PropertyChangeEvent JavaDoc evt) {
247         State newState = (State)evt.getNewValue();
248         if(newState == SchemaModel.State.VALID) {
249             SchemaModel model = (SchemaModel)evt.getSource();
250             show(model);
251             return;
252         }
253         
254         //model is broken
255
showError();
256         return;
257     }
258     
259     private void showError() {
260         if (notAvailableLabel.isShowing()) {
261             return;
262         }
263         remove(treeView);
264         add(notAvailableLabel, BorderLayout.CENTER);
265         revalidate();
266         repaint();
267     }
268     
269     private void show(SchemaModel model) {
270         remove(notAvailableLabel);
271         add(treeView, BorderLayout.CENTER);
272         SchemaNodeFactory factory = new CategorizedSchemaNodeFactory(
273                 model, lookup);
274         Node node = factory.createRootNode();
275         getExplorerManager().setRootContext(node);
276         // Expand the default nodes.
277
EventQueue.invokeLater(this);
278         revalidate();
279         repaint();
280     }
281 }
282
Popular Tags