KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > viewmodel > TreeTable


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-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.viewmodel;
21
22 import java.awt.BorderLayout JavaDoc;
23 import java.beans.PropertyChangeEvent JavaDoc;
24 import java.beans.PropertyChangeListener JavaDoc;
25 import java.beans.PropertyEditor JavaDoc;
26
27
28 import java.util.*;
29 import javax.swing.ActionMap JavaDoc;
30 import javax.swing.JPanel JavaDoc;
31 import javax.swing.JScrollPane JavaDoc;
32 import javax.swing.JTable JavaDoc;
33 import javax.swing.JTree JavaDoc;
34 import javax.swing.SwingUtilities JavaDoc;
35 import javax.swing.event.TreeExpansionListener JavaDoc;
36 import javax.swing.event.TreeExpansionEvent JavaDoc;
37 import javax.swing.table.TableColumn JavaDoc;
38 import javax.swing.tree.TreeNode JavaDoc;
39
40 import javax.swing.tree.TreePath JavaDoc;
41 import javax.swing.tree.TreeModel JavaDoc;
42
43
44 import org.netbeans.spi.viewmodel.Models;
45 import org.netbeans.spi.viewmodel.ColumnModel;
46 import org.netbeans.spi.viewmodel.UnknownTypeException;
47 import org.openide.explorer.ExplorerUtils;
48
49 import org.openide.explorer.ExplorerManager;
50 import org.openide.explorer.view.BeanTreeView;
51
52 import org.openide.explorer.view.NodeTableModel;
53 import org.openide.explorer.view.TreeTableView;
54 import org.openide.explorer.view.Visualizer;
55
56 import org.openide.nodes.AbstractNode;
57 import org.openide.nodes.Children;
58 import org.openide.nodes.Node;
59 import org.openide.nodes.NodeNotFoundException;
60
61 import org.openide.nodes.NodeOp;
62
63 import org.openide.nodes.PropertySupport;
64 import org.openide.windows.TopComponent;
65
66
67 /**
68  * Implements root node of hierarchy created for given TreeModel.
69  *
70  * @author Jan Jancura
71  */

