KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > spi > viewmodel > Models


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.spi.viewmodel;
21
22 import java.awt.event.ActionEvent JavaDoc;
23 import java.lang.StringBuffer JavaDoc;
24 import java.lang.ref.WeakReference JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Collection JavaDoc;
27 import java.util.Collections JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.HashSet JavaDoc;
30 import java.util.IdentityHashMap JavaDoc;
31 import java.util.Iterator JavaDoc;
32 import java.util.LinkedList JavaDoc;
33 import java.util.List JavaDoc;
34 import java.util.Set JavaDoc;
35 import java.util.Vector JavaDoc;
36 import java.util.WeakHashMap JavaDoc;
37 import javax.swing.AbstractAction JavaDoc;
38 import javax.swing.Action JavaDoc;
39 import javax.swing.JComponent JavaDoc;
40 import javax.swing.SwingUtilities JavaDoc;
41
42 import org.netbeans.modules.viewmodel.TreeModelNode;
43 import org.netbeans.modules.viewmodel.TreeTable;
44
45 import org.netbeans.spi.viewmodel.ColumnModel;
46 import org.netbeans.spi.viewmodel.NodeActionsProvider;
47 import org.netbeans.spi.viewmodel.NodeActionsProviderFilter;
48 import org.netbeans.spi.viewmodel.NodeModel;
49 import org.netbeans.spi.viewmodel.NodeModelFilter;
50 import org.netbeans.spi.viewmodel.TableModel;
51 import org.netbeans.spi.viewmodel.TableModelFilter;
52 import org.netbeans.spi.viewmodel.TreeModel;
53 import org.netbeans.spi.viewmodel.TreeModelFilter;
54 import org.netbeans.spi.viewmodel.ModelListener;
55 import org.netbeans.spi.viewmodel.UnknownTypeException;
56 import org.openide.nodes.Node;
57 import org.openide.util.WeakSet;
58
59 import org.openide.windows.TopComponent;
60
61
62 /**
63  * Contains various utility methods for various models.
64  *
65  * @author Jan Jancura
66  */

