KickJava   Java API By Example, From Geeks To Geeks.

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


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;
21
22 import java.awt.BorderLayout JavaDoc;
23 import java.awt.Component 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.util.Enumeration JavaDoc;
29 import java.util.List JavaDoc;
30 import javax.swing.ActionMap JavaDoc;
31 import javax.swing.JPanel JavaDoc;
32 import javax.swing.JScrollPane JavaDoc;
33 import javax.swing.JTree JavaDoc;
34 import javax.swing.text.DefaultEditorKit JavaDoc;
35 import javax.swing.tree.TreeSelectionModel JavaDoc;
36 import org.openide.explorer.ExplorerManager;
37 import org.openide.explorer.ExplorerUtils;
38 import org.openide.explorer.view.BeanTreeView;
39 import org.openide.explorer.view.TreeView;
40 import org.openide.nodes.Node;
41 import org.openide.util.Lookup;
42 import org.openide.util.NbBundle;
43 import org.openide.windows.TopComponent;
44 import org.netbeans.modules.xml.schema.model.SchemaComponent;
45 import org.netbeans.modules.xml.schema.model.SchemaModel;
46 import org.netbeans.modules.xml.schema.ui.nodes.DefaultExpandedCookie;
47 import org.netbeans.modules.xml.schema.ui.nodes.SchemaNodeFactory;
48 import org.netbeans.modules.xml.schema.ui.nodes.StructuralSchemaNodeFactory;
49 import org.netbeans.modules.xml.schema.ui.nodes.categorized.CategorizedSchemaNodeFactory;
50
51 /**
52  * Represents the schema model using a tree view.
53  *
54  * @author Todd Fast, todd.fast@sun.com
55  * @author Nathan Fiedler
56  * @author Jeri Lockhart
57  */

58 public class SchemaTreeView extends JPanel JavaDoc
59         implements ExplorerManager.Provider, Lookup.Provider,
60         PropertyChangeListener JavaDoc {
61     private static final long serialVersionUID = 1L;
62     private ExplorerManager explorerManager;
63     private Lookup lookup;
64     private TreeView treeView;
65
66     public static enum ViewType {
67         /** Use the categorized node factory */
68         CATEGORIZED,
69         /** Use the structural node factory */
70         STRUCTURAL;
71     }
72
73     /**
74      * Creates a new instance of SchemaTreeView.
75      *
76      * @param model schema model.
77      * @param viewType type of view (categorized, structural).
78      * @param lookup the Lookup for this view.
79      */

80     public SchemaTreeView(SchemaModel model, ViewType viewType, Lookup lookup) {
81         super(new BorderLayout JavaDoc());
82         treeView = new BeanTreeView();
83         treeView.getAccessibleContext().setAccessibleName(NbBundle.getMessage(SchemaTreeCategory.class,
84                 "LBL_SchemaCategory_Tree"));
85         treeView.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(SchemaTreeCategory.class,
86                 "HINT_SchemaCategory_Tree"));
87         treeView.setRootVisible(true);
88         treeView.setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
89         treeView.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
90         add(treeView, BorderLayout.CENTER);
91
92         SchemaNodeFactory factory;
93         switch (viewType) {
94             case CATEGORIZED:
95                 factory = new CategorizedSchemaNodeFactory(model, lookup);
96                 break;
97             case STRUCTURAL:
98                 factory = new StructuralSchemaNodeFactory(model, lookup);
99                 break;
100             default:
101                 factory = null;
102                 break;
103         }
104         Node rootNode = factory.createRootNode();
105         explorerManager = new ExplorerManager();
106         explorerManager.setRootContext(rootNode);
107         // Listen to changes in the selection
108
explorerManager.addPropertyChangeListener(this);
109
110         // Set up the map of standard actions.
111
ActionMap JavaDoc map = getActionMap();
112         map.put(DefaultEditorKit.copyAction,
113                 ExplorerUtils.actionCopy(explorerManager));
114         map.put(DefaultEditorKit.cutAction,
115                 ExplorerUtils.actionCut(explorerManager));
116         map.put(DefaultEditorKit.pasteAction,
117                 ExplorerUtils.actionPaste(explorerManager));
118         map.put("delete", ExplorerUtils.actionDelete(explorerManager, false));
119         // This lookup is sufficient for us, no need to include the lookup
120
// coming from the argument list.
121
this.lookup = ExplorerUtils.createLookup(explorerManager, map);
122         // Do _not_ define the keyboard shortcuts for the actions, as
123
// they are in the lookup of our containing TopComponent, and
124
// those are activated by the standard keyboard bindings. If we
125
// define our own here, we get exceptions in OwnPaste (IZ#80500).
126

127         // Expand the default nodes
128
EventQueue.invokeLater(new Runnable JavaDoc() {
129             public void run() {
130                 expandDefaultNodes();
131             }
132         });
133     }
134
135     public ExplorerManager getExplorerManager() {
136         return explorerManager;
137     }
138
139     public Lookup getLookup() {
140         return lookup;
141     }
142
143     @Override JavaDoc
144     public void requestFocus() {
145         super.requestFocus();
146         treeView.requestFocus();
147     }
148
149     @Override JavaDoc
150     public boolean requestFocusInWindow() {
151         super.requestFocusInWindow();
152         return treeView.requestFocusInWindow();
153     }
154
155     /**
156      * Expand the nodes which should be expanded by default.
157      */