72 public class TreeTable extends JPanel JavaDoc implements
73 ExplorerManager.Provider, PropertyChangeListener JavaDoc, TreeExpansionListener JavaDoc {
74     
75     private ExplorerManager explorerManager;
76     private MyTreeTable treeTable;
77     Node.Property JavaDoc[] columns; // Accessed from tests
78
private List expandedPaths = new ArrayList ();
79     private TreeModelRoot currentTreeModelRoot;
80     private Models.CompoundModel model;
81     
82     
83     public TreeTable () {
84         setLayout (new BorderLayout JavaDoc ());
85             treeTable = new MyTreeTable ();
86             treeTable.setRootVisible (false);
87             treeTable.setVerticalScrollBarPolicy
88                 (JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
89             treeTable.setHorizontalScrollBarPolicy
90                 (JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
91         add (treeTable, "Center"); //NOI18N
92
treeTable.getTree ().addTreeExpansionListener (this);
93         ActionMap JavaDoc map = getActionMap();
94         map.put("delete", ExplorerUtils.actionDelete(getExplorerManager(), false));
95         
96     }
97     
98     public void setModel (Models.CompoundModel model) {
99         this.model = model;
100         
101         // 1) destroy old model
102
if (currentTreeModelRoot != null)
103             currentTreeModelRoot.destroy ();
104         
105         // 2) save current settings (like columns, expanded paths)
106
List ep = treeTable.getExpandedPaths ();
107         saveWidths ();
108         
109         // 3) no model => set empty root node & return
110
if (model == null) {
111             getExplorerManager ().setRootContext (
112                 new AbstractNode (Children.LEAF)
113             );
114             return;
115         }
116         
117         // 4) set columns for given model
118
columns = createColumns (model);
119         currentTreeModelRoot = new TreeModelRoot (model, this);
120         TreeModelNode rootNode = currentTreeModelRoot.getRootNode ();
121         getExplorerManager ().setRootContext (rootNode);
122         // The root node must be ready when setting the columns
123
treeTable.setProperties (columns);
124         
125         // 5) set root node for given model
126
// Moved to 4), because the new root node must be ready when setting columns
127

128         // 6) update column widths & expanded nodes
129
updateColumnWidths ();
130         //treeTable.expandNodes (expandedPaths);
131
// TODO: this is a workaround, we should find a better way later
132
/* We must not call children here - it can take a long time...
133          * the expansion is performed in TreeModelNode.TreeModelChildren.applyChildren()
134         final List backupPath = new ArrayList (expandedPaths);
135         if (backupPath.size () == 0)
136             TreeModelNode.getRequestProcessor ().post (new Runnable () {
137                 public void run () {
138                     try {
139                         final Object[] ch = TreeTable.this.model.getChildren
140                             (TreeTable.this.model.getRoot (), 0, 0);
141                         SwingUtilities.invokeLater (new Runnable () {
142                             public void run () {
143                                 expandDefault (ch);
144                             }
145                         });
146                     } catch (UnknownTypeException ex) {}
147                 }
148             });
149         else
150             SwingUtilities.invokeLater (new Runnable () {
151                 public void run () {
152                     treeTable.expandNodes (backupPath);
153                 }
154             });
155          */

156         if (ep.size () > 0) expandedPaths = ep;
157     }
158     
159     public ExplorerManager getExplorerManager () {
160         if (explorerManager == null) {
161             explorerManager = new ExplorerManager ();
162         }
163         return explorerManager;
164     }
165     
166     public void propertyChange (PropertyChangeEvent JavaDoc evt) {
167         String JavaDoc propertyName = evt.getPropertyName ();
168         TopComponent tc = (TopComponent) SwingUtilities.
169             getAncestorOfClass (TopComponent.class, this);
170         if (tc == null) return;
171         if (propertyName.equals (TopComponent.Registry.PROP_CURRENT_NODES)) {
172             ExplorerUtils.activateActions(getExplorerManager(), equalNodes());
173         } else
174         if (propertyName.equals (ExplorerManager.PROP_SELECTED_NODES)) {
175             tc.setActivatedNodes ((Node JavaDoc[]) evt.getNewValue ());
176         }
177     }
178     
179     /**
180       * Called whenever an item in the tree has been expanded.
181       */

182     public void treeExpanded (TreeExpansionEvent JavaDoc event) {
183         Object JavaDoc obj = Visualizer.findNode
184             (event.getPath ().getLastPathComponent ()).getLookup().lookup(Object JavaDoc.class);
185         model.nodeExpanded (obj);
186     }
187
188     /**
189       * Called whenever an item in the tree has been collapsed.
190       */

191     public void treeCollapsed (TreeExpansionEvent JavaDoc event) {
192         Object JavaDoc obj = Visualizer.findNode
193             (event.getPath ().getLastPathComponent ()).getLookup().lookup(Object JavaDoc.class);
194         model.nodeCollapsed (obj);
195     }
196     
197     private boolean equalNodes () {
198         Node JavaDoc[] ns1 = TopComponent.getRegistry ().getCurrentNodes ();
199         Node JavaDoc[] ns2 = getExplorerManager ().getSelectedNodes ();
200         if (ns1 == ns2) return true;
201         if ( (ns1 == null) || (ns2 == null) ) return false;
202         if (ns1.length != ns2.length) return false;
203         int i, k = ns1.length;
204         for (i = 0; i < k; i++)
205             if (!ns1 [i].equals (ns2 [i])) return false;
206         return true;
207     }
208     
209     private Node.Property JavaDoc[] createColumns (Models.CompoundModel model) {
210         ColumnModel[] cs = model.getColumns ();
211         int i, k = cs.length;
212         Node.Property JavaDoc[] columns = new Column [k];
213         boolean addDefaultColumn = true;
214         for (i = 0; i < k; i++) {
215             columns [i] = new Column (
216                 cs [i], this
217             );
218             if (cs [i].getType () == null)
219                 addDefaultColumn = false;
220         }
221         if (!addDefaultColumn) {
222             return columns;
223         }
224         PropertySupport.ReadWrite[] columns2 =
225             new PropertySupport.ReadWrite [columns.length + 1];
226         System.arraycopy (columns, 0, columns2, 1, columns.length);
227         columns2 [0] = new DefaultColumn ();
228         return columns2;
229     }
230     
231     boolean isCustomizedColumnIndex(Column c, int index) {
232         if (index == -1) return false;
233         int ci = 0, k = columns.length;
234         for (int i = 0; i < k; i++, ci++) {
235             if (Boolean.TRUE.equals (columns [i].getValue
236                 ("InvisibleInTreeTableView"))
237             ) continue;
238             if (c == columns[i]) {
239                 break;
240             }
241         }
242         return ci != index;
243     }
244     
245     void updateColumnWidths () {
246         int i, k = columns.length;
247         for (i = 0; i < k; i++) {
248             if (Boolean.TRUE.equals (columns [i].getValue
249                 ("InvisibleInTreeTableView"))
250             ) continue;
251             if (columns [i] instanceof Column) {
252                 Column column = (Column) columns [i];
253                 if (column.isDefault ()) {
254                     int width = column.getColumnWidth ();
255                     treeTable.setTreePreferredWidth (width);
256                 } else {
257                     int order = column.getOrderNumber ();
258                     if (order == -1) continue;
259                     int width = column.getColumnWidth ();
260                     treeTable.setTableColumnPreferredWidth (order, width);
261                 }
262             }
263         }
264     }
265     
266     private void saveWidths () {
267         if (columns == null) return;
268         int i, k = columns.length;
269         for (i = 0; i < k; i++) {
270             if (Boolean.TRUE.equals (columns [i].getValue
271                 ("InvisibleInTreeTableView"))
272             ) continue;
273             if (!(columns [i] instanceof Column)) continue;
274             Column column = (Column) columns [i];
275             if (column.isDefault ()) {
276                 TableColumn JavaDoc tc = treeTable.getTable ().getColumnModel ().
277                     getColumn (0);
278                 if (tc == null) continue;
279                 int width = tc.getWidth ();
280                 column.setColumnWidth (width);
281             } else {
282                 int order = column.getOrderNumber ();
283                 if (order == -1) continue;
284
285                 TableColumn JavaDoc tc = treeTable.getTable ().getColumnModel ().
286                     getColumn (order + 1);
287                 if (tc == null) continue;
288                 int width = tc.getWidth ();
289                 column.setColumnWidth (width);
290             }
291         }
292     }
293     
294     private void expandDefault (Object JavaDoc[] nodes) {
295         int i, k = nodes.length;
296         for (i = 0; i < k; i++)
297             try {
298                 if (model.isExpanded (nodes [i]))
299                     expandNode (nodes [i]);
300             } catch (UnknownTypeException ex) {
301             }
302     }
303     
304     /** Requests focus for the tree component. Overrides superclass method. */
305     public boolean requestFocusInWindow () {
306         super.requestFocusInWindow ();
307         return treeTable.requestFocusInWindow ();
308     }
309     
310     public void addNotify () {
311         super.addNotify ();
312         TopComponent.getRegistry ().addPropertyChangeListener (this);
313         getExplorerManager ().addPropertyChangeListener (this);
314     }
315     
316     public void removeNotify () {
317         super.removeNotify ();
318         TopComponent.getRegistry ().removePropertyChangeListener (this);
319         getExplorerManager ().removePropertyChangeListener (this);
320     }
321     
322     public boolean isExpanded (Object JavaDoc node) {
323         Node JavaDoc n = currentTreeModelRoot.findNode (node);
324         if (n == null) return false; // Something what does not exist is not expanded ;-)
325
return treeTable.isExpanded (n);
326     }
327
328     public void expandNode (Object JavaDoc node) {
329         Node JavaDoc n = currentTreeModelRoot.findNode (node);
330         if (treeTable != null && n != null)
331             treeTable.expandNode (n);
332     }
333
334     public void collapseNode (Object JavaDoc node) {
335         Node JavaDoc n = currentTreeModelRoot.findNode (node);
336         treeTable.collapseNode (n);
337     }
338     
339     private static class MyTreeTable extends TreeTableView {
340         MyTreeTable () {
341             super ();
342             treeTable.setShowHorizontalLines (true);
343             treeTable.setShowVerticalLines (false);
344         }
345         
346         JTable JavaDoc getTable () {
347             return treeTable;
348         }
349         
350         JTree JavaDoc getTree () {
351             return tree;
352         }
353
354         public List getExpandedPaths () {
355             List result = new ArrayList ();
356             ExplorerManager em = ExplorerManager.find (this);
357             TreeNode JavaDoc rtn = Visualizer.findVisualizer (
358                 em.getRootContext ()
359             );
360             TreePath JavaDoc tp = new TreePath JavaDoc (rtn); // Get the root
361

362             Enumeration exPaths = tree.getExpandedDescendants (tp);
363             if (exPaths == null) return result;
364             for (;exPaths.hasMoreElements ();) {
365                 TreePath JavaDoc ep = (TreePath JavaDoc) exPaths.nextElement ();
366                 Node JavaDoc en = Visualizer.findNode (ep.getLastPathComponent ());
367                 String JavaDoc[] path = NodeOp.createPath (en, em.getRootContext ());
368                 result.add (path);
369             }
370             return result;
371         }
372         
373         /** Expands all the paths, when exists
374          */

375         public void expandNodes (List exPaths) {
376             for (Iterator it = exPaths.iterator (); it.hasNext ();) {
377                 String JavaDoc[] sp = (String JavaDoc[]) it.next ();
378                 TreePath JavaDoc tp = stringPath2TreePath (sp);
379                 if (tp != null) showPath (tp);
380             }
381         }
382
383         /** Converts path of strings to TreePath if exists null otherwise
384          */

385         private TreePath JavaDoc stringPath2TreePath (String JavaDoc[] sp) {
386             ExplorerManager em = ExplorerManager.find (this);
387             try {
388                 Node JavaDoc n = NodeOp.findPath (em.getRootContext (), sp);
389                 
390                 // Create the tree path
391
TreeNode JavaDoc tns[] = new TreeNode JavaDoc [sp.length + 1];
392                 
393                 for (int i = sp.length; i >= 0; i--) {
394                     tns[i] = Visualizer.findVisualizer (n);
395                     n = n.getParentNode ();
396                 }
397                 return new TreePath JavaDoc (tns);
398             } catch (NodeNotFoundException e) {
399                 return null;
400             }
401         }
402     }
403 }
404
405
Popular Tags