KickJava   Java API By Example, From Geeks To Geeks.

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


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.beans.PropertyChangeEvent JavaDoc;
24 import java.beans.PropertyChangeListener JavaDoc;
25 import java.beans.PropertyVetoException JavaDoc;
26 import java.lang.reflect.Method JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.EventListener JavaDoc;
29 import java.util.List JavaDoc;
30 import javax.swing.JPanel JavaDoc;
31 import javax.swing.JScrollPane JavaDoc;
32 import org.netbeans.modules.xml.schema.model.SchemaComponent;
33 import org.netbeans.modules.xml.schema.model.SchemaModel;
34 import org.netbeans.modules.xml.schema.ui.nodes.SchemaNodeFactory;
35 import org.netbeans.modules.xml.schema.ui.nodes.StructuralSchemaNodeFactory;
36 import org.netbeans.modules.xml.schema.ui.nodes.categorized.CategorizedSchemaNodeFactory;
37 import org.netbeans.modules.xml.xam.ui.column.LinkPanel;
38 import org.netbeans.modules.xml.xam.ui.column.Column;
39 import org.netbeans.modules.xml.xam.ui.column.ColumnView;
40 import org.netbeans.modules.xml.xam.ui.column.BasicColumnView;
41 import org.openide.ErrorManager;
42 import org.openide.explorer.ExplorerManager;
43 import org.openide.nodes.Node;
44 import org.openide.util.Lookup;
45
46 /**
47  * Displays the XML schema in a series of columns, each usually
48  * containing a tree representing a subset of the schema model.
49  *
50  * <p><em>Note: SchemaColumnsView, like all NbColumnView subclasses, has its
51  * own JScrollPane, you do not need to place it in a JScrollPane.</em></p>
52  *
53  * @author Todd Fast, todd.fast@sun.com
54  * @author Nathan Fiedler
55  * @author Jeri Lockhart
56  */