158     private void expandDefaultNodes() {
159         Node rootNode = getExplorerManager().getRootContext();
160         // Need to prevent looping on malformed trees, so avoid going too
161
// deep when expanding the children of nodes with only one child.
162
int depth = 0;
163         do {
164             Node[] children = rootNode.getChildren().getNodes();
165             if (children.length == 1) {
166                 // Expand all nodes that have only a single child.
167
treeView.expandNode(children[0]);
168                 rootNode = children[0];
169                 depth++;
170             } else {
171                 // Expand all first-level children that are meant to be shown
172
// expanded by default.
173
for (Node child : children) {
174                     DefaultExpandedCookie cookie = (DefaultExpandedCookie)
175                     child.getCookie(DefaultExpandedCookie.class);
176                     if (cookie != null && cookie.isDefaultExpanded()) {
177                         treeView.expandNode(child);
178                     }
179                 }
180                 rootNode = null;
181             }
182         } while (rootNode != null && depth < 5);
183
184         // The following code addresses two issues:
185
//
186
// 1. When viewing large schemas, expanding the default set of nodes
187
// generally means that the contents of the view are so long that
188
// copious amounts of scrolling are necessary to see it all. This is
189
// not desirable for the user's first experience with the document.
190
//
191
// 2. Because BasicTreeUI essentially ignores the scrollsOnExpand
192
// setting (or at least it does not work as documented), the tree
193
// is left scrolled to some random position.
194
//
195
// So, if scrolling is necessary, then collapse root's children.
196
JTree JavaDoc tree = (JTree JavaDoc) treeView.getViewport().getView();
197         if (tree.getRowCount() > tree.getVisibleRowCount()) {
198             rootNode = getExplorerManager().getRootContext();
199             Enumeration JavaDoc kids = rootNode.getChildren().nodes();
200             while (kids.hasMoreElements()) {
201                 Node kid = (Node) kids.nextElement();
202                 treeView.collapseNode(kid);
203             }
204         }
205     }
206
207     /**
208      * Finds the TopComponent that contains us.
209      *
210      * @return the parent TopComponent.
211      */

212     private TopComponent findParentTopComponent() {
213         Component JavaDoc parent = getParent();
214         while (parent != null) {
215             if (parent instanceof TopComponent) {
216                 return (TopComponent) parent;
217             } else {
218                 parent = parent.getParent();
219             }
220         }
221         return null;
222     }
223
224     public void propertyChange(PropertyChangeEvent JavaDoc event) {
225         if (ExplorerManager.PROP_SELECTED_NODES.equals(
226                 event.getPropertyName())) {
227             Node[] filteredNodes = (Node[]) event.getNewValue();
228             if (filteredNodes != null && filteredNodes.length >= 1) {
229                 // Set the active nodes for the parent TopComponent.
230
TopComponent tc = findParentTopComponent();
231                 if (tc != null) {
232                     tc.setActivatedNodes(filteredNodes);
233                 }
234             }
235         }
236     }
237
238     public void showComponent(SchemaComponent sc) {
239         List JavaDoc<Node> path = UIUtilities.findPathFromRoot(
240                 getExplorerManager().getRootContext(), sc);
241         if (path == null || path.isEmpty()) {
242             return;
243         }
244         Node node = path.get(path.size() - 1);
245         // If using the explorer manager to show selection does not work,
246
// use the following code instead.
247
// JTree tree = (JTree) treeView.getViewport().getView();
248
// NodeTreeModel model = (NodeTreeModel) tree.getModel();
249
// TreeNode tn = Visualizer.findVisualizer(node);
250
// TreeNode[] tnp = model.getPathToRoot(tn);
251
// TreePath treePath = new TreePath(tnp);
252
// tree.setSelectionPath(treePath);
253
// tree.scrollPathToVisible(treePath);
254
try {
255             getExplorerManager().setSelectedNodes(new Node[] { node });
256         } catch (PropertyVetoException JavaDoc pve) {
257         }
258     }
259 }
260
Popular Tags