67 public final class Models {
68
69     /** Cached default implementations of expansion models. */
70     private static WeakHashMap JavaDoc defaultExpansionModels = new WeakHashMap JavaDoc();
71     /**
72      * Empty model - returns default root node with no children.
73      */

74     public static CompoundModel EMPTY_MODEL = createCompoundModel
75         (new ArrayList JavaDoc ());
76     
77     
78     public static int MULTISELECTION_TYPE_EXACTLY_ONE = 1;
79     public static int MULTISELECTION_TYPE_ALL = 2;
80     public static int MULTISELECTION_TYPE_ANY = 3;
81     
82     private static boolean verbose =
83         System.getProperty ("netbeans.debugger.models") != null;
84     
85     
86     /**
87      * Creates a new instance of TreeTableView
88      * for given {@link org.netbeans.spi.viewmodel.Models.CompoundModel}.
89      *
90      * @param compoundModel a compound model instance
91      *
92      * @return new instance of complete model view
93      */

94     public static JComponent JavaDoc createView (
95         CompoundModel compoundModel
96     ) {
97         TreeTable tt = new TreeTable ();
98         tt.setModel (compoundModel);
99         return tt;
100     }
101     
102     /**
103      * Set given models to given view instance.
104      *
105      * @param view a view instance - must be an instance created by {@link #createView} method.
106      * @param compoundModel a compound model instance
107      */

108     public static void setModelsToView (
109         final JComponent JavaDoc view,
110         final CompoundModel compoundModel
111     ) {
112         if (!(view instanceof TreeTable)) {
113             throw new IllegalArgumentException JavaDoc("Expecting an instance of "+TreeTable.class.getName()+", which can be obtained from Models.createView().");
114         }
115         if (verbose)
116             System.out.println (compoundModel);
117         SwingUtilities.invokeLater (new Runnable JavaDoc () {
118             public void run () {
119                 ((TreeTable) view).setModel (compoundModel);
120             }
121         });
122     }
123     
124     /**
125      * Creates one {@link CompoundModel} from given list of models.
126      * <p>
127      * If this list does not include any instance of TreeModel or
128      * TreeExpansionModel, a default implementation of these models is created
129      * based on the instance of this list. Thus you get one implementation
130      * per provided instance of the models list.
131      *
132      * @param models a list of models
133      * @return {@link CompoundModel} encapsulating given list of models
134      */

135     public static CompoundModel createCompoundModel (List JavaDoc models) {
136         return createCompoundModel(models, null);
137     }
138     
139     /**
140      * Creates one {@link CompoundModel} from given list of models.
141      * <p>
142      * If this list does not include any instance of TreeModel or
143      * TreeExpansionModel, a default implementation of these models is created
144      * based on the instance of this list. Thus you get one implementation
145      * per provided instance of the models list.
146      *
147      * @param models a list of models
148      * @param propertiesHelpID The help ID, which is set for the properties
149      * sheets created from this model.
150      * @return {@link CompoundModel} encapsulating given list of models
151      * @since 1.7
152      */

153     public static CompoundModel createCompoundModel (List JavaDoc models, String JavaDoc propertiesHelpID) {
154         List JavaDoc treeModels;
155         List JavaDoc treeModelFilters;
156         List JavaDoc treeExpansionModels;
157         List JavaDoc nodeModels;
158         List JavaDoc nodeModelFilters;
159         List JavaDoc tableModels;
160         List JavaDoc tableModelFilters;
161         List JavaDoc nodeActionsProviders;
162         List JavaDoc nodeActionsProviderFilters;
163         List JavaDoc columnModels;
164         List JavaDoc otherModels;
165         
166         // Either the list contains 10 lists of individual models + one list of mixed models; or the models directly
167
boolean hasLists = false;
168         if (models.size() == 11) {
169             Iterator JavaDoc it = models.iterator ();
170             while (it.hasNext ()) {
171                 if (!(it.next() instanceof List JavaDoc)) break;
172             }
173             if (!it.hasNext()) { // All elements are lists
174
hasLists = true;
175             }
176         }
177         if (hasLists) { // We have 11 lists of individual models
178
treeModels = (List JavaDoc) models.get(0);
179             treeModelFilters = (List JavaDoc) models.get(1);
180             revertOrder(treeModelFilters);
181             treeExpansionModels = (List JavaDoc) models.get(2);
182             nodeModels = (List JavaDoc) models.get(3);
183             nodeModelFilters = (List JavaDoc) models.get(4);
184             revertOrder(nodeModelFilters);
185             tableModels = (List JavaDoc) models.get(5);
186             tableModelFilters = (List JavaDoc) models.get(6);
187             revertOrder(tableModelFilters);
188             nodeActionsProviders = (List JavaDoc) models.get(7);
189             nodeActionsProviderFilters = (List JavaDoc) models.get(8);
190             revertOrder(nodeActionsProviderFilters);
191             columnModels = (List JavaDoc) models.get(9);
192             otherModels = (List JavaDoc) models.get(10);
193         } else { // We have the models, need to find out what they implement
194
treeModels = new LinkedList JavaDoc ();
195             treeModelFilters = new LinkedList JavaDoc ();
196             treeExpansionModels = new LinkedList JavaDoc ();
197             nodeModels = new LinkedList JavaDoc ();
198             nodeModelFilters = new LinkedList JavaDoc ();
199             tableModels = new LinkedList JavaDoc ();
200             tableModelFilters = new LinkedList JavaDoc ();
201             nodeActionsProviders = new LinkedList JavaDoc ();
202             nodeActionsProviderFilters = new LinkedList JavaDoc ();
203             columnModels = new LinkedList JavaDoc ();
204             otherModels = models;
205         }
206             
207         Iterator JavaDoc it = otherModels.iterator ();
208         while (it.hasNext ()) {
209             Object JavaDoc model = it.next ();
210             boolean first = model.getClass ().getName ().endsWith ("First");
211             if (model instanceof TreeModel)
212                 treeModels.add(model);
213             if (model instanceof TreeModelFilter)
214                 if (first)
215                     treeModelFilters.add(model);
216                 else
217                     treeModelFilters.add(0, model);
218             if (model instanceof TreeExpansionModel)
219                 treeExpansionModels.add(model);
220             if (model instanceof NodeModel)
221                 nodeModels.add(model);
222             if (model instanceof NodeModelFilter)
223                 if (first)
224                     nodeModelFilters.add(model);
225                 else
226                     nodeModelFilters.add(0, model);
227             if (model instanceof TableModel)
228                 tableModels.add(model);
229             if (model instanceof TableModelFilter)
230                 if (first)
231                     tableModelFilters.add(model);
232                 else
233                     tableModelFilters.add(0, model);
234             if (model instanceof NodeActionsProvider)
235                 nodeActionsProviders.add(model);
236             if (model instanceof NodeActionsProviderFilter)
237                 if (first)
238                     nodeActionsProviderFilters.add(model);
239                 else
240                     nodeActionsProviderFilters.add(0, model);
241             if (model instanceof ColumnModel)
242                 columnModels.add(model);
243         }
244         /*
245         System.out.println("Tree Models = "+treeModels);
246         System.out.println("Tree Model Filters = "+treeModelFilters);
247         System.out.println("Tree Expans Models = "+treeExpansionModels);
248         System.out.println("Node Models = "+nodeModels);
249         System.out.println("Node Model Filters = "+nodeModelFilters);
250         System.out.println("Table Models = "+tableModels);
251         System.out.println("Table Model Filters = "+tableModelFilters);
252         System.out.println("Node Action Providers = "+nodeActionsProviders);
253         System.out.println("Node Action Provider Filters = "+nodeActionsProviderFilters);
254         System.out.println("Column Models = "+columnModels);
255          */

256         if (treeModels.isEmpty ()) {
257             treeModels = Collections.singletonList(new EmptyTreeModel ());
258         }
259         if (treeExpansionModels.isEmpty()) {
260             TreeExpansionModel tem = (TreeExpansionModel) defaultExpansionModels.get(models);
261             if (tem == null) {
262                 tem = new DefaultTreeExpansionModel();
263                 defaultExpansionModels.put(models, tem);
264             }
265             treeExpansionModels = Collections.singletonList(tem);
266         }
267         
268         return new CompoundModel (
269             createCompoundTreeModel (
270                 new DelegatingTreeModel (treeModels),
271                 treeModelFilters
272             ),
273             new DelegatingTreeExpansionModel (treeExpansionModels),
274             createCompoundNodeModel (
275                 new DelegatingNodeModel (nodeModels),
276                 nodeModelFilters
277             ),
278             createCompoundNodeActionsProvider (
279                 new DelegatingNodeActionsProvider (nodeActionsProviders),
280                 nodeActionsProviderFilters
281             ),
282             columnModels,
283             createCompoundTableModel (
284                 new DelegatingTableModel (tableModels),
285                 tableModelFilters
286             ),
287             propertiesHelpID
288         );
289     }
290     
291     private static void revertOrder(List JavaDoc filters) {
292         int n = filters.size();
293         for (int i = 0; i < n; ) {
294             Object JavaDoc filter = filters.remove(i);
295             boolean first = filter.getClass ().getName ().endsWith ("First");
296             if (first) { // The "First" should be the last one in this list
297
filters.add(filter);
298                 n--;
299             } else {
300                 filters.add(0, filter);
301                 i++;
302             }
303         }
304     }
305     
306     
307     /**
308      * Returns {@link javax.swing.Action} for given parameters.
309      *
310      * @param displayName a display name for action
311      * @param performer a performer for action
312      * @param multiselectionType The type of the multiselection - one of the
313      * MULTISELECTION_TYPE_* constants.
314      *
315      * @return a new instance of {@link javax.swing.Action} for given parameters
316      */

317     public static Action JavaDoc createAction (
318         String JavaDoc displayName,
319         ActionPerformer performer,
320         int multiselectionType
321     ) {
322         return new ActionSupport (
323             displayName,
324             performer,
325             multiselectionType
326         );
327     }
328     
329     /**
330      * Returns implementation of tree view features for given view.
331      *
332      * @param view a view created by this Models class
333      * @throws UnsupportedOperationException in the case that given
334      * view is not tree view
335      * @return implementation of tree view features
336      */

337     public static TreeFeatures treeFeatures (JComponent JavaDoc view)
338     throws UnsupportedOperationException JavaDoc {
339         return new TreeFeatures (view);
340     }
341     
342     
343     // private methods .........................................................
344

345     /**
346      * Creates {@link org.netbeans.spi.viewmodel.TreeModel} for given TreeModel and
347      * {@link org.netbeans.spi.viewmodel.TreeModelFilter}.
348      *
349      * @param originalTreeModel a original tree model
350      * @param treeModelFilter a list of tree model filters
351      *
352      * @returns compund tree model
353      */

354     private static TreeModel createCompoundTreeModel (
355         TreeModel originalTreeModel,
356         List JavaDoc treeModelFilters
357     ) {
358         TreeModel tm = originalTreeModel;
359         int i, k = treeModelFilters.size ();
360         for (i = 0; i < k; i++)
361             tm = new CompoundTreeModel (
362                 tm,
363                 (TreeModelFilter) treeModelFilters.get (i)
364             );
365         return tm;
366     }
367     
368     /**
369      * Creates {@link org.netbeans.spi.viewmodel.NodeModel} for given NodeModel and
370      * {@link org.netbeans.spi.viewmodel.NodeModelFilter}.
371      *
372      * @param originalNodeModel a original node model
373      * @param nodeModelFilters a list of node model filters
374      *
375      * @returns compund tree model
376      */

377     private static NodeModel createCompoundNodeModel (
378         NodeModel originalNodeModel,
379         List JavaDoc treeNodeModelFilters
380     ) {
381         NodeModel nm = originalNodeModel;
382         int i, k = treeNodeModelFilters.size ();
383         for (i = 0; i < k; i++)
384             nm = new CompoundNodeModel (
385                 nm,
386                 (NodeModelFilter) treeNodeModelFilters.get (i)
387             );
388         return nm;
389     }
390     
391     /**
392      * Creates {@link org.netbeans.spi.viewmodel.TableModel} for given TableModel and
393      * {@link org.netbeans.spi.viewmodel.TableModelFilter}.
394      *
395      * @param originalTableModel a original table model
396      * @param tableModelFilters a list of table model filters
397      *
398      * @returns compund table model
399      */

400     private static TableModel createCompoundTableModel (
401         TableModel originalTableModel,
402         List JavaDoc tableModelFilters
403     ) {
404         TableModel tm = originalTableModel;
405         int i, k = tableModelFilters.size ();
406         for (i = 0; i < k; i++)
407             tm = new CompoundTableModel (
408                 tm,
409                 (TableModelFilter) tableModelFilters.get (i)
410             );
411         return tm;
412     }
413     
414     /**
415      * Creates {@link org.netbeans.spi.viewmodel.NodeActionsProvider} for given NodeActionsProvider and
416      * {@link org.netbeans.spi.viewmodel.NodeActionsProviderFilter}.
417      *
418      * @param originalNodeActionsProvider a original node actions provider
419      * @param nodeActionsProviderFilters a list of node actions provider filters
420      *
421      * @returns compund node actions provider
422      */

423     private static NodeActionsProvider createCompoundNodeActionsProvider (
424         NodeActionsProvider originalNodeActionsProvider,
425         List JavaDoc nodeActionsProviderFilters
426     ) {
427         NodeActionsProvider nap = originalNodeActionsProvider;
428         int i, k = nodeActionsProviderFilters.size ();
429         for (i = 0; i < k; i++)
430             nap = new CompoundNodeActionsProvider (
431                 nap,
432                 (NodeActionsProviderFilter) nodeActionsProviderFilters.get (i)
433             );
434         return nap;
435     }
436     
437     
438     // innerclasses ............................................................
439

440     /**
441      * @author Jan Jancura
442      */

443     private static class ActionSupport extends AbstractAction JavaDoc {
444
445         private ActionPerformer performer;
446         private int multiselectionType;
447         private String JavaDoc displayName;
448
449  
450         ActionSupport (
451             String JavaDoc displayName,
452             ActionPerformer performer,
453             int multiselectionType
454         ) {
455             super (displayName);
456             this.performer = performer;
457             this.displayName = displayName;
458             this.multiselectionType = multiselectionType;
459         }
460         
461         public boolean isEnabled () {
462             if (multiselectionType == MULTISELECTION_TYPE_ANY)
463                 return true;
464             Node[] ns = TopComponent.getRegistry ().getActivatedNodes ();
465             if (multiselectionType == MULTISELECTION_TYPE_EXACTLY_ONE) {
466                 if (ns.length != 1) return false;
467                 return performer.isEnabled (
468                     ns[0].getLookup().lookup(Object JavaDoc.class)
469                 );
470             }
471             int i, k = ns.length;
472             for (i = 0; i < k; i++)
473                 if (!performer.isEnabled (
474                     ns[i].getLookup().lookup(Object JavaDoc.class)
475                  )) return false;
476             return true;
477         }
478
479         public void actionPerformed (ActionEvent JavaDoc e) {
480             Node[] ns = TopComponent.getRegistry ().getActivatedNodes ();
481             int i, k = ns.length;
482             IdentityHashMap JavaDoc h = new IdentityHashMap JavaDoc ();
483             for (i = 0; i < k; i++) {
484                 Object JavaDoc node = ns[i].getLookup().lookup(Object JavaDoc.class);
485                 Action JavaDoc[] as = ns [i].getActions (false);
486                 int j, jj = as.length;
487                 for (j = 0; j < jj; j++)
488                     if (equals (as [j])) {
489                         ArrayList JavaDoc l = (ArrayList JavaDoc) h.get (as [j]);
490                         if (l == null) {
491                             l = new ArrayList JavaDoc ();
492                             h.put (as [j], l);
493                         }
494                         l.add (node);
495                     }
496             }
497             Iterator JavaDoc it = h.keySet ().iterator ();
498             while (it.hasNext ()) {
499                 ActionSupport a = (ActionSupport) it.next ();
500                 a.performer.perform (
501                     ((ArrayList JavaDoc) h.get (a)).toArray ()
502                 );
503             }
504         }
505         
506         public int hashCode () {
507             return displayName.hashCode ();
508         }
509         
510         public boolean equals (Object JavaDoc o) {
511             return (o instanceof ActionSupport) &&
512                 displayName.equals (((ActionSupport) o).displayName);
513         }
514     }
515
516     /**
517      * Support interface for
518      * {@link #createAction(String,Models.ActionPerformer,int)} method.
519      */

520     public static interface ActionPerformer {
521
522         /**
523          * Returns enabled property state for given node.
524          *
525          * @param node the node the action shouuld be applied to
526          * @return enabled property state for given node
527          *
528          * @see #createAction(String,Models.ActionPerformer,int)
529          */

530         public boolean isEnabled (Object JavaDoc node);
531
532         /**
533          * Called when action <code>action</code> is performed for
534          * nodes.
535          *
536          * @param nodes nodes the action shouuld be applied to
537          *
538          * @see #createAction(String,Models.ActionPerformer,int)
539          */

540         public void perform (Object JavaDoc[] nodes);
541     }
542
543     /**
544      * Creates {@link org.netbeans.spi.viewmodel.TreeModel} for given TreeModel and
545      * {@link org.netbeans.spi.viewmodel.TreeModelFilter}.
546      *
547      * @author Jan Jancura
548      */

549     final static class CompoundTreeModel implements TreeModel, ModelListener {
550
551
552         private TreeModel model;
553         private TreeModelFilter filter;
554         
555         private Collection JavaDoc modelListeners = new HashSet JavaDoc();
556
557         
558         /**
559          * Creates {@link org.netbeans.spi.viewmodel.TreeModel} for given TreeModel and
560          * {@link org.netbeans.spi.viewmodel.TreeModelFilter}.
561          */

562         CompoundTreeModel (TreeModel model, TreeModelFilter filter) {
563             this.model = model;
564             this.filter = filter;
565         }
566
567         /**
568          * Returns the root node of the tree or null, if the tree is empty.
569          *
570          * @return the root node of the tree or null
571          */

572         public Object JavaDoc getRoot () {
573             return filter.getRoot (model);
574         }
575
576         /**
577          * Returns children for given parent on given indexes.
578          *
579          * @param parent a parent of returned nodes
580          * @throws NoInformationException if the set of children can not be
581          * resolved
582          * @throws UnknownTypeException if this TreeModel implementation is not
583          * able to resolve dchildren for given node type
584          *
585          * @return children for given parent on given indexes
586          */

587         public Object JavaDoc[] getChildren (Object JavaDoc parent, int from, int to)
588             throws UnknownTypeException {
589
590             return filter.getChildren (model, parent, from, to);
591         }
592     
593         /**
594          * Returns number of children for given node.
595          *
596          * @param node the parent node
597          * @throws NoInformationException if the set of children can not be
598          * resolved
599          * @throws UnknownTypeException if this TreeModel implementation is not
600          * able to resolve children for given node type
601          *
602          * @return true if node is leaf
603          */

604         public int getChildrenCount (Object JavaDoc node) throws UnknownTypeException {
605             return filter.getChildrenCount (model, node);
606         }
607
608         /**
609          * Returns true if node is leaf.
610          *
611          * @throws UnknownTypeException if this TreeModel implementation is not
612          * able to resolve dchildren for given node type
613          * @return true if node is leaf
614          */

615         public boolean isLeaf (Object JavaDoc node) throws UnknownTypeException {
616             return filter.isLeaf (model, node);
617         }
618
619         /**
620          * Registers given listener.
621          *
622          * @param l the listener to add
623          */

624         public void addModelListener (ModelListener l) {
625             synchronized (modelListeners) {
626                 if (modelListeners.size() == 0) {
627                     filter.addModelListener (this);
628                     model.addModelListener (this);
629                 }
630                 modelListeners.add(l);
631             }
632         }
633
634         /**
635          * Unregisters given listener.
636          *
637          * @param l the listener to remove
638          */

639         public void removeModelListener (ModelListener l) {
640             synchronized (modelListeners) {
641                 modelListeners.remove(l);
642                 if (modelListeners.size() == 0) {
643                     filter.removeModelListener (this);
644                     model.removeModelListener (this);
645                 }
646             }
647         }
648
649         public void modelChanged(ModelEvent event) {
650             ModelEvent newEvent = translateEvent(event, this);
651             Collection JavaDoc listeners;
652             synchronized (modelListeners) {
653                 listeners = new ArrayList JavaDoc(modelListeners);
654             }
655             for (Iterator JavaDoc it = listeners.iterator(); it.hasNext(); ) {
656                 ((ModelListener) it.next()).modelChanged(newEvent);
657             }
658         }
659         
660         public String JavaDoc toString () {
661             return super.toString () + "\n" + toString (" ");
662         }
663         
664         public String JavaDoc toString (String JavaDoc n) {
665             if (model instanceof CompoundTreeModel)
666                 return n + filter + "\n" +
667                     ((CompoundTreeModel) model).toString (n + " ");
668             return n + filter + "\n" +
669                    n + " " + model;
670         }
671
672     }
673     
674     private static ModelEvent translateEvent(ModelEvent event, Object JavaDoc newSource) {
675         ModelEvent newEvent;
676         if (event instanceof ModelEvent.NodeChanged) {
677             newEvent = new ModelEvent.NodeChanged(newSource,
678                     ((ModelEvent.NodeChanged) event).getNode(),
679                     ((ModelEvent.NodeChanged) event).getChange());
680         } else if (event instanceof ModelEvent.TableValueChanged) {
681             newEvent = new ModelEvent.TableValueChanged(newSource,
682                     ((ModelEvent.TableValueChanged) event).getNode(),
683                     ((ModelEvent.TableValueChanged) event).getColumnID());
684         } else if (event instanceof ModelEvent.TreeChanged) {
685             newEvent = new ModelEvent.TreeChanged(newSource);
686         } else {
687             newEvent = event;
688         }
689         return newEvent;
690     }
691     
692     /**
693      * Creates {@link org.netbeans.spi.viewmodel.TreeModel} for given TreeModel and
694      * {@link org.netbeans.spi.viewmodel.TreeModelFilter}.
695      *
696      * @author Jan Jancura
697      */

698     final static class CompoundNodeModel implements NodeModel, ModelListener {
699
700
701         private NodeModel model;
702         private NodeModelFilter filter;
703
704         private Collection JavaDoc modelListeners = new HashSet JavaDoc();
705
706
707         /**
708          * Creates {@link org.netbeans.spi.viewmodel.TreeModel} for given TreeModel and
709          * {@link org.netbeans.spi.viewmodel.TreeModelFilter}.
710          */

711         CompoundNodeModel (NodeModel model, NodeModelFilter filter) {
712             this.model = model;
713             this.filter = filter;
714         }
715     
716         /**
717          * Returns display name for given node.
718          *
719          * @throws UnknownTypeException if this NodeModel implementation is not
720          * able to resolve display name for given node type
721          * @return display name for given node
722          */

723         public String JavaDoc getDisplayName (Object JavaDoc node)
724         throws UnknownTypeException {
725             return filter.getDisplayName (model, node);
726         }
727
728         /**
729          * Returns icon for given node.
730          *
731          * @throws UnknownTypeException if this NodeModel implementation is not
732          * able to resolve icon for given node type
733          * @return icon for given node
734          */

735         public String JavaDoc getIconBase (Object JavaDoc node)
736         throws UnknownTypeException {
737             return filter.getIconBase (model, node);
738         }
739
740         /**
741          * Returns tooltip for given node.
742          *
743          * @throws UnknownTypeException if this NodeModel implementation is not
744          * able to resolve tooltip for given node type
745          * @return tooltip for given node
746          */

747         public String JavaDoc getShortDescription (Object JavaDoc node)
748         throws UnknownTypeException {
749             return filter.getShortDescription (model, node);
750         }
751
752
753         /**
754          * Registers given listener.
755          *
756          * @param l the listener to add
757          */

758         public void addModelListener (ModelListener l) {
759             synchronized (modelListeners) {
760                 if (modelListeners.size() == 0) {
761                     filter.addModelListener (this);
762                     model.addModelListener (this);
763                 }
764                 modelListeners.add(l);
765             }
766         }
767
768         /**
769          * Unregisters given listener.
770          *
771          * @param l the listener to remove
772          */

773         public void removeModelListener (ModelListener l) {
774             synchronized (modelListeners) {
775                 modelListeners.remove(l);
776                 if (modelListeners.size() == 0) {
777                     filter.removeModelListener (this);
778                     model.removeModelListener (this);
779                 }
780             }
781         }
782
783         public void modelChanged(ModelEvent event) {
784             ModelEvent newEvent = translateEvent(event, this);
785             Collection JavaDoc listeners;
786             synchronized (modelListeners) {
787                 listeners = new ArrayList JavaDoc(modelListeners);
788             }
789             for (Iterator JavaDoc it = listeners.iterator(); it.hasNext(); ) {
790                 ((ModelListener) it.next()).modelChanged(newEvent);
791             }
792         }
793         
794         public String JavaDoc toString () {
795             return super.toString () + "\n" + toString (" ");
796         }
797         
798         public String JavaDoc toString (String JavaDoc n) {
799             if (model instanceof CompoundNodeModel)
800                 return n + filter + "\n" +
801                     ((CompoundNodeModel) model).toString (n + " ");
802             if (model instanceof DelegatingNodeModel)
803                 return n + filter + "\n" +
804                     ((DelegatingNodeModel) model).toString (n + " ");
805             return n + filter + "\n" +
806                    n + " " + model;
807         }
808     }
809     
810     /**
811      * Creates {@link org.netbeans.spi.viewmodel.TableModel} for given TableModel and
812      * {@link org.netbeans.spi.viewmodel.TableModelFilter}.
813      *
814      * @author Jan Jancura
815      */

816     final static class CompoundTableModel implements TableModel, ModelListener {
817
818
819         private TableModel model;
820         private TableModelFilter filter;
821
822         private Collection JavaDoc modelListeners = new HashSet JavaDoc();
823
824
825         /**
826          * Creates {@link org.netbeans.spi.viewmodel.TableModel} for given TableModel and
827          * {@link org.netbeans.spi.viewmodel.TableModelFilter}.
828          */

829         CompoundTableModel (TableModel model, TableModelFilter filter) {
830             this.model = model;
831             this.filter = filter;
832         }
833     
834         /**
835          * Returns value to be displayed in column <code>columnID</code>
836          * and row <code>node</code>. Column ID is defined in by
837          * {@link ColumnModel#getID}, and rows are defined by values returned from
838          * {@TreeModel#getChildren}.
839          *
840          * @param node a object returned from {@TreeModel#getChildren} for this row
841          * @param columnID a id of column defined by {@link ColumnModel#getID}
842          * @throws UnknownTypeException if there is no TableModel defined for given
843          * parameter type
844          *
845          * @return value of variable representing given position in tree table.
846          */

847         public Object JavaDoc getValueAt (Object JavaDoc node, String JavaDoc columnID) throws
848         UnknownTypeException {
849             return filter.getValueAt (model, node, columnID);
850         }
851
852         /**
853          * Returns true if value displayed in column <code>columnID</code>
854          * and row <code>node</code> is read only. Column ID is defined in by
855          * {@link ColumnModel#getID}, and rows are defined by values returned from
856          * {@TreeModel#getChildren}.
857          *
858          * @param node a object returned from {@TreeModel#getChildren} for this row
859          * @param columnID a id of column defined by {@link ColumnModel#getID}
860          * @throws UnknownTypeException if there is no TableModel defined for given
861          * parameter type
862          *
863          * @return true if variable on given position is read only
864          */

865         public boolean isReadOnly (Object JavaDoc node, String JavaDoc columnID) throws
866         UnknownTypeException {
867             return filter.isReadOnly (model, node, columnID);
868         }
869
870         /**
871          * Changes a value displayed in column <code>columnID</code>
872          * and row <code>node</code>. Column ID is defined in by
873          * {@link ColumnModel#getID}, and rows are defined by values returned from
874          * {@TreeModel#getChildren}.
875          *
876          * @param node a object returned from {@TreeModel#getChildren} for this row
877          * @param columnID a id of column defined by {@link ColumnModel#getID}
878          * @param value a new value of variable on given position
879          * @throws UnknownTypeException if there is no TableModel defined for given
880          * parameter type
881          */

882         public void setValueAt (Object JavaDoc node, String JavaDoc columnID, Object JavaDoc value)
883         throws UnknownTypeException {
884             filter.setValueAt (model, node, columnID, value);
885         }
886
887         /**
888          * Registers given listener.
889          *
890          * @param l the listener to add
891          */

892         public void addModelListener (ModelListener l) {
893             synchronized (modelListeners) {
894                 if (modelListeners.size() == 0) {
895                     filter.addModelListener (this);
896                     model.addModelListener (this);
897                 }
898                 modelListeners.add(l);
899             }
900         }
901
902         /**
903          * Unregisters given listener.
904          *
905          * @param l the listener to remove
906          */

907         public void removeModelListener (ModelListener l) {
908             synchronized (modelListeners) {
909                 modelListeners.remove(l);
910                 if (modelListeners.size() == 0) {
911                     filter.removeModelListener (this);
912                     model.removeModelListener (this);
913                 }
914             }
915         }
916
917         public void modelChanged(ModelEvent event) {
918             ModelEvent newEvent = translateEvent(event, this);
919             Collection JavaDoc listeners;
920             synchronized (modelListeners) {
921                 listeners = new ArrayList JavaDoc(modelListeners);
922             }
923             for (Iterator JavaDoc it = listeners.iterator(); it.hasNext(); ) {
924                 ((ModelListener) it.next()).modelChanged(newEvent);
925             }
926         }
927         
928         public String JavaDoc toString () {
929             return super.toString () + "\n" + toString (" ");
930         }
931         
932         public String JavaDoc toString (String JavaDoc n) {
933             if (model instanceof CompoundTableModel)
934                 return n + filter + "\n" +
935                     ((CompoundTableModel) model).toString (n + " ");
936             if (model instanceof DelegatingTableModel)
937                 return n + filter + "\n" +
938                     ((DelegatingTableModel) model).toString (n + " ");
939             return n + filter + "\n" +
940                    n + " " + model;
941         }
942     }
943
944     /**
945      * Creates one {@link org.netbeans.spi.viewmodel.TreeModel}
946      * from given list of TreeModels. DelegatingTreeModel asks all underlaying
947      * models for each concrete parameter, and returns first returned value.
948      *
949      * @author Jan Jancura
950      */

951     final static class DelegatingTreeModel implements TreeModel {
952
953         private TreeModel[] models;
954         private HashMap JavaDoc classNameToModel = new HashMap JavaDoc ();
955
956
957         /**
958          * Creates new instance of DelegatingTreeModel for given list of
959          * TableModels.
960          *
961          * @param models a list of TableModels
962          */

963         DelegatingTreeModel (List JavaDoc models) {
964             this (convert (models));
965         }
966
967         private static TreeModel[] convert (List JavaDoc l) {
968             TreeModel[] models = new TreeModel [l.size ()];
969             return (TreeModel[]) l.toArray (models);
970         }
971
972         /**
973          * Creates new instance of DelegatingTreeModel for given array of
974          * TableModels.
975          *
976          * @param models a array of TreeModel
977          */

978         DelegatingTreeModel (TreeModel[] models) {
979             this.models = models;
980         }
981         
982         /**
983          * Returns the root node of the tree or null, if the tree is empty.
984          *
985          * @return the root node of the tree or null
986          */

987         public Object JavaDoc getRoot () {
988             return models [0].getRoot ();
989         }
990
991         /**
992          * Returns children for given parent on given indexes.
993          *
994          * @param parent a parent of returned nodes
995          * @param from a start index
996          * @param to a end index
997          *
998          * @throws UnknownTypeException if this TreeModel implementation is not
999          * able to resolve children for given node type
1000         *
1001         * @return children for given parent on given indexes
1002         */

1003        public Object JavaDoc[] getChildren (Object JavaDoc node, int from, int to)
1004        throws UnknownTypeException {
1005            TreeModel model = (TreeModel) classNameToModel.get (
1006                node.getClass ().getName ()
1007            );
1008            if (model != null)
1009                try {
1010                    return model.getChildren (node, from, to);
1011                } catch (UnknownTypeException e) {
1012                }
1013            int i, k = models.length;
1014            for (i = 0; i < k; i++) {
1015                try {
1016                    Object JavaDoc[] v = models [i].getChildren (node, from, to);
1017                    classNameToModel.put (node.getClass ().getName (), models [i]);
1018                    return v;
1019                } catch (UnknownTypeException e) {
1020                }
1021            }
1022            throw new UnknownTypeException (node);
1023        }
1024
1025        /**
1026         * Returns number of children for given node.
1027         *
1028         * @param node the parent node
1029         * @throws UnknownTypeException if this TreeModel implementation is not
1030         * able to resolve children for given node type
1031         *
1032         * @return true if node is leaf
1033         * @since 1.1
1034         */

1035        public int getChildrenCount (Object JavaDoc node)
1036        throws UnknownTypeException {
1037            TreeModel model = (TreeModel) classNameToModel.get (
1038                node.getClass ().getName ()
1039            );
1040            if (model != null)
1041                try {
1042                    return model.getChildrenCount (node);
1043                } catch (UnknownTypeException e) {
1044                }
1045            int i, k = models.length;
1046            for (i = 0; i < k; i++) {
1047                try {
1048                    int result = models [i].getChildrenCount (node);
1049                    classNameToModel.put (node.getClass ().getName (), models [i]);
1050                    return result;
1051                } catch (UnknownTypeException e) {
1052                }
1053            }
1054            throw new UnknownTypeException (node);
1055        }
1056
1057        /**
1058         * Returns true if node is leaf.
1059         *
1060         * @throws UnknownTypeException if this TreeModel implementation is not
1061         * able to resolve dchildren for given node type
1062         * @return true if node is leaf
1063         */

1064        public boolean isLeaf (Object JavaDoc node) throws UnknownTypeException {
1065            TreeModel model = (TreeModel) classNameToModel.get (
1066                node.getClass ().getName ()
1067            );
1068            if (model != null)
1069                try {
1070                    return model.isLeaf (node);
1071                } catch (UnknownTypeException e) {
1072                }
1073            int i, k = models.length;
1074            for (i = 0; i < k; i++) {
1075                try {
1076                    boolean result = models [i].isLeaf (node);
1077                    classNameToModel.put (node.getClass ().getName (), models [i]);
1078                    return result;
1079                } catch (UnknownTypeException e) {
1080                }
1081            }
1082            throw new UnknownTypeException (node);
1083        }
1084
1085        /**
1086         * Registers given listener.
1087         *
1088         * @param l the listener to add
1089         */

1090        public void addModelListener (ModelListener l) {
1091            int i, k = models.length;
1092            for (i = 0; i < k; i++)
1093                models [i].addModelListener (l);
1094        }
1095
1096        /**
1097         * Unregisters given listener.
1098         *
1099         * @param l the listener to remove
1100         */

1101        public void removeModelListener (ModelListener l) {
1102            int i, k = models.length;
1103            for (i = 0; i < k; i++)
1104                models [i].removeModelListener (l);
1105        }
1106
1107        public String JavaDoc toString () {
1108            return super.toString () + "\n" + toString (" ");
1109        }
1110        
1111        public String JavaDoc toString (String JavaDoc n) {
1112            int i, k = models.length - 1;
1113            if (k == -1) return "";
1114            StringBuffer JavaDoc sb = new StringBuffer JavaDoc ();
1115            for (i = 0; i < k; i++) {
1116                sb.append (n);
1117                sb.append (models [i]);
1118                sb.append ('\n');
1119            }
1120            sb.append (n);
1121            sb.append (models [i]);
1122            return new String JavaDoc (sb);
1123        }
1124    }
1125    
1126    /**
1127     * Creates {@link org.netbeans.spi.viewmodel.NodeActionsProvider}
1128     * for given NodeActionsProvider and
1129     * {@link org.netbeans.spi.viewmodel.NodeActionsProviderFilter}.
1130     *
1131     * @author Jan Jancura
1132     */

1133    final static class CompoundNodeActionsProvider
1134    implements NodeActionsProvider {
1135
1136
1137        private NodeActionsProvider model;
1138        private NodeActionsProviderFilter filter;
1139
1140
1141        /**
1142         * Creates {@link org.netbeans.spi.viewmodel.NodeActionsProvider}
1143         * for given NodeActionsProvider and
1144         * {@link org.netbeans.spi.viewmodel.NodeActionsProviderFilter}.
1145         */

1146        CompoundNodeActionsProvider (
1147            NodeActionsProvider model,
1148            NodeActionsProviderFilter filter
1149        ) {
1150            this.model = model;
1151            this.filter = filter;
1152        }
1153    
1154        /**
1155         * Performs default action for given node.
1156         *
1157         * @throws UnknownTypeException if this NodeActionsProvider
1158         * implementation is not able to resolve actions
1159         * for given node type
1160         * @return display name for given node
1161         */

1162        public void performDefaultAction (Object JavaDoc node)
1163        throws UnknownTypeException {
1164            filter.performDefaultAction (model, node);
1165        }
1166
1167        /**
1168         * Returns set of actions for given node.
1169         *
1170         * @throws UnknownTypeException if this NodeActionsProvider implementation
1171         * is not able to resolve actions for given node type
1172         * @return display name for given node
1173         */

1174        public Action JavaDoc[] getActions (Object JavaDoc node)
1175        throws UnknownTypeException {
1176            return filter.getActions (model, node);
1177        }
1178
1179        public String JavaDoc toString () {
1180            return super.toString () + "\n" + toString (" ");
1181        }
1182        
1183        public String JavaDoc toString (String JavaDoc n) {
1184            if (model instanceof CompoundNodeActionsProvider)
1185                return n + filter + "\n" +
1186                    ((CompoundNodeActionsProvider) model).toString (n + " ");
1187            if (model instanceof DelegatingNodeActionsProvider)
1188                return n + filter + "\n" +
1189                    ((DelegatingNodeActionsProvider) model).toString (n + " ");
1190            return n + filter + "\n" +
1191                   n + " " + model;
1192        }
1193    }
1194
1195    /**
1196     * Creates one {@link org.netbeans.spi.viewmodel.TableModel}
1197     * from given list of TableModels. DelegatingTableModel asks all underlaying
1198     * models for each concrete parameter, and returns first returned value.
1199     *
1200     * @author Jan Jancura
1201     */

1202    final static class DelegatingTableModel implements TableModel {
1203
1204        private TableModel[] models;
1205        private HashMap JavaDoc classNameToModel = new HashMap JavaDoc ();
1206
1207
1208        /**
1209         * Creates new instance of DelegatingTableModel for given list of
1210         * TableModels.
1211         *
1212         * @param models a list of TableModels
1213         */

1214        DelegatingTableModel (List JavaDoc models) {
1215            this (convert (models));
1216        }
1217
1218        private static TableModel[] convert (List JavaDoc l) {
1219            TableModel[] models = new TableModel [l.size ()];
1220            return (TableModel[]) l.toArray (models);
1221        }
1222
1223        /**
1224         * Creates new instance of DelegatingTableModel for given array of
1225         * TableModels.
1226         *
1227         * @param models a array of TableModels
1228         */

1229        DelegatingTableModel (TableModel[] models) {
1230            this.models = models;
1231        }
1232
1233        /**
1234         * Returns value to be displayed in column <code>columnID</code>
1235         * and row <code>node</code>. Column ID is defined in by
1236         * {@link ColumnModel#getID}, and rows are defined by values returned from
1237         * {@TreeModel#getChildren}.
1238         *
1239         * @param node a object returned from {@TreeModel#getChildren} for this row
1240         * @param columnID a id of column defined by {@link ColumnModel#getID}
1241         * @throws UnknownTypeException if there is no TableModel defined for given
1242         * parameter type
1243         *
1244         * @return value of variable representing given position in tree table.
1245         */

1246        public Object JavaDoc getValueAt (Object JavaDoc node, String JavaDoc columnID)
1247        throws UnknownTypeException {
1248            TableModel model = (TableModel) classNameToModel.get (
1249                node.getClass ().getName ()
1250            );
1251            if (model != null)
1252                try {
1253                    return model.getValueAt (node, columnID);
1254                } catch (UnknownTypeException e) {
1255                }
1256            int i, k = models.length;
1257            for (i = 0; i < k; i++) {
1258                try {
1259                    Object JavaDoc v = models [i].getValueAt (node, columnID);
1260                    classNameToModel.put (node.getClass ().getName (), models [i]);
1261                    return v;
1262                } catch (UnknownTypeException e) {
1263                }
1264            }
1265            throw new UnknownTypeException (node);
1266        }
1267
1268        /**
1269         * Returns true if value displayed in column <code>columnID</code>
1270         * and row <code>node</code> is read only. Column ID is defined in by
1271         * {@link ColumnModel#getID}, and rows are defined by values returned from
1272         * {@TreeModel#getChildren}.
1273         *
1274         * @param node a object returned from {@TreeModel#getChildren} for this row
1275         * @param columnID a id of column defined by {@link ColumnModel#getID}
1276         * @throws UnknownTypeException if there is no TableModel defined for given
1277         * parameter type
1278         *
1279         * @return true if variable on given position is read only
1280         */

1281        public boolean isReadOnly (Object JavaDoc node, String JavaDoc columnID) throws
1282        UnknownTypeException {
1283            TableModel model = (TableModel) classNameToModel.get (
1284                node.getClass ().getName ()
1285            );
1286            if (model != null)
1287                try {
1288                    return model.isReadOnly (node, columnID);
1289                } catch (UnknownTypeException e) {
1290                }
1291            int i, k = models.length;
1292            for (i = 0; i < k; i++) {
1293                try {
1294                    boolean ro = models [i].isReadOnly (node, columnID);
1295                    classNameToModel.put (node.getClass ().getName (), models [i]);
1296                    return ro;
1297                } catch (UnknownTypeException e) {
1298                }
1299            }
1300            throw new UnknownTypeException (node);
1301        }
1302
1303        /**
1304         * Changes a value displayed in column <code>columnID</code>
1305         * and row <code>node</code>. Column ID is defined in by
1306         * {@link ColumnModel#getID}, and rows are defined by values returned from
1307         * {@TreeModel#getChildren}.
1308         *
1309         * @param node a object returned from {@TreeModel#getChildren} for this row
1310         * @param columnID a id of column defined by {@link ColumnModel#getID}
1311         * @param value a new value of variable on given position
1312         * @throws UnknownTypeException if there is no TableModel defined for given
1313         * parameter type
1314         */

1315        public void setValueAt (Object JavaDoc node, String JavaDoc columnID, Object JavaDoc value)
1316        throws UnknownTypeException {
1317            TableModel model = (TableModel) classNameToModel.get (
1318                node.getClass ().getName ()
1319            );
1320            if (model != null)
1321                try {
1322                    model.setValueAt (node, columnID, value);
1323                    return;
1324                } catch (UnknownTypeException e) {
1325                }
1326            int i, k = models.length;
1327            for (i = 0; i < k; i++) {
1328                try {
1329                    models [i].setValueAt (node, columnID, value);
1330                    classNameToModel.put (node.getClass ().getName (), models [i]);
1331                    return;
1332                } catch (UnknownTypeException e) {
1333                }
1334            }
1335            throw new UnknownTypeException (node);
1336        }
1337
1338        /**
1339         * Registers given listener.
1340         *
1341         * @param l the listener to add
1342         */

1343        public void addModelListener (ModelListener l) {
1344            int i, k = models.length;
1345            for (i = 0; i < k; i++)
1346                models [i].addModelListener (l);
1347        }
1348
1349        /**
1350         * Unregisters given listener.
1351         *
1352         * @param l the listener to remove
1353         */

1354        public void removeModelListener (ModelListener l) {
1355            int i, k = models.length;
1356            for (i = 0; i < k; i++)
1357                models [i].removeModelListener (l);
1358        }
1359
1360        public String JavaDoc toString () {
1361            return super.toString () + "\n" + toString (" ");
1362        }
1363        
1364        public String JavaDoc toString (String JavaDoc n) {
1365            int i, k = models.length - 1;
1366            if (k == -1) return "";
1367            StringBuffer JavaDoc sb = new StringBuffer JavaDoc ();
1368            for (i = 0; i < k; i++) {
1369                sb.append (n);
1370                sb.append (models [i]);
1371                sb.append ('\n');
1372            }
1373            sb.append (n);
1374            sb.append (models [i]);
1375            return new String JavaDoc (sb);
1376        }
1377    }
1378
1379    /**
1380     * Creates one {@link org.netbeans.spi.viewmodel.TableModel}
1381     * from given list of TableModels. DelegatingTableModel asks all underlaying
1382     * models for each concrete parameter, and returns first returned value.
1383     *
1384     * @author Jan Jancura
1385     */

1386    final static class DelegatingTreeExpansionModel
1387    implements TreeExpansionModel {
1388
1389        private TreeExpansionModel[] models;
1390        private HashMap JavaDoc classNameToModel = new HashMap JavaDoc ();
1391
1392
1393        /**
1394         * Creates new instance of DelegatingTableModel for given list of
1395         * TableModels.
1396         *
1397         * @param models a list of TableModels
1398         */

1399        DelegatingTreeExpansionModel (List JavaDoc models) {
1400            this (convert (models));
1401        }
1402
1403        private static TreeExpansionModel[] convert (List JavaDoc l) {
1404            TreeExpansionModel[] models = new TreeExpansionModel [l.size()];
1405            return (TreeExpansionModel[]) l.toArray (models);
1406        }
1407
1408        /**
1409         * Creates new instance of DelegatingTableModel for given array of
1410         * TableModels.
1411         *
1412         * @param models a array of TableModels
1413         */

1414        private DelegatingTreeExpansionModel (TreeExpansionModel[] models) {
1415            this.models = models;
1416        }
1417
1418        /**
1419         * Defines default state (collapsed, expanded) of given node.
1420         *
1421         * @param node a node
1422         * @return default state (collapsed, expanded) of given node
1423         */

1424        public boolean isExpanded (Object JavaDoc node)
1425        throws UnknownTypeException {
1426            TreeExpansionModel model = (TreeExpansionModel)
1427                classNameToModel.get (
1428                    node.getClass ().getName ()
1429                );
1430            if (model != null)
1431                try {
1432                    return model.isExpanded (node);
1433                } catch (UnknownTypeException e) {
1434                }
1435            int i, k = models.length;
1436            for (i = 0; i < k; i++) {
1437                try {
1438                    boolean result = models [i].isExpanded (node);
1439                    classNameToModel.put (node.getClass ().getName (), models [i]);
1440                    return result;
1441                } catch (UnknownTypeException e) {
1442                }
1443            }
1444            throw new UnknownTypeException (node);
1445        }
1446
1447
1448        /**
1449         * Called when given node is expanded.
1450         *
1451         * @param node a expanded node
1452         */

1453        public void nodeExpanded (Object JavaDoc node) {
1454            int i, k = models.length;
1455            for (i = 0; i < k; i++) {
1456                models [i].nodeExpanded (node);
1457            }
1458        }
1459
1460        /**
1461         * Called when given node is collapsed.
1462         *
1463         * @param node a collapsed node
1464         */

1465        public void nodeCollapsed (Object JavaDoc node) {
1466            int i, k = models.length;
1467            for (i = 0; i < k; i++) {
1468                models [i].nodeCollapsed (node);
1469            }
1470        }
1471
1472        public String JavaDoc toString () {
1473            return super.toString () + "\n" + toString (" ");
1474        }
1475        
1476        public String JavaDoc toString (String JavaDoc n) {
1477            int i, k = models.length - 1;
1478            if (k == -1) return "";
1479            StringBuffer JavaDoc sb = new StringBuffer JavaDoc ();
1480            for (i = 0; i < k; i++) {
1481                sb.append (n);
1482                sb.append (models [i]);
1483                sb.append ('\n');
1484            }
1485            sb.append (n);
1486            sb.append (models [i]);
1487            return new String JavaDoc (sb);
1488        }
1489    }
1490    
1491    private static class DefaultTreeExpansionModel implements TreeExpansionModel {
1492        
1493        private Set JavaDoc expandedNodes = new WeakSet();
1494        private Set JavaDoc collapsedNodes = new WeakSet();
1495        
1496        /**
1497         * Defines default state (collapsed, expanded) of given node.
1498         *
1499         * @param node a node
1500         * @return default state (collapsed, expanded) of given node
1501         */

1502        public boolean isExpanded (Object JavaDoc node)
1503        throws UnknownTypeException {
1504            synchronized (this) {
1505                if (expandedNodes.contains(node)) {
1506                    return true;
1507                }
1508                if (collapsedNodes.contains(node)) {
1509                    return false;
1510                }
1511            }
1512            // Default behavior follows:
1513
return false;
1514        }
1515
1516        /**
1517         * Called when given node is expanded.
1518         *
1519         * @param node a expanded node
1520         */

1521        public void nodeExpanded (Object JavaDoc node) {
1522            synchronized (this) {
1523                expandedNodes.add(node);
1524                collapsedNodes.remove(node);
1525            }
1526        }
1527
1528        /**
1529         * Called when given node is collapsed.
1530         *
1531         * @param node a collapsed node
1532         */

1533        public void nodeCollapsed (Object JavaDoc node) {
1534            synchronized (this) {
1535                collapsedNodes.add(node);
1536                expandedNodes.remove(node);
1537            }
1538        }
1539        
1540    }
1541
1542    /**
1543     * Creates one {@link org.netbeans.spi.viewmodel.NodeModel}
1544     * from given list of NodeModels. DelegatingNodeModel asks all underlaying
1545     * models for each concrete parameter, and returns first returned value.
1546     *
1547     * @author Jan Jancura
1548     */

1549    static final class DelegatingNodeModel implements NodeModel {
1550
1551        private NodeModel[] models;
1552        private HashMap JavaDoc classNameToModel = new HashMap JavaDoc ();
1553
1554
1555        /**
1556         * Creates new instance of DelegatingNodeModel for given list of
1557         * NodeModels.
1558         *
1559         * @param models a list of NodeModels
1560         */

1561        DelegatingNodeModel (
1562            List JavaDoc models
1563        ) {
1564            this (convert (models));
1565        }
1566
1567        private static NodeModel[] convert (List JavaDoc l) {
1568            NodeModel[] models = new NodeModel [l.size ()];
1569            return (NodeModel[]) l.toArray (models);
1570        }
1571
1572        /**
1573         * Creates new instance of DelegatingNodeModel for given array of
1574         * NodeModels.
1575         *
1576         * @param models a array of NodeModels
1577         */

1578        DelegatingNodeModel (
1579            NodeModel[] models
1580        ) {
1581            this.models = models;
1582
1583        }
1584        
1585        NodeModel[] getModels() {
1586            return models;
1587        }
1588
1589        /**
1590         * Returns display name for given node.
1591         *
1592         * @throws UnknownTypeException if this NodeModel implementation is not
1593         * able to resolve display name for given node type
1594         * @return display name for given node
1595         */

1596        public String JavaDoc getDisplayName (Object JavaDoc node)
1597        throws UnknownTypeException {
1598            NodeModel model = (NodeModel) classNameToModel.get (
1599                node.getClass ().getName ()
1600            );
1601            if (model != null)
1602                try {
1603                    return model.getDisplayName (node);
1604                } catch (UnknownTypeException e) {
1605                }
1606            int i, k = models.length;
1607            for (i = 0; i < k; i++) {
1608                try {
1609                    String JavaDoc dn = models [i].getDisplayName (node);
1610                    classNameToModel.put (node.getClass ().getName (), models [i]);
1611                    return dn;
1612                } catch (UnknownTypeException e) {
1613                }
1614            }
1615            throw new UnknownTypeException (node);
1616        }
1617
1618        /**
1619         * Returns tooltip for given node.
1620         *
1621         * @throws UnknownTypeException if this NodeModel implementation is not
1622         * able to resolve tooltip for given node type
1623         * @return tooltip for given node
1624         */

1625        public String JavaDoc getShortDescription (Object JavaDoc node)
1626        throws UnknownTypeException {
1627            NodeModel model = (NodeModel) classNameToModel.get (
1628                node.getClass ().getName ()
1629            );
1630            if (model != null)
1631                try {
1632                    return model.getShortDescription (node);
1633                } catch (UnknownTypeException e) {
1634                }
1635            int i, k = models.length;
1636            for (i = 0; i < k; i++) {
1637                try {
1638                    String JavaDoc dn = models [i].getShortDescription (node);
1639                    classNameToModel.put (node.getClass ().getName (), models [i]);
1640                    return dn;
1641                } catch (UnknownTypeException e) {
1642                }
1643            }
1644            throw new UnknownTypeException (node);
1645        }
1646
1647        /**
1648         * Returns icon for given node.
1649         *
1650         * @throws UnknownTypeException if this NodeModel implementation is not
1651         * able to resolve icon for given node type
1652         * @return icon for given node
1653         */

1654        public String JavaDoc getIconBase (Object JavaDoc node)
1655        throws UnknownTypeException {
1656            NodeModel model = (NodeModel) classNameToModel.get (
1657                node.getClass ().getName ()
1658            );
1659            if (model != null)
1660                try {
1661                    return model.getIconBase (node);
1662                } catch (UnknownTypeException e) {
1663                }
1664            int i, k = models.length;
1665            for (i = 0; i < k; i++) {
1666                try {
1667                    String JavaDoc dn = models [i].getIconBase (node);
1668                    classNameToModel.put (node.getClass ().getName (), models [i]);
1669                    return dn;
1670                } catch (UnknownTypeException e) {
1671                }
1672            }
1673            throw new UnknownTypeException (node);
1674        }
1675
1676        /**
1677         * Registers given listener.
1678         *
1679         * @param l the listener to add
1680         */

1681        public void addModelListener (ModelListener l) {
1682            int i, k = models.length;
1683            for (i = 0; i < k; i++)
1684                models [i].addModelListener (l);
1685        }
1686
1687        /**
1688         * Unregisters given listener.
1689         *
1690         * @param l the listener to remove
1691         */

1692        public void removeModelListener (ModelListener l) {
1693            int i, k = models.length;
1694            for (i = 0; i < k; i++)
1695                models [i].removeModelListener (l);
1696        }
1697
1698        public String JavaDoc toString () {
1699            return toString (" ");
1700        }
1701        
1702        public String JavaDoc toString (String JavaDoc n) {
1703            int i, k = models.length - 1;
1704            if (k == -1) return "";
1705            StringBuffer JavaDoc sb = new StringBuffer JavaDoc ();
1706            for (i = 0; i < k; i++) {
1707                sb.append (n);
1708                sb.append (models [i]);
1709                sb.append ('\n');
1710            }
1711            sb.append (n);
1712            sb.append (models [i]);
1713            return new String JavaDoc (sb);
1714        }
1715    }
1716
1717    /**
1718     * Empty impleemntation of {@link org.netbeans.spi.viewmodel.TreeModel}.
1719     *
1720     * @author Jan Jancura
1721     */

1722    private static final class EmptyTreeModel implements TreeModel {
1723
1724        /**
1725         * Returns {@link org.netbeans.spi.viewmodel.TreeModel#ROOT}.
1726         *
1727         * @return {@link org.netbeans.spi.viewmodel.TreeModel#ROOT}
1728         */

1729        public Object JavaDoc getRoot () {
1730            return ROOT;
1731        }
1732
1733        /**
1734         * Returns empty array.
1735         *
1736         * @return empty array
1737         */

1738        public Object JavaDoc[] getChildren (Object JavaDoc parent, int from, int to) {
1739            return new Object JavaDoc [0];
1740        }
1741    
1742        /**
1743         * Returns number of children for given node.
1744         *
1745         * @param node the parent node
1746         * @throws UnknownTypeException if this TreeModel implementation is not
1747         * able to resolve children for given node type
1748         *
1749         * @return true if node is leaf
1750         */

1751        public int getChildrenCount (Object JavaDoc node) {
1752            return 0;
1753        }
1754
1755        /**
1756         * Returns false.
1757         *
1758         * @return false
1759         */

1760        public boolean isLeaf (Object JavaDoc node) {
1761            return false;
1762        }
1763
1764        /**
1765         * Do nothing.
1766         *
1767         * @param l the listener to be added
1768         */

1769        public void addModelListener (ModelListener l) {
1770        }
1771
1772        /**
1773         * Do nothing.
1774         *
1775         * @param l the listener to be removed
1776         */

1777        public void removeModelListener (ModelListener l) {
1778        }
1779    }
1780
1781    /**
1782     * Empty impleemntation of {@link org.netbeans.spi.viewmodel.NodeModel}.
1783     *
1784     * @author Jan Jancura
1785     */

1786    private static final class EmptyNodeModel implements NodeModel {
1787
1788        /**
1789         * Returns display name for given node.
1790         *
1791         * @throws UnknownTypeException if this NodeModel implementation is not
1792         * able to resolve display name for given node type
1793         * @return display name for given node
1794         */

1795        public String JavaDoc getDisplayName (Object JavaDoc node)
1796        throws UnknownTypeException {
1797            throw new UnknownTypeException (node);
1798        }
1799
1800        /**
1801         * Returns icon for given node.
1802         *
1803         * @throws UnknownTypeException if this NodeModel implementation is not
1804         * able to resolve icon for given node type
1805         * @return icon for given node
1806         */

1807        public String JavaDoc getIconBase (Object JavaDoc node)
1808        throws UnknownTypeException {
1809            throw new UnknownTypeException (node);
1810        }
1811
1812        /**
1813         * Returns tooltip for given node.
1814         *
1815         * @throws UnknownTypeException if this NodeModel implementation is not
1816         * able to resolve tooltip for given node type
1817         * @return tooltip for given node
1818         */

1819        public String JavaDoc getShortDescription (Object JavaDoc node)
1820        throws UnknownTypeException {
1821            throw new UnknownTypeException (node);
1822        }
1823
1824        /**
1825         * Do nothing.
1826         *
1827         * @param l the listener to be added
1828         */

1829        public void addModelListener (ModelListener l) {
1830        }
1831
1832        /**
1833         * Do nothing.
1834         *
1835         * @param l the listener to be removed
1836         */

1837        public void removeModelListener (ModelListener l) {
1838        }
1839    }
1840
1841    /**
1842     * Empty impleemntation of {@link org.netbeans.spi.viewmodel.TableModel}.
1843     *
1844     * @author Jan Jancura
1845     */

1846    private static final class EmptyTableModel implements TableModel {
1847 
1848        /**
1849         * Returns value to be displayed in column <code>columnID</code>
1850         * and row identified by <code>node</code>. Column ID is defined in by
1851         * {@link ColumnModel#getID}, and rows are defined by values returned from
1852         * {@link org.netbeans.spi.viewmodel.TreeModel#getChildren}.
1853         *
1854         * @param node a object returned from
1855         * {@link org.netbeans.spi.viewmodel.TreeModel#getChildren} for this row
1856         * @param columnID a id of column defined by {@link ColumnModel#getID}
1857         * @throws UnknownTypeException if there is no TableModel defined for given
1858         * parameter type
1859         *
1860         * @return value of variable representing given position in tree table.
1861         */

1862        public Object JavaDoc getValueAt (Object JavaDoc node, String JavaDoc columnID) throws
1863        UnknownTypeException {
1864            throw new UnknownTypeException (node);
1865        }
1866
1867        /**
1868         * Returns true if value displayed in column <code>columnID</code>
1869         * and row <code>node</code> is read only. Column ID is defined in by
1870         * {@link ColumnModel#getID}, and rows are defined by values returned from
1871         * {@link TreeModel#getChildren}.
1872         *
1873         * @param node a object returned from {@link TreeModel#getChildren} for this row
1874         * @param columnID a id of column defined by {@link ColumnModel#getID}
1875         * @throws UnknownTypeException if there is no TableModel defined for given
1876         * parameter type
1877         *
1878         * @return true if variable on given position is read only
1879         */

1880        public boolean isReadOnly (Object JavaDoc node, String JavaDoc columnID) throws
1881        UnknownTypeException {
1882            throw new UnknownTypeException (node);
1883        }
1884
1885        /**
1886         * Changes a value displayed in column <code>columnID</code>
1887         * and row <code>node</code>. Column ID is defined in by
1888         * {@link ColumnModel#getID}, and rows are defined by values returned from
1889         * {@link TreeModel#getChildren}.
1890         *
1891         * @param node a object returned from {@link TreeModel#getChildren} for this row
1892         * @param columnID a id of column defined by {@link ColumnModel#getID}
1893         * @param value a new value of variable on given position
1894         * @throws UnknownTypeException if there is no TableModel defined for given
1895         * parameter type
1896         */

1897        public void setValueAt (Object JavaDoc node, String JavaDoc columnID, Object JavaDoc value)
1898        throws UnknownTypeException {
1899            throw new UnknownTypeException (node);
1900        }
1901        
1902        /**
1903         * Do nothing.
1904         *
1905         * @param l the listener to be added
1906         */

1907        public void addModelListener (ModelListener l) {
1908        }
1909
1910        /**
1911         * Do nothing.
1912         *
1913         * @param l the listener to be removed
1914         */

1915        public void removeModelListener (ModelListener l) {
1916        }
1917    }
1918
1919    /**
1920     * Empty impleemntation of {@link org.netbeans.spi.viewmodel.TableModel}.
1921     *
1922     * @author Jan Jancura
1923     */

1924    private static final class EmptyNodeActionsProvider implements
1925    NodeActionsProvider {
1926    
1927        /**
1928         * Performs default action for given node.
1929         *
1930         * @throws UnknownTypeException if this NodeActionsProvider implementation
1931         * is not able to resolve actions for given node type
1932         * @return display name for given node
1933         */

1934        public void performDefaultAction (Object JavaDoc node)
1935        throws UnknownTypeException {
1936            throw new UnknownTypeException (node);
1937        }
1938
1939        /**
1940         * Returns set of actions for given node.
1941         *
1942         * @throws UnknownTypeException if this NodeActionsProvider implementation
1943         * is not able to resolve actions for given node type
1944         * @return display name for given node
1945         */

1946        public Action JavaDoc[] getActions (Object JavaDoc node)
1947        throws UnknownTypeException {
1948            throw new UnknownTypeException (node);
1949        }
1950    }
1951    
1952    /**
1953     * Creates one {@link org.netbeans.spi.viewmodel.NodeActionsProvider}
1954     * from given list of NodeActionsProviders. DelegatingNodeActionsProvider asks all
1955     * underlaying models for each concrete parameter, and returns first
1956     * returned value.
1957     *
1958     * @author Jan Jancura
1959     */

1960    static final class DelegatingNodeActionsProvider implements NodeActionsProvider {
1961
1962        private NodeActionsProvider[] models;
1963        private HashMap JavaDoc classNameToModel = new HashMap JavaDoc ();
1964
1965
1966        /**
1967         * Creates new instance of DelegatingNodeActionsProvider for given list of
1968         * NodeActionsProvider.
1969         *
1970         * @param models a list of NodeActionsProvider
1971         */

1972        public DelegatingNodeActionsProvider (
1973            List JavaDoc models
1974        ) {
1975            this (convert (models));
1976        }
1977
1978        private static NodeActionsProvider[] convert (List JavaDoc l) {
1979            NodeActionsProvider[] models = new NodeActionsProvider [l.size ()];
1980            return (NodeActionsProvider[]) l.toArray (models);
1981        }
1982
1983        /**
1984         * Creates new instance of DelegatingNodeActionsProvider for given array of
1985         * NodeActionsProvider.
1986         *
1987         * @param models a array of NodeActionsProvider
1988         */

1989        public DelegatingNodeActionsProvider (NodeActionsProvider[] models) {
1990            this.models = models;
1991        }
1992
1993        /**
1994         * Returns set of actions for given node.
1995         *
1996         * @throws UnknownTypeException if this NodeActionsProvider implementation
1997         * is not able to resolve actions for given node type
1998         * @return display name for given node
1999         */

2000        public Action JavaDoc[] getActions (Object JavaDoc node)
2001        throws UnknownTypeException {
2002            NodeActionsProvider model = (NodeActionsProvider) classNameToModel.get (
2003                node.getClass ().getName ()
2004            );
2005            if (model != null)
2006                try {
2007                    return model.getActions (node);
2008                } catch (UnknownTypeException e) {
2009                }
2010            int i, k = models.length;
2011            for (i = 0; i < k; i++) {
2012                try {
2013                    Action JavaDoc[] dn = models [i].getActions (node);
2014                    classNameToModel.put (node.getClass ().getName (), models [i]);
2015                    return dn;
2016                } catch (UnknownTypeException e) {
2017                }
2018            }
2019            throw new UnknownTypeException (node);
2020        }
2021
2022        /**
2023         * Performs default action for given node.
2024         *
2025         * @throws UnknownTypeException if this NodeActionsProvider implementation
2026         * is not able to resolve actions for given node type
2027         * @return display name for given node
2028         */

2029        public void performDefaultAction (Object JavaDoc node) throws UnknownTypeException {
2030            NodeActionsProvider model = (NodeActionsProvider) classNameToModel.get (
2031                node.getClass ().getName ()
2032            );
2033            if (model != null)
2034                try {
2035                    model.performDefaultAction (node);
2036                    return;
2037                } catch (UnknownTypeException e) {
2038                }
2039            int i, k = models.length;
2040            for (i = 0; i < k; i++) {
2041                try {
2042                    models [i].performDefaultAction (node);
2043                    classNameToModel.put (node.getClass ().getName (), models [i]);
2044                    return;
2045                } catch (UnknownTypeException e) {
2046                }
2047            }
2048            throw new UnknownTypeException (node);
2049        }
2050
2051        public String JavaDoc toString () {
2052            return super.toString () + "\n" + toString (" ");
2053        }
2054        
2055        public String JavaDoc toString (String JavaDoc n) {
2056            int i, k = models.length - 1;
2057            if (k == -1) return "";
2058            StringBuffer JavaDoc sb = new StringBuffer JavaDoc ();
2059            for (i = 0; i < k; i++) {
2060                sb.append (n);
2061                sb.append (models [i]);
2062                sb.append ('\n');
2063            }
2064            sb.append (n);
2065            sb.append (models [i]);
2066            return new String JavaDoc (sb);
2067        }
2068    }
2069    
2070    /**
2071     * Implements set of tree view features.
2072     */

2073    public static final class TreeFeatures {
2074        
2075        private JComponent JavaDoc view;
2076        
2077        private TreeFeatures (JComponent JavaDoc view) {
2078            this.view = view;
2079        }
2080        
2081        /**
2082         * Returns <code>true</code> if given node is expanded.
2083         *
2084         * @param node a node to be checked
2085         * @return <code>true</code> if given node is expanded
2086         */

2087        public boolean isExpanded (
2088            Object JavaDoc node
2089        ) {
2090            return ((TreeTable) view).isExpanded (node);
2091        }
2092
2093        /**
2094         * Expands given list of nodes.
2095         *
2096         * @param node a list of nodes to be expanded
2097         */

2098        public void expandNode (
2099            Object JavaDoc node
2100        ) {
2101            ((TreeTable) view).expandNode (node);
2102        }
2103
2104        /**
2105         * Collapses given node.
2106         *
2107         * @param node a node to be expanded
2108         */

2109        public void collapseNode (
2110            Object JavaDoc node
2111        ) {
2112            ((TreeTable) view).collapseNode (node);
2113        }
2114    }
2115
2116    /**
2117     * This model encapsulates all currently supported models.
2118     *
2119     * @see Models#createCompoundModel
2120     * @author Jan Jancura
2121     */

2122    public static final class CompoundModel implements TreeModel,
2123    NodeModel, NodeActionsProvider, TableModel, TreeExpansionModel {
2124
2125        private TreeModel treeModel;
2126        private NodeModel nodeModel;
2127        private NodeActionsProvider nodeActionsProvider;
2128        private ColumnModel[] columnModels;
2129        private TableModel tableModel;
2130        private TreeExpansionModel treeExpansionModel;
2131        
2132        // <RAVE>
2133
// New field, setter/getter for propertiesHelpID, which is used
2134
// for property sheet help
2135
private String JavaDoc propertiesHelpID = null;
2136        // </RAVE>
2137

2138        // init ....................................................................
2139

2140        /**
2141         * Creates a new instance of {@link CompoundModel} for given models.
2142         *
2143         * @param treeModel a tree model to delegate on
2144         * @param nodeModel a node model to delegate on
2145         * @param nodeActionsProvider a node actions provider to delegate on
2146         * @param nodeActionsProvider a columns modeol to delegate on
2147         */

2148        private CompoundModel (
2149            TreeModel treeModel,
2150            TreeExpansionModel treeExpansionModel,
2151            NodeModel nodeModel,
2152            NodeActionsProvider nodeActionsProvider,
2153            List JavaDoc columnModels,
2154            TableModel tableModel,
2155            String JavaDoc propertiesHelpID
2156        ) {
2157            if (treeModel == null) throw new NullPointerException JavaDoc ();
2158            if (treeModel == null) throw new NullPointerException JavaDoc ();
2159            if (nodeModel == null) throw new NullPointerException JavaDoc ();
2160            if (tableModel == null) throw new NullPointerException JavaDoc ();
2161            if (nodeActionsProvider == null) throw new NullPointerException JavaDoc ();
2162
2163            this.treeModel = treeModel;
2164            this.treeExpansionModel = treeExpansionModel;
2165            this.nodeModel = nodeModel;
2166            this.tableModel = tableModel;
2167            this.nodeActionsProvider = nodeActionsProvider;
2168            this.columnModels = (ColumnModel[]) columnModels.toArray (
2169                new ColumnModel [columnModels.size ()]
2170            );
2171            this.propertiesHelpID = propertiesHelpID;
2172        }
2173
2174        // <RAVE>
2175
/**
2176         * Get a help ID for this model.
2177         * @return The help ID defined for the properties sheets,
2178         * or <code>null</code>.
2179         * @since 1.7
2180         */

2181        public String JavaDoc getHelpId() {
2182            return propertiesHelpID;
2183        }
2184        // </RAVE>
2185

2186        // TreeModel ...............................................................
2187

2188        /**
2189         * Returns the root node of the tree or null, if the tree is empty.
2190         *
2191         * @return the root node of the tree or null
2192         */

2193        public Object JavaDoc getRoot () {
2194            return treeModel.getRoot ();
2195        }
2196
2197        /**
2198         * Returns children for given parent on given indexes.
2199         *
2200         * @param parent a parent of returned nodes
2201         * @throws UnknownTypeException if this TreeModel implementation is not
2202         * able to resolve dchildren for given node type
2203         *
2204         * @return children for given parent on given indexes
2205         */

2206        public Object JavaDoc[] getChildren (Object JavaDoc parent, int from, int to)
2207        throws UnknownTypeException {
2208            return treeModel.getChildren (parent, from, to);
2209        }
2210
2211        /**
2212         * Returns number of children for given node.
2213         *
2214         * @param node the parent node
2215         * @throws UnknownTypeException if this TreeModel implementation is not
2216         * able to resolve children for given node type
2217         *
2218         * @return true if node is leaf
2219         */

2220        public int getChildrenCount (Object JavaDoc node) throws UnknownTypeException {
2221            return treeModel.getChildrenCount (node);
2222        }
2223
2224        /**
2225         * Returns true if node is leaf.
2226         *
2227         * @throws UnknownTypeException if this TreeModel implementation is not
2228         * able to resolve dchildren for given node type
2229         * @return true if node is leaf
2230         */

2231        public boolean isLeaf (Object JavaDoc node) throws UnknownTypeException {
2232            return treeModel.isLeaf (node);
2233        }
2234
2235
2236        // NodeModel ...............................................................
2237

2238        /**
2239         * Returns display name for given node.
2240         *
2241         * @throws UnknownTypeException if this NodeModel implementation is not
2242         * able to resolve display name for given node type
2243         * @return display name for given node
2244         */

2245        public String JavaDoc getDisplayName (Object JavaDoc node) throws UnknownTypeException {
2246            if (nodeModel instanceof DelegatingNodeModel) {
2247                NodeModel[] subModels = ((DelegatingNodeModel) nodeModel).getModels();
2248                if (subModels.length == 0) {
2249                    return ""; // Nothing when there are no models
2250
}
2251            }
2252            return nodeModel.getDisplayName (node);
2253        }
2254
2255        /**
2256         * Returns tooltip for given node.
2257         *
2258         * @throws UnknownTypeException if this NodeModel implementation is not
2259         * able to resolve tooltip for given node type
2260         * @return tooltip for given node
2261         */

2262        public String JavaDoc getShortDescription (Object JavaDoc node)
2263        throws UnknownTypeException {
2264            return nodeModel.getShortDescription (node);
2265        }
2266
2267        /**
2268         * Returns icon for given node.
2269         *
2270         * @throws UnknownTypeException if this NodeModel implementation is not
2271         * able to resolve icon for given node type
2272         * @return icon for given node
2273         */

2274        public String JavaDoc getIconBase (Object JavaDoc node)
2275        throws UnknownTypeException {
2276            if (nodeModel instanceof DelegatingNodeModel) {
2277                NodeModel[] subModels = ((DelegatingNodeModel) nodeModel).getModels();
2278                if (subModels.length == 0) {
2279                    return null; // Nothing when there are no models
2280
}
2281            }
2282            return nodeModel.getIconBase (node);
2283        }
2284
2285
2286        // NodeActionsProvider .....................................................
2287

2288        /**
2289         * Performs default action for given node.
2290         *
2291         * @throws UnknownTypeException if this NodeActionsProvider implementation
2292         * is not able to resolve actions for given node type
2293         * @return display name for given node
2294         */

2295        public void performDefaultAction (Object JavaDoc node) throws UnknownTypeException {
2296            nodeActionsProvider.performDefaultAction (node);
2297        }
2298
2299        /**
2300         * Returns set of actions for given node.
2301         *
2302         * @throws UnknownTypeException if this NodeActionsProvider implementation
2303         * is not able to resolve actions for given node type
2304         * @return display name for given node
2305         */

2306        public Action JavaDoc[] getActions (Object JavaDoc node) throws UnknownTypeException {
2307            return nodeActionsProvider.getActions (node);
2308        }
2309
2310
2311        // ColumnsModel ............................................................
2312

2313        /**
2314         * Returns sorted array of
2315         * {@link org.netbeans.spi.viewmodel.ColumnModel}s.
2316         *
2317         * @return sorted array of ColumnModels
2318         */

2319        public ColumnModel[] getColumns () {
2320            return columnModels;
2321        }
2322
2323
2324        // TableModel ..............................................................
2325

2326        public Object JavaDoc getValueAt (Object JavaDoc node, String JavaDoc columnID) throws
2327        UnknownTypeException {
2328            return tableModel.getValueAt (node, columnID);
2329        }
2330
2331        public boolean isReadOnly (Object JavaDoc node, String JavaDoc columnID) throws
2332        UnknownTypeException {
2333            return tableModel.isReadOnly (node, columnID);
2334        }
2335
2336        public void setValueAt (Object JavaDoc node, String JavaDoc columnID, Object JavaDoc value) throws
2337        UnknownTypeException {
2338            tableModel.setValueAt (node, columnID, value);
2339        }
2340
2341
2342        // TreeExpansionModel ......................................................
2343

2344        /**
2345         * Defines default state (collapsed, expanded) of given node.
2346         *
2347         * @param node a node
2348         * @return default state (collapsed, expanded) of given node
2349         */

2350        public boolean isExpanded (Object JavaDoc node) throws UnknownTypeException {
2351            if (treeExpansionModel == null) return false;
2352            return treeExpansionModel.isExpanded (node);
2353        }
2354
2355        /**
2356         * Called when given node is expanded.
2357         *
2358         * @param node a expanded node
2359         */

2360        public void nodeExpanded (Object JavaDoc node) {
2361            if (treeExpansionModel != null)
2362                treeExpansionModel.nodeExpanded (node);
2363        }
2364
2365        /**
2366         * Called when given node is collapsed.
2367         *
2368         * @param node a collapsed node
2369         */

2370        public void nodeCollapsed (Object JavaDoc node) {
2371            if (treeExpansionModel != null)
2372                treeExpansionModel.nodeCollapsed (node);
2373        }
2374
2375
2376        // listeners ...............................................................
2377

2378        /**
2379         * Registers given listener.
2380         *
2381         * @param l the listener to add
2382         */

2383        public void addModelListener (ModelListener l) {
2384            treeModel.addModelListener (l);
2385            if (nodeModel != treeModel) {
2386                nodeModel.addModelListener (l);
2387            }
2388            if (tableModel != treeModel && tableModel != nodeModel) {
2389                tableModel.addModelListener (l);
2390            }
2391        }
2392
2393        /**
2394         * Unregisters given listener.
2395         *
2396         * @param l the listener to remove
2397         */

2398        public void removeModelListener (ModelListener l) {
2399            treeModel.removeModelListener (l);
2400            if (nodeModel != treeModel) {
2401                nodeModel.removeModelListener (l);
2402            }
2403            if (tableModel != treeModel && tableModel != nodeModel) {
2404                tableModel.removeModelListener (l);
2405            }
2406        }
2407
2408        public String JavaDoc toString () {
2409            return super.toString () +
2410                   "\n TreeModel = " + treeModel +
2411                   "\n NodeModel = " + nodeModel +
2412                   "\n TableModel = " + tableModel +
2413                   "\n NodeActionsProvider = " + nodeActionsProvider +
2414                   "\n ColumnsModel = " + java.util.Arrays.asList(columnModels);
2415        }
2416    }
2417}
2418
Popular Tags