57 public class SchemaColumnsView extends JPanel JavaDoc
58         implements ColumnView, PropertyChangeListener JavaDoc {
59     /** silence compiler warnings */
60     static final long serialVersionUID = 1L;
61     /** Where the columns are shown. */
62     private transient BasicColumnView columnView;
63     /** Where the bread crumbs live. */
64     private transient LinkPanel breadCrumbs;
65     private transient SchemaModel schemaModel;
66     private transient SchemaNodeFactory factory;
67     private ViewType viewType;
68     private transient Lookup lookup;
69     private Class JavaDoc<? extends EventListener JavaDoc> columnListenerClass;
70     private transient EventListener JavaDoc columnListener;
71     public static final String JavaDoc PROP_COLUMN_ADDED = "column_added";
72
73     public static enum ViewType {
74         /** The developer will set the node factory directly */
75         CUSTOM,
76         /** Use the categorized node factory */
77         CATEGORIZED,
78         /** Use the structural node factory */
79         STRUCTURAL;
80     }
81
82     /**
83      * Constructs a new instance of SchemaColumnsView.
84      *
85      * @param model schema model being displayed.
86      * @param viewType type of column view.
87      * @param lookup from whence services are found.
88      */

89     public SchemaColumnsView(SchemaModel model, ViewType viewType,
90             Lookup lookup) {
91         super(new BorderLayout JavaDoc());
92         breadCrumbs = new LinkPanel(this);
93         add(breadCrumbs, BorderLayout.NORTH);
94         columnView = new BasicColumnView();
95         add(columnView, BorderLayout.CENTER);
96         this.schemaModel = model;
97         this.lookup = lookup;
98         _setViewType(viewType);
99     }
100
101     /**
102      * Set the schema node factory.
103      *
104      * @param factory new schema node factory.
105      */

106     public void setNodeFactory(SchemaNodeFactory factory) {
107         _setNodeFactory(factory);
108     }
109
110     /**
111      * Private version of <code>setNodeFactory()</code> so it can be safely
112      * called from the constructor.
113      *
114      * @param factory new schema node factory.
115      */

116     private void _setNodeFactory(SchemaNodeFactory factory) {
117         this.factory = factory;
118         clearColumns();
119         Node rootNode = factory.createRootNode();
120         SchemaColumn rootPanel = createColumnComponent(rootNode, true);
121         appendColumn(rootPanel);
122     }
123
124     /**
125      * Construct a default column component for the given schema component.
126      *
127      * @param node root node of the schema component.
128      * @param showRoot true to show the root of the tree.
129      */

130     protected SchemaColumn createColumnComponent(Node node, boolean showRoot) {
131         SchemaColumn panel = new SchemaColumn(this, node, showRoot);
132         addColumnListener(panel);
133         return panel;
134     }
135
136     /**
137      * Add the pre-defined column listener to the given column.
138      *
139      * @param column SchemaColumn to which the listener is added.
140      */

141     public void addColumnListener(SchemaColumn column){
142         if (!(columnListener == null && columnListenerClass == null)) {
143             try {
144                 // Look for the method, e.g. addPropertyChangeListener.
145
Method JavaDoc addListenerMethod = SchemaColumn.class.getMethod(
146                         "add" + columnListenerClass.getSimpleName(),
147                         columnListenerClass); // NOI18N
148
addListenerMethod.invoke(column, columnListener);
149             } catch (Exception JavaDoc e) {
150                 // This is not expected to happen, but log it if it does.
151
ErrorManager.getDefault().notify(ErrorManager.WARNING, e);
152             }
153         }
154     }
155
156     /**
157      * Set the column listener for this column view. The listener will
158      * be added to each column instance that has a corresponding "add"
159      * method (e.g. "addPropertyChangeListener()").
160      *
161      * @param listenerClass class of the listener.
162      * @param listener listener to be added.
163      */

164     public <L extends EventListener JavaDoc> void setColumnListener(
165             Class JavaDoc<L> listenerClass, L listener) {
166         columnListenerClass = listenerClass;
167         columnListener = listener;
168     }
169
170     /**
171      * Retrieve the column listener, if one is defined.
172      *
173      * @return the column listener, or null if none.
174      */

175     public EventListener JavaDoc getColumnListener() {
176         return columnListener;
177     }
178
179     /**
180      * Private version of <code>setViewType()</code> so it can be safely
181      * called from the constructor.
182      *
183      * @param type the type of schema column view.
184      */

185     private void _setViewType(ViewType type) {
186         if (viewType != type) {
187             viewType = type;
188             SchemaNodeFactory factory = createNodeFactory(type);
189             if (factory != null) {
190                 _setNodeFactory(factory);
191             }
192         }
193     }
194
195     /**
196      * Create the SchemaNodeFactory appropriate for the given view type.
197      *
198      * @param type the type of schema column view.
199      */

200     private SchemaNodeFactory createNodeFactory(ViewType type) {
201         SchemaNodeFactory factory;
202         switch (type) {
203             case CATEGORIZED:
204                 factory = new CategorizedSchemaNodeFactory(schemaModel, lookup);
205                 break;
206             case STRUCTURAL:
207                 factory = new StructuralSchemaNodeFactory(schemaModel, lookup);
208                 break;
209             default:
210                 factory = null;
211                 break;
212         }
213         return factory;
214     }
215
216     public void propertyChange(PropertyChangeEvent JavaDoc event) {
217         Object JavaDoc src = event.getSource();
218         if (event.getPropertyName().equals(Column.PROP_TITLE) &&
219                 src instanceof Column) {
220             // Update the link title to reflect the change.
221
breadCrumbs.updateLink((Column) src);
222         }
223     }
224
225     public void showComponent(SchemaComponent sc) {
226         Node rootNode = null;
227         Column currentColumn = getFirstColumn();
228         ExplorerManager currentExplorer = null;
229         if(currentColumn instanceof ExplorerManager.Provider)
230             currentExplorer = ((ExplorerManager.Provider)currentColumn).
231                     getExplorerManager();
232         if(currentExplorer!=null) {
233             rootNode = currentExplorer.getRootContext();
234         } else {
235             rootNode = factory.createRootNode();
236             clearColumns();
237             currentColumn = createColumnComponent(rootNode,false);
238             appendColumn(currentColumn);
239             currentExplorer = ExplorerManager.find(currentColumn.getComponent());
240         }
241         List JavaDoc<Node> path = UIUtilities.findPathFromRoot(rootNode,sc);
242         if(path.isEmpty()) return;
243         // retain existing columns if appropriate
244
int idx = 0;
245         Column tmpColumn = currentColumn;
246         ExplorerManager tmpExplorer = currentExplorer;
247         for(Node node:path.subList(0,path.size()-1)) {
248             boolean found = false;
249             while(tmpExplorer!=null&&tmpExplorer.getRootContext()==node) {
250                 found = true;
251                 currentColumn = tmpColumn;
252                 currentExplorer = tmpExplorer;
253                 tmpColumn = getNextColumn(tmpColumn);
254                 if(!(tmpColumn instanceof ExplorerManager.Provider)) break;
255                 tmpExplorer = ((ExplorerManager.Provider)tmpColumn).
256                         getExplorerManager();
257             }
258             if(found) idx++;
259             else // remove columns if needed
260
{
261                 removeColumnsAfter(currentColumn);
262                 try {
263                     currentExplorer.setSelectedNodes(new Node[]{});
264                 } catch (PropertyVetoException JavaDoc ex) {
265                 }
266                 break;
267             }
268         }
269         // add necessary columns
270
if (idx < path.size() - 1) {
271             List JavaDoc<Column> columns = new ArrayList JavaDoc<Column>();
272             for (Node node : path.subList(idx, path.size() - 1)) {
273                 currentColumn = createColumnComponent(node, true);
274                 columns.add(currentColumn);
275             }
276             Column[] arr = columns.toArray(new Column[columns.size()]);
277             appendColumns(arr);
278         }
279         // select node representing component
280
if(currentColumn instanceof ExplorerManager.Provider)
281             currentExplorer = ((ExplorerManager.Provider)currentColumn).
282                     getExplorerManager();
283         try {
284             if(currentExplorer!=null)
285                 currentExplorer.setSelectedNodes(
286                         new Node[]{path.get(path.size()-1)});
287         } catch (PropertyVetoException JavaDoc ex) {
288         }
289     }
290
291     /**
292      * Remove our listeners from the columns, starting with the given
293      * column and moving toward the right.
294      *
295      * @param col first column from which to remove listeners.
296      */

297     private void removeListeners(Column col) {
298         while (col != null) {
299             col.removePropertyChangeListener(this);
300             col = getNextColumn(col);
301         }
302     }
303
304     @Override JavaDoc
305     public void requestFocus() {
306         super.requestFocus();
307         columnView.requestFocus();
308     }
309
310     @Override JavaDoc
311     public boolean requestFocusInWindow() {
312         super.requestFocusInWindow();
313         return columnView.requestFocusInWindow();
314     }
315
316     //
317
// ColumnView implementation
318
//
319

320     public void appendColumn(Column column) {
321         column.addPropertyChangeListener(this);
322         columnView.appendColumn(column);
323         breadCrumbs.appendLink(column);
324         firePropertyChange(PROP_COLUMN_ADDED, null, column);
325     }
326
327     public void appendColumns(Column[] columns) {
328         for (Column column : columns) {
329             column.addPropertyChangeListener(this);
330             breadCrumbs.appendLink(column);
331             firePropertyChange(PROP_COLUMN_ADDED, null, column);
332         }
333         columnView.appendColumns(columns);
334     }
335
336     public void clearColumns() {
337         removeListeners(getFirstColumn());
338         columnView.clearColumns();
339         breadCrumbs.clearLinks();
340     }
341
342     public int getColumnCount() {
343         return columnView.getColumnCount();
344     }
345
346     public int getColumnIndex(Column column) {
347         return columnView.getColumnIndex(column);
348     }
349
350     public Column getFirstColumn() {
351         return columnView.getFirstColumn();
352     }
353
354     public Column getNextColumn(Column column) {
355         return columnView.getNextColumn(column);
356     }
357
358     public void removeColumnsAfter(Column column) {
359         removeListeners(getNextColumn(column));
360         int index = columnView.getColumnIndex(column);
361         columnView.removeColumnsAfter(column);
362         // Remove the links after this column.
363
breadCrumbs.truncateLinks(index + 1);
364     }
365
366     public void scrollToColumn(Column column, boolean synchronous) {
367         columnView.scrollToColumn(column, synchronous);
368     }
369 }
370
Popular Tags