Source Code Cross Referenced for Models.java in  » IDE-Netbeans » spi » org » netbeans » spi » viewmodel » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » spi » org.netbeans.spi.viewmodel 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:
0042:        package org.netbeans.spi.viewmodel;
0043:
0044:        import java.awt.datatransfer.Transferable;
0045:        import java.awt.event.ActionEvent;
0046:        import java.io.IOException;
0047:        import java.lang.StringBuffer;
0048:        import java.util.ArrayList;
0049:        import java.util.Collection;
0050:        import java.util.Collections;
0051:        import java.util.HashMap;
0052:        import java.util.HashSet;
0053:        import java.util.IdentityHashMap;
0054:        import java.util.Iterator;
0055:        import java.util.LinkedList;
0056:        import java.util.List;
0057:        import java.util.Set;
0058:        import java.util.Vector;
0059:        import java.util.WeakHashMap;
0060:        import javax.swing.AbstractAction;
0061:        import javax.swing.Action;
0062:        import javax.swing.JComponent;
0063:        import javax.swing.SwingUtilities;
0064:
0065:        import org.netbeans.modules.viewmodel.TreeTable;
0066:
0067:        import org.netbeans.spi.viewmodel.ColumnModel;
0068:        import org.netbeans.spi.viewmodel.NodeActionsProvider;
0069:        import org.netbeans.spi.viewmodel.NodeActionsProviderFilter;
0070:        import org.netbeans.spi.viewmodel.NodeModel;
0071:        import org.netbeans.spi.viewmodel.ExtendedNodeModel;
0072:        import org.netbeans.spi.viewmodel.ExtendedNodeModelFilter;
0073:        import org.netbeans.spi.viewmodel.NodeModelFilter;
0074:        import org.netbeans.spi.viewmodel.TableModel;
0075:        import org.netbeans.spi.viewmodel.TableModelFilter;
0076:        import org.netbeans.spi.viewmodel.TreeModel;
0077:        import org.netbeans.spi.viewmodel.TreeModelFilter;
0078:        import org.netbeans.spi.viewmodel.ModelListener;
0079:        import org.netbeans.spi.viewmodel.UnknownTypeException;
0080:        import org.openide.ErrorManager;
0081:
0082:        import org.openide.nodes.Node;
0083:        import org.openide.util.Exceptions;
0084:        import org.openide.util.WeakSet;
0085:        import org.openide.util.datatransfer.PasteType;
0086:        import org.openide.windows.TopComponent;
0087:
0088:        /**
0089:         * Contains various utility methods for various models.
0090:         *
0091:         * @author   Jan Jancura
0092:         */
0093:        public final class Models {
0094:
0095:            /** Cached default implementations of expansion models. */
0096:            private static WeakHashMap<Object, TreeExpansionModel> defaultExpansionModels = new WeakHashMap<Object, TreeExpansionModel>();
0097:            /**
0098:             * Empty model - returns default root node with no children.
0099:             */
0100:            public static CompoundModel EMPTY_MODEL = createCompoundModel(new ArrayList());
0101:
0102:            public static int MULTISELECTION_TYPE_EXACTLY_ONE = 1;
0103:            public static int MULTISELECTION_TYPE_ALL = 2;
0104:            public static int MULTISELECTION_TYPE_ANY = 3;
0105:
0106:            private static boolean verbose = System
0107:                    .getProperty("netbeans.debugger.models") != null;
0108:
0109:            /**
0110:             * Creates a new instance of TreeTableView
0111:             * for given {@link org.netbeans.spi.viewmodel.Models.CompoundModel}.
0112:             *
0113:             * @param compoundModel a compound model instance
0114:             *
0115:             * @return new instance of complete model view
0116:             */
0117:            public static JComponent createView(CompoundModel compoundModel) {
0118:                TreeTable tt = new TreeTable();
0119:                tt.setModel(compoundModel);
0120:                return tt;
0121:            }
0122:
0123:            /**
0124:             * Set given models to given view instance.
0125:             *
0126:             * @param view a view instance - must be an instance created by {@link #createView} method.
0127:             * @param compoundModel a compound model instance
0128:             */
0129:            public static void setModelsToView(final JComponent view,
0130:                    final CompoundModel compoundModel) {
0131:                if (!(view instanceof  TreeTable)) {
0132:                    throw new IllegalArgumentException(
0133:                            "Expecting an instance of "
0134:                                    + TreeTable.class.getName()
0135:                                    + ", which can be obtained from Models.createView().");
0136:                }
0137:                if (verbose)
0138:                    System.out.println(compoundModel);
0139:                SwingUtilities.invokeLater(new Runnable() {
0140:                    public void run() {
0141:                        ((TreeTable) view).setModel(compoundModel);
0142:                    }
0143:                });
0144:            }
0145:
0146:            /**
0147:             * Creates one {@link CompoundModel} from given list of models.
0148:             * <p>
0149:             * If this list does not include any instance of TreeModel or
0150:             * TreeExpansionModel, a default implementation of these models is created
0151:             * based on the instance of this list. Thus you get one implementation
0152:             * per provided instance of the models list.
0153:             * 
0154:             * @param models a list of models
0155:             * @return {@link CompoundModel} encapsulating given list of models
0156:             */
0157:            public static CompoundModel createCompoundModel(List models) {
0158:                return createCompoundModel(models, null);
0159:            }
0160:
0161:            /**
0162:             * Creates one {@link CompoundModel} from given list of models.
0163:             * <p>
0164:             * If this list does not include any instance of TreeModel or
0165:             * TreeExpansionModel, a default implementation of these models is created
0166:             * based on the instance of this list. Thus you get one implementation
0167:             * per provided instance of the models list.
0168:             * 
0169:             * @param models a list of models
0170:             * @param propertiesHelpID The help ID, which is set for the properties
0171:             *        sheets created from this model.
0172:             * @return {@link CompoundModel} encapsulating given list of models
0173:             * @since 1.7
0174:             */
0175:            public static CompoundModel createCompoundModel(List models,
0176:                    String propertiesHelpID) {
0177:                List<TreeModel> treeModels;
0178:                List<TreeModelFilter> treeModelFilters;
0179:                List<TreeExpansionModel> treeExpansionModels;
0180:                List<NodeModel> nodeModels;
0181:                List<NodeModelFilter> nodeModelFilters;
0182:                List<TableModel> tableModels;
0183:                List<TableModelFilter> tableModelFilters;
0184:                List<NodeActionsProvider> nodeActionsProviders;
0185:                List<NodeActionsProviderFilter> nodeActionsProviderFilters;
0186:                List<ColumnModel> columnModels;
0187:                List<? extends Model> otherModels;
0188:
0189:                // Either the list contains 10 lists of individual models + one list of mixed models; or the models directly
0190:                boolean hasLists = false;
0191:                if (models.size() == 11) {
0192:                    Iterator it = models.iterator();
0193:                    while (it.hasNext()) {
0194:                        if (!(it.next() instanceof  List))
0195:                            break;
0196:                    }
0197:                    if (!it.hasNext()) { // All elements are lists
0198:                        hasLists = true;
0199:                    }
0200:                }
0201:                if (hasLists) { // We have 11 lists of individual models
0202:                    treeModels = (List<TreeModel>) models.get(0);
0203:                    treeModelFilters = (List<TreeModelFilter>) models.get(1);
0204:                    revertOrder(treeModelFilters);
0205:                    treeExpansionModels = (List<TreeExpansionModel>) models
0206:                            .get(2);
0207:                    nodeModels = (List<NodeModel>) models.get(3);
0208:                    nodeModelFilters = (List<NodeModelFilter>) models.get(4);
0209:                    revertOrder(nodeModelFilters);
0210:                    tableModels = (List<TableModel>) models.get(5);
0211:                    tableModelFilters = (List<TableModelFilter>) models.get(6);
0212:                    revertOrder(tableModelFilters);
0213:                    nodeActionsProviders = (List<NodeActionsProvider>) models
0214:                            .get(7);
0215:                    nodeActionsProviderFilters = (List<NodeActionsProviderFilter>) models
0216:                            .get(8);
0217:                    revertOrder(nodeActionsProviderFilters);
0218:                    columnModels = (List<ColumnModel>) models.get(9);
0219:                    otherModels = (List<? extends Model>) models.get(10);
0220:                } else { // We have the models, need to find out what they implement
0221:                    treeModels = new LinkedList<TreeModel>();
0222:                    treeModelFilters = new LinkedList<TreeModelFilter>();
0223:                    treeExpansionModels = new LinkedList<TreeExpansionModel>();
0224:                    nodeModels = new LinkedList<NodeModel>();
0225:                    nodeModelFilters = new LinkedList<NodeModelFilter>();
0226:                    tableModels = new LinkedList<TableModel>();
0227:                    tableModelFilters = new LinkedList<TableModelFilter>();
0228:                    nodeActionsProviders = new LinkedList<NodeActionsProvider>();
0229:                    nodeActionsProviderFilters = new LinkedList<NodeActionsProviderFilter>();
0230:                    columnModels = new LinkedList<ColumnModel>();
0231:                    otherModels = (List<? extends Model>) models;
0232:                }
0233:
0234:                Iterator it = otherModels.iterator();
0235:                while (it.hasNext()) {
0236:                    Object model = it.next();
0237:                    boolean first = model.getClass().getName()
0238:                            .endsWith("First");
0239:                    if (model instanceof  TreeModel)
0240:                        treeModels.add((TreeModel) model);
0241:                    if (model instanceof  TreeModelFilter)
0242:                        if (first)
0243:                            treeModelFilters.add((TreeModelFilter) model);
0244:                        else
0245:                            treeModelFilters.add(0, (TreeModelFilter) model);
0246:                    if (model instanceof  TreeExpansionModel)
0247:                        treeExpansionModels.add((TreeExpansionModel) model);
0248:                    if (model instanceof  NodeModel)
0249:                        nodeModels.add((NodeModel) model);
0250:                    if (model instanceof  NodeModelFilter)
0251:                        if (first)
0252:                            nodeModelFilters.add((NodeModelFilter) model);
0253:                        else
0254:                            nodeModelFilters.add(0, (NodeModelFilter) model);
0255:                    if (model instanceof  TableModel)
0256:                        tableModels.add((TableModel) model);
0257:                    if (model instanceof  TableModelFilter)
0258:                        if (first)
0259:                            tableModelFilters.add((TableModelFilter) model);
0260:                        else
0261:                            tableModelFilters.add(0, (TableModelFilter) model);
0262:                    if (model instanceof  NodeActionsProvider)
0263:                        nodeActionsProviders.add((NodeActionsProvider) model);
0264:                    if (model instanceof  NodeActionsProviderFilter)
0265:                        if (first)
0266:                            nodeActionsProviderFilters
0267:                                    .add((NodeActionsProviderFilter) model);
0268:                        else
0269:                            nodeActionsProviderFilters.add(0,
0270:                                    (NodeActionsProviderFilter) model);
0271:                    if (model instanceof  ColumnModel)
0272:                        columnModels.add((ColumnModel) model);
0273:                }
0274:                /*
0275:                System.out.println("Tree Models = "+treeModels);
0276:                System.out.println("Tree Model Filters = "+treeModelFilters);
0277:                System.out.println("Tree Expans Models = "+treeExpansionModels);
0278:                System.out.println("Node Models = "+nodeModels);
0279:                System.out.println("Node Model Filters = "+nodeModelFilters);
0280:                System.out.println("Table Models = "+tableModels);
0281:                System.out.println("Table Model Filters = "+tableModelFilters);
0282:                System.out.println("Node Action Providers = "+nodeActionsProviders);
0283:                System.out.println("Node Action Provider Filters = "+nodeActionsProviderFilters);
0284:                System.out.println("Column Models = "+columnModels);
0285:                 */
0286:                if (treeModels.isEmpty()) {
0287:                    TreeModel etm = new EmptyTreeModel();
0288:                    treeModels = Collections.singletonList(etm);
0289:                }
0290:                if (treeExpansionModels.isEmpty()) {
0291:                    TreeExpansionModel tem = defaultExpansionModels.get(models);
0292:                    if (tem == null) {
0293:                        tem = new DefaultTreeExpansionModel();
0294:                        defaultExpansionModels.put(models, tem);
0295:                    }
0296:                    treeExpansionModels = Collections.singletonList(tem);
0297:                }
0298:
0299:                return new CompoundModel(createCompoundTreeModel(
0300:                        new DelegatingTreeModel(treeModels), treeModelFilters),
0301:                        new DelegatingTreeExpansionModel(treeExpansionModels),
0302:                        createCompoundNodeModel(new DelegatingNodeModel(
0303:                                nodeModels), nodeModelFilters),
0304:                        createCompoundNodeActionsProvider(
0305:                                new DelegatingNodeActionsProvider(
0306:                                        nodeActionsProviders),
0307:                                nodeActionsProviderFilters), columnModels,
0308:                        createCompoundTableModel(new DelegatingTableModel(
0309:                                tableModels), tableModelFilters),
0310:                        propertiesHelpID);
0311:            }
0312:
0313:            private static <T> void revertOrder(List<T> filters) {
0314:                int n = filters.size();
0315:                for (int i = 0; i < n;) {
0316:                    T filter = filters.remove(i);
0317:                    boolean first = filter.getClass().getName().endsWith(
0318:                            "First");
0319:                    if (first) { // The "First" should be the last one in this list
0320:                        filters.add(filter);
0321:                        n--;
0322:                    } else {
0323:                        filters.add(0, filter);
0324:                        i++;
0325:                    }
0326:                }
0327:            }
0328:
0329:            /**
0330:             * Returns {@link javax.swing.Action} for given parameters.
0331:             *
0332:             * @param displayName a display name for action
0333:             * @param performer a performer for action
0334:             * @param multiselectionType The type of the multiselection - one of the
0335:             *        MULTISELECTION_TYPE_* constants.
0336:             *
0337:             * @return a new instance of {@link javax.swing.Action} for given parameters
0338:             */
0339:            public static Action createAction(String displayName,
0340:                    ActionPerformer performer, int multiselectionType) {
0341:                return new ActionSupport(displayName, performer,
0342:                        multiselectionType);
0343:            }
0344:
0345:            /**
0346:             * Returns implementation of tree view features for given view.
0347:             *
0348:             * @param view a view created by this Models class
0349:             * @throws UnsupportedOperationException in the case that given 
0350:             *        view is not tree view
0351:             * @return implementation of tree view features
0352:             */
0353:            public static TreeFeatures treeFeatures(JComponent view)
0354:                    throws UnsupportedOperationException {
0355:                return new TreeFeatures(view);
0356:            }
0357:
0358:            // private methods .........................................................
0359:
0360:            /**
0361:             * Creates {@link org.netbeans.spi.viewmodel.TreeModel} for given TreeModel and
0362:             * {@link org.netbeans.spi.viewmodel.TreeModelFilter}.
0363:             * 
0364:             * @param originalTreeModel a original tree model
0365:             * @param treeModelFilter a list of tree model filters
0366:             *
0367:             * @returns compund tree model
0368:             */
0369:            private static TreeModel createCompoundTreeModel(
0370:                    TreeModel originalTreeModel, List treeModelFilters) {
0371:                TreeModel tm = originalTreeModel;
0372:                int i, k = treeModelFilters.size();
0373:                for (i = 0; i < k; i++)
0374:                    tm = new CompoundTreeModel(tm,
0375:                            (TreeModelFilter) treeModelFilters.get(i));
0376:                return tm;
0377:            }
0378:
0379:            /**
0380:             * Creates {@link org.netbeans.spi.viewmodel.NodeModel} for given NodeModel and
0381:             * {@link org.netbeans.spi.viewmodel.NodeModelFilter}.
0382:             * 
0383:             * @param originalNodeModel a original node model
0384:             * @param nodeModelFilters a list of node model filters
0385:             *
0386:             * @returns compund tree model
0387:             */
0388:            private static ExtendedNodeModel createCompoundNodeModel(
0389:                    ExtendedNodeModel originalNodeModel,
0390:                    List treeNodeModelFilters) {
0391:                ExtendedNodeModel nm = originalNodeModel;
0392:                int i, k = treeNodeModelFilters.size();
0393:                for (i = 0; i < k; i++)
0394:                    nm = new CompoundNodeModel(nm,
0395:                            (NodeModelFilter) treeNodeModelFilters.get(i));
0396:                return nm;
0397:            }
0398:
0399:            /**
0400:             * Creates {@link org.netbeans.spi.viewmodel.TableModel} for given TableModel and
0401:             * {@link org.netbeans.spi.viewmodel.TableModelFilter}.
0402:             * 
0403:             * @param originalTableModel a original table model
0404:             * @param tableModelFilters a list of table model filters
0405:             *
0406:             * @returns compund table model
0407:             */
0408:            private static TableModel createCompoundTableModel(
0409:                    TableModel originalTableModel, List tableModelFilters) {
0410:                TableModel tm = originalTableModel;
0411:                int i, k = tableModelFilters.size();
0412:                for (i = 0; i < k; i++)
0413:                    tm = new CompoundTableModel(tm,
0414:                            (TableModelFilter) tableModelFilters.get(i));
0415:                return tm;
0416:            }
0417:
0418:            /**
0419:             * Creates {@link org.netbeans.spi.viewmodel.NodeActionsProvider} for given NodeActionsProvider and
0420:             * {@link org.netbeans.spi.viewmodel.NodeActionsProviderFilter}.
0421:             * 
0422:             * @param originalNodeActionsProvider a original node actions provider
0423:             * @param nodeActionsProviderFilters a list of node actions provider filters
0424:             *
0425:             * @returns compund node actions provider
0426:             */
0427:            private static NodeActionsProvider createCompoundNodeActionsProvider(
0428:                    NodeActionsProvider originalNodeActionsProvider,
0429:                    List nodeActionsProviderFilters) {
0430:                NodeActionsProvider nap = originalNodeActionsProvider;
0431:                int i, k = nodeActionsProviderFilters.size();
0432:                for (i = 0; i < k; i++)
0433:                    nap = new CompoundNodeActionsProvider(
0434:                            nap,
0435:                            (NodeActionsProviderFilter) nodeActionsProviderFilters
0436:                                    .get(i));
0437:                return nap;
0438:            }
0439:
0440:            // innerclasses ............................................................
0441:
0442:            /**
0443:             * @author   Jan Jancura
0444:             */
0445:            private static class ActionSupport extends AbstractAction {
0446:
0447:                private ActionPerformer performer;
0448:                private int multiselectionType;
0449:                private String displayName;
0450:
0451:                ActionSupport(String displayName, ActionPerformer performer,
0452:                        int multiselectionType) {
0453:                    super (displayName);
0454:                    this .performer = performer;
0455:                    this .displayName = displayName;
0456:                    this .multiselectionType = multiselectionType;
0457:                }
0458:
0459:                public boolean isEnabled() {
0460:                    if (multiselectionType == MULTISELECTION_TYPE_ANY)
0461:                        return true;
0462:                    Node[] ns = TopComponent.getRegistry().getActivatedNodes();
0463:                    if (multiselectionType == MULTISELECTION_TYPE_EXACTLY_ONE) {
0464:                        if (ns.length != 1)
0465:                            return false;
0466:                        return performer.isEnabled(ns[0].getLookup().lookup(
0467:                                Object.class));
0468:                    }
0469:                    int i, k = ns.length;
0470:                    for (i = 0; i < k; i++)
0471:                        if (!performer.isEnabled(ns[i].getLookup().lookup(
0472:                                Object.class)))
0473:                            return false;
0474:                    return true;
0475:                }
0476:
0477:                public void actionPerformed(ActionEvent e) {
0478:                    Node[] ns = TopComponent.getRegistry().getActivatedNodes();
0479:                    int i, k = ns.length;
0480:                    IdentityHashMap<Action, ArrayList<Object>> h = new IdentityHashMap<Action, ArrayList<Object>>();
0481:                    for (i = 0; i < k; i++) {
0482:                        Object node = ns[i].getLookup().lookup(Object.class);
0483:                        Action[] as = ns[i].getActions(false);
0484:                        int j, jj = as.length;
0485:                        for (j = 0; j < jj; j++)
0486:                            if (equals(as[j])) {
0487:                                ArrayList<Object> l = h.get(as[j]);
0488:                                if (l == null) {
0489:                                    l = new ArrayList<Object>();
0490:                                    h.put(as[j], l);
0491:                                }
0492:                                l.add(node);
0493:                            }
0494:                    }
0495:                    Iterator<Action> it = h.keySet().iterator();
0496:                    while (it.hasNext()) {
0497:                        ActionSupport a = (ActionSupport) it.next();
0498:                        a.performer.perform(((ArrayList) h.get(a)).toArray());
0499:                    }
0500:                }
0501:
0502:                public int hashCode() {
0503:                    return displayName.hashCode();
0504:                }
0505:
0506:                public boolean equals(Object o) {
0507:                    return (o instanceof  ActionSupport)
0508:                            && displayName
0509:                                    .equals(((ActionSupport) o).displayName);
0510:                }
0511:            }
0512:
0513:            /**
0514:             * Support interface for 
0515:             * {@link #createAction(String,Models.ActionPerformer,int)} method.
0516:             */
0517:            public static interface ActionPerformer {
0518:
0519:                /**
0520:                 * Returns enabled property state for given node.
0521:                 *
0522:                 * @param node the node the action shouuld be applied to
0523:                 * @return enabled property state for given node
0524:                 *
0525:                 * @see #createAction(String,Models.ActionPerformer,int)
0526:                 */
0527:                public boolean isEnabled(Object node);
0528:
0529:                /**
0530:                 * Called when action <code>action</code> is performed for 
0531:                 * nodes.
0532:                 *
0533:                 * @param nodes nodes the action shouuld be applied to
0534:                 *
0535:                 * @see #createAction(String,Models.ActionPerformer,int)
0536:                 */
0537:                public void perform(Object[] nodes);
0538:            }
0539:
0540:            /**
0541:             * Creates {@link org.netbeans.spi.viewmodel.TreeModel} for given TreeModel and
0542:             * {@link org.netbeans.spi.viewmodel.TreeModelFilter}.
0543:             * 
0544:             * @author   Jan Jancura
0545:             */
0546:            final static class CompoundTreeModel implements  TreeModel,
0547:                    ModelListener {
0548:
0549:                private TreeModel model;
0550:                private TreeModelFilter filter;
0551:
0552:                private Collection<ModelListener> modelListeners = new HashSet<ModelListener>();
0553:
0554:                /**
0555:                 * Creates {@link org.netbeans.spi.viewmodel.TreeModel} for given TreeModel and
0556:                 * {@link org.netbeans.spi.viewmodel.TreeModelFilter}.
0557:                 */
0558:                CompoundTreeModel(TreeModel model, TreeModelFilter filter) {
0559:                    this .model = model;
0560:                    this .filter = filter;
0561:                }
0562:
0563:                /** 
0564:                 * Returns the root node of the tree or null, if the tree is empty.
0565:                 *
0566:                 * @return the root node of the tree or null
0567:                 */
0568:                public Object getRoot() {
0569:                    return filter.getRoot(model);
0570:                }
0571:
0572:                /** 
0573:                 * Returns children for given parent on given indexes.
0574:                 *
0575:                 * @param   parent a parent of returned nodes
0576:                 * @throws  NoInformationException if the set of children can not be 
0577:                 *          resolved
0578:                 * @throws  UnknownTypeException if this TreeModel implementation is not
0579:                 *          able to resolve dchildren for given node type
0580:                 *
0581:                 * @return  children for given parent on given indexes
0582:                 */
0583:                public Object[] getChildren(Object parent, int from, int to)
0584:                        throws UnknownTypeException {
0585:
0586:                    return filter.getChildren(model, parent, from, to);
0587:                }
0588:
0589:                /**
0590:                 * Returns number of children for given node.
0591:                 * 
0592:                 * @param   node the parent node
0593:                 * @throws  NoInformationException if the set of children can not be 
0594:                 *          resolved
0595:                 * @throws  UnknownTypeException if this TreeModel implementation is not
0596:                 *          able to resolve children for given node type
0597:                 *
0598:                 * @return  true if node is leaf
0599:                 */
0600:                public int getChildrenCount(Object node)
0601:                        throws UnknownTypeException {
0602:                    return filter.getChildrenCount(model, node);
0603:                }
0604:
0605:                /**
0606:                 * Returns true if node is leaf.
0607:                 * 
0608:                 * @throws  UnknownTypeException if this TreeModel implementation is not
0609:                 *          able to resolve dchildren for given node type
0610:                 * @return  true if node is leaf
0611:                 */
0612:                public boolean isLeaf(Object node) throws UnknownTypeException {
0613:                    return filter.isLeaf(model, node);
0614:                }
0615:
0616:                /** 
0617:                 * Registers given listener.
0618:                 * 
0619:                 * @param l the listener to add
0620:                 */
0621:                public void addModelListener(ModelListener l) {
0622:                    synchronized (modelListeners) {
0623:                        if (modelListeners.size() == 0) {
0624:                            filter.addModelListener(this );
0625:                            model.addModelListener(this );
0626:                        }
0627:                        modelListeners.add(l);
0628:                    }
0629:                }
0630:
0631:                /** 
0632:                 * Unregisters given listener.
0633:                 *
0634:                 * @param l the listener to remove
0635:                 */
0636:                public void removeModelListener(ModelListener l) {
0637:                    synchronized (modelListeners) {
0638:                        modelListeners.remove(l);
0639:                        if (modelListeners.size() == 0) {
0640:                            filter.removeModelListener(this );
0641:                            model.removeModelListener(this );
0642:                        }
0643:                    }
0644:                }
0645:
0646:                public void modelChanged(ModelEvent event) {
0647:                    ModelEvent newEvent = translateEvent(event, this );
0648:                    Collection<ModelListener> listeners;
0649:                    synchronized (modelListeners) {
0650:                        listeners = new ArrayList<ModelListener>(modelListeners);
0651:                    }
0652:                    for (Iterator<ModelListener> it = listeners.iterator(); it
0653:                            .hasNext();) {
0654:                        it.next().modelChanged(newEvent);
0655:                    }
0656:                }
0657:
0658:                public String toString() {
0659:                    return super .toString() + "\n" + toString("    ");
0660:                }
0661:
0662:                public String toString(String n) {
0663:                    if (model instanceof  CompoundTreeModel)
0664:                        return n
0665:                                + filter
0666:                                + "\n"
0667:                                + ((CompoundTreeModel) model)
0668:                                        .toString(n + "  ");
0669:                    return n + filter + "\n" + n + "  " + model;
0670:                }
0671:
0672:            }
0673:
0674:            private static ModelEvent translateEvent(ModelEvent event,
0675:                    Object newSource) {
0676:                ModelEvent newEvent;
0677:                if (event instanceof  ModelEvent.NodeChanged) {
0678:                    newEvent = new ModelEvent.NodeChanged(newSource,
0679:                            ((ModelEvent.NodeChanged) event).getNode(),
0680:                            ((ModelEvent.NodeChanged) event).getChange());
0681:                } else if (event instanceof  ModelEvent.TableValueChanged) {
0682:                    newEvent = new ModelEvent.TableValueChanged(newSource,
0683:                            ((ModelEvent.TableValueChanged) event).getNode(),
0684:                            ((ModelEvent.TableValueChanged) event)
0685:                                    .getColumnID());
0686:                } else if (event instanceof  ModelEvent.TreeChanged) {
0687:                    newEvent = new ModelEvent.TreeChanged(newSource);
0688:                } else {
0689:                    newEvent = event;
0690:                }
0691:                return newEvent;
0692:            }
0693:
0694:            /**
0695:             * Creates {@link org.netbeans.spi.viewmodel.TreeModel} for given TreeModel and
0696:             * {@link org.netbeans.spi.viewmodel.TreeModelFilter}.
0697:             * 
0698:             * @author   Jan Jancura
0699:             */
0700:            final static class CompoundNodeModel implements  ExtendedNodeModel,
0701:                    ModelListener {
0702:
0703:                private ExtendedNodeModel model;
0704:                private NodeModelFilter filter;
0705:
0706:                private Collection<ModelListener> modelListeners = new HashSet<ModelListener>();
0707:
0708:                /**
0709:                 * Creates {@link org.netbeans.spi.viewmodel.TreeModel} for given TreeModel and
0710:                 * {@link org.netbeans.spi.viewmodel.TreeModelFilter}.
0711:                 */
0712:                CompoundNodeModel(ExtendedNodeModel model,
0713:                        NodeModelFilter filter) {
0714:                    this .model = model;
0715:                    this .filter = filter;
0716:                }
0717:
0718:                /**
0719:                 * Returns display name for given node.
0720:                 *
0721:                 * @throws  UnknownTypeException if this NodeModel implementation is not
0722:                 *          able to resolve display name for given node type
0723:                 * @return  display name for given node
0724:                 */
0725:                public String getDisplayName(Object node)
0726:                        throws UnknownTypeException {
0727:                    return filter.getDisplayName(model, node);
0728:                }
0729:
0730:                /**
0731:                 * Returns icon for given node.
0732:                 *
0733:                 * @throws  UnknownTypeException if this NodeModel implementation is not
0734:                 *          able to resolve icon for given node type
0735:                 * @return  icon for given node
0736:                 */
0737:                public String getIconBase(Object node)
0738:                        throws UnknownTypeException {
0739:                    return filter.getIconBase(model, node);
0740:                }
0741:
0742:                /**
0743:                 * Returns tooltip for given node.
0744:                 *
0745:                 * @throws  UnknownTypeException if this NodeModel implementation is not
0746:                 *          able to resolve tooltip for given node type
0747:                 * @return  tooltip for given node
0748:                 */
0749:                public String getShortDescription(Object node)
0750:                        throws UnknownTypeException {
0751:                    return filter.getShortDescription(model, node);
0752:                }
0753:
0754:                /** 
0755:                 * Registers given listener.
0756:                 * 
0757:                 * @param l the listener to add
0758:                 */
0759:                public void addModelListener(ModelListener l) {
0760:                    synchronized (modelListeners) {
0761:                        if (modelListeners.size() == 0) {
0762:                            filter.addModelListener(this );
0763:                            model.addModelListener(this );
0764:                        }
0765:                        modelListeners.add(l);
0766:                    }
0767:                }
0768:
0769:                /** 
0770:                 * Unregisters given listener.
0771:                 *
0772:                 * @param l the listener to remove
0773:                 */
0774:                public void removeModelListener(ModelListener l) {
0775:                    synchronized (modelListeners) {
0776:                        modelListeners.remove(l);
0777:                        if (modelListeners.size() == 0) {
0778:                            filter.removeModelListener(this );
0779:                            model.removeModelListener(this );
0780:                        }
0781:                    }
0782:                }
0783:
0784:                public void modelChanged(ModelEvent event) {
0785:                    ModelEvent newEvent = translateEvent(event, this );
0786:                    Collection<ModelListener> listeners;
0787:                    synchronized (modelListeners) {
0788:                        listeners = new ArrayList<ModelListener>(modelListeners);
0789:                    }
0790:                    for (Iterator<ModelListener> it = listeners.iterator(); it
0791:                            .hasNext();) {
0792:                        it.next().modelChanged(newEvent);
0793:                    }
0794:                }
0795:
0796:                public String toString() {
0797:                    return super .toString() + "\n" + toString("    ");
0798:                }
0799:
0800:                public String toString(String n) {
0801:                    if (model instanceof  CompoundNodeModel)
0802:                        return n
0803:                                + filter
0804:                                + "\n"
0805:                                + ((CompoundNodeModel) model)
0806:                                        .toString(n + "  ");
0807:                    if (model instanceof  DelegatingNodeModel)
0808:                        return n
0809:                                + filter
0810:                                + "\n"
0811:                                + ((DelegatingNodeModel) model).toString(n
0812:                                        + "  ");
0813:                    return n + filter + "\n" + n + "  " + model;
0814:                }
0815:
0816:                public boolean canRename(Object node)
0817:                        throws UnknownTypeException {
0818:                    if (filter instanceof  ExtendedNodeModelFilter) {
0819:                        return ((ExtendedNodeModelFilter) filter).canRename(
0820:                                model, node);
0821:                    } else {
0822:                        return model.canRename(node);
0823:                    }
0824:                }
0825:
0826:                public boolean canCopy(Object node) throws UnknownTypeException {
0827:                    if (filter instanceof  ExtendedNodeModelFilter) {
0828:                        return ((ExtendedNodeModelFilter) filter).canCopy(
0829:                                model, node);
0830:                    } else {
0831:                        return model.canCopy(node);
0832:                    }
0833:                }
0834:
0835:                public boolean canCut(Object node) throws UnknownTypeException {
0836:                    if (filter instanceof  ExtendedNodeModelFilter) {
0837:                        return ((ExtendedNodeModelFilter) filter).canCut(model,
0838:                                node);
0839:                    } else {
0840:                        return model.canCut(node);
0841:                    }
0842:                }
0843:
0844:                public Transferable clipboardCopy(Object node)
0845:                        throws IOException, UnknownTypeException {
0846:                    if (filter instanceof  ExtendedNodeModelFilter) {
0847:                        return ((ExtendedNodeModelFilter) filter)
0848:                                .clipboardCopy(model, node);
0849:                    } else {
0850:                        return model.clipboardCopy(node);
0851:                    }
0852:                }
0853:
0854:                public Transferable clipboardCut(Object node)
0855:                        throws IOException, UnknownTypeException {
0856:                    if (filter instanceof  ExtendedNodeModelFilter) {
0857:                        return ((ExtendedNodeModelFilter) filter).clipboardCut(
0858:                                model, node);
0859:                    } else {
0860:                        return model.clipboardCut(node);
0861:                    }
0862:                }
0863:
0864:                /*public Transferable drag(Object node) throws IOException,
0865:                                                             UnknownTypeException {
0866:                    if (filter instanceof ExtendedNodeModelFilter) {
0867:                        return ((ExtendedNodeModelFilter) filter).drag(model, node);
0868:                    } else {
0869:                        return model.drag(node);
0870:                    }
0871:                }*/
0872:
0873:                public PasteType[] getPasteTypes(Object node, Transferable t)
0874:                        throws UnknownTypeException {
0875:                    if (filter instanceof  ExtendedNodeModelFilter) {
0876:                        return ((ExtendedNodeModelFilter) filter)
0877:                                .getPasteTypes(model, node, t);
0878:                    } else {
0879:                        return model.getPasteTypes(node, t);
0880:                    }
0881:                }
0882:
0883:                /*public PasteType getDropType(Object node, Transferable t, int action,
0884:                                             int index) throws UnknownTypeException {
0885:                    if (filter instanceof ExtendedNodeModelFilter) {
0886:                        return ((ExtendedNodeModelFilter) filter).getDropType(model, node, t, action, index);
0887:                    } else {
0888:                        return model.getDropType(node, t, action, index);
0889:                    }
0890:                }*/
0891:
0892:                public void setName(Object node, String name)
0893:                        throws UnknownTypeException {
0894:                    if (filter instanceof  ExtendedNodeModelFilter) {
0895:                        ((ExtendedNodeModelFilter) filter).setName(model, node,
0896:                                name);
0897:                    } else {
0898:                        model.setName(node, name);
0899:                    }
0900:                }
0901:
0902:                public String getIconBaseWithExtension(Object node)
0903:                        throws UnknownTypeException {
0904:                    if (filter instanceof  ExtendedNodeModelFilter) {
0905:                        return ((ExtendedNodeModelFilter) filter)
0906:                                .getIconBaseWithExtension(model, node);
0907:                    } else {
0908:                        String base;
0909:                        try {
0910:                            base = filter.getIconBase(model, node);
0911:                            if (base != null) {
0912:                                base += ".gif";
0913:                            }
0914:                        } catch (Exception utex) {
0915:                            // The filter can not process the icon base filtering
0916:                            // Perhaps it needs to be upgraded to ExtendedNodeModelFilter
0917:                            ErrorManager
0918:                                    .getDefault()
0919:                                    .notify(
0920:                                            ErrorManager.INFORMATIONAL,
0921:                                            ErrorManager
0922:                                                    .getDefault()
0923:                                                    .annotate(
0924:                                                            utex,
0925:                                                            "The filter "
0926:                                                                    + filter
0927:                                                                    + " does not perform icon base filtering for "
0928:                                                                    + node
0929:                                                                    + ".\n"
0930:                                                                    + "If this is a problem, it should be upgraded to "
0931:                                                                    + "ExtendedNodeModelFilter and getIconBaseWithExtension() implemented."));
0932:                            base = model.getIconBaseWithExtension(node);
0933:                        }
0934:                        return base;
0935:                    }
0936:                }
0937:            }
0938:
0939:            /**
0940:             * Creates {@link org.netbeans.spi.viewmodel.TableModel} for given TableModel and
0941:             * {@link org.netbeans.spi.viewmodel.TableModelFilter}.
0942:             * 
0943:             * @author   Jan Jancura
0944:             */
0945:            final static class CompoundTableModel implements  TableModel,
0946:                    ModelListener {
0947:
0948:                private TableModel model;
0949:                private TableModelFilter filter;
0950:
0951:                private Collection<ModelListener> modelListeners = new HashSet<ModelListener>();
0952:
0953:                /**
0954:                 * Creates {@link org.netbeans.spi.viewmodel.TableModel} for given TableModel and
0955:                 * {@link org.netbeans.spi.viewmodel.TableModelFilter}.
0956:                 */
0957:                CompoundTableModel(TableModel model, TableModelFilter filter) {
0958:                    this .model = model;
0959:                    this .filter = filter;
0960:                }
0961:
0962:                /**
0963:                 * Returns value to be displayed in column <code>columnID</code>
0964:                 * and row <code>node</code>. Column ID is defined in by 
0965:                 * {@link ColumnModel#getID}, and rows are defined by values returned from 
0966:                 * {@TreeModel#getChildren}.
0967:                 *
0968:                 * @param node a object returned from {@TreeModel#getChildren} for this row
0969:                 * @param columnID a id of column defined by {@link ColumnModel#getID}
0970:                 * @throws UnknownTypeException if there is no TableModel defined for given
0971:                 *         parameter type
0972:                 *
0973:                 * @return value of variable representing given position in tree table.
0974:                 */
0975:                public Object getValueAt(Object node, String columnID)
0976:                        throws UnknownTypeException {
0977:                    return filter.getValueAt(model, node, columnID);
0978:                }
0979:
0980:                /**
0981:                 * Returns true if value displayed in column <code>columnID</code>
0982:                 * and row <code>node</code> is read only. Column ID is defined in by 
0983:                 * {@link ColumnModel#getID}, and rows are defined by values returned from 
0984:                 * {@TreeModel#getChildren}.
0985:                 *
0986:                 * @param node a object returned from {@TreeModel#getChildren} for this row
0987:                 * @param columnID a id of column defined by {@link ColumnModel#getID}
0988:                 * @throws UnknownTypeException if there is no TableModel defined for given
0989:                 *         parameter type
0990:                 *
0991:                 * @return true if variable on given position is read only
0992:                 */
0993:                public boolean isReadOnly(Object node, String columnID)
0994:                        throws UnknownTypeException {
0995:                    return filter.isReadOnly(model, node, columnID);
0996:                }
0997:
0998:                /**
0999:                 * Changes a value displayed in column <code>columnID</code>
1000:                 * and row <code>node</code>. Column ID is defined in by 
1001:                 * {@link ColumnModel#getID}, and rows are defined by values returned from 
1002:                 * {@TreeModel#getChildren}.
1003:                 *
1004:                 * @param node a object returned from {@TreeModel#getChildren} for this row
1005:                 * @param columnID a id of column defined by {@link ColumnModel#getID}
1006:                 * @param value a new value of variable on given position
1007:                 * @throws UnknownTypeException if there is no TableModel defined for given
1008:                 *         parameter type
1009:                 */
1010:                public void setValueAt(Object node, String columnID,
1011:                        Object value) throws UnknownTypeException {
1012:                    filter.setValueAt(model, node, columnID, value);
1013:                }
1014:
1015:                /** 
1016:                 * Registers given listener.
1017:                 * 
1018:                 * @param l the listener to add
1019:                 */
1020:                public void addModelListener(ModelListener l) {
1021:                    synchronized (modelListeners) {
1022:                        if (modelListeners.size() == 0) {
1023:                            filter.addModelListener(this );
1024:                            model.addModelListener(this );
1025:                        }
1026:                        modelListeners.add(l);
1027:                    }
1028:                }
1029:
1030:                /** 
1031:                 * Unregisters given listener.
1032:                 *
1033:                 * @param l the listener to remove
1034:                 */
1035:                public void removeModelListener(ModelListener l) {
1036:                    synchronized (modelListeners) {
1037:                        modelListeners.remove(l);
1038:                        if (modelListeners.size() == 0) {
1039:                            filter.removeModelListener(this );
1040:                            model.removeModelListener(this );
1041:                        }
1042:                    }
1043:                }
1044:
1045:                public void modelChanged(ModelEvent event) {
1046:                    ModelEvent newEvent = translateEvent(event, this );
1047:                    Collection<ModelListener> listeners;
1048:                    synchronized (modelListeners) {
1049:                        listeners = new ArrayList<ModelListener>(modelListeners);
1050:                    }
1051:                    for (Iterator<ModelListener> it = listeners.iterator(); it
1052:                            .hasNext();) {
1053:                        it.next().modelChanged(newEvent);
1054:                    }
1055:                }
1056:
1057:                public String toString() {
1058:                    return super .toString() + "\n" + toString("    ");
1059:                }
1060:
1061:                public String toString(String n) {
1062:                    if (model instanceof  CompoundTableModel)
1063:                        return n
1064:                                + filter
1065:                                + "\n"
1066:                                + ((CompoundTableModel) model).toString(n
1067:                                        + "  ");
1068:                    if (model instanceof  DelegatingTableModel)
1069:                        return n
1070:                                + filter
1071:                                + "\n"
1072:                                + ((DelegatingTableModel) model).toString(n
1073:                                        + "  ");
1074:                    return n + filter + "\n" + n + "  " + model;
1075:                }
1076:            }
1077:
1078:            /**
1079:             * Creates one {@link org.netbeans.spi.viewmodel.TreeModel}
1080:             * from given list of TreeModels. DelegatingTreeModel asks all underlaying 
1081:             * models for each concrete parameter, and returns first returned value.
1082:             *
1083:             * @author   Jan Jancura
1084:             */
1085:            final static class DelegatingTreeModel implements  TreeModel {
1086:
1087:                private TreeModel[] models;
1088:                private HashMap<String, TreeModel> classNameToModel = new HashMap<String, TreeModel>();
1089:
1090:                /**
1091:                 * Creates new instance of DelegatingTreeModel for given list of 
1092:                 * TableModels.
1093:                 *
1094:                 * @param models a list of TableModels
1095:                 */
1096:                DelegatingTreeModel(List<TreeModel> models) {
1097:                    this (convert(models));
1098:                }
1099:
1100:                private static TreeModel[] convert(List<TreeModel> l) {
1101:                    TreeModel[] models = new TreeModel[l.size()];
1102:                    return l.toArray(models);
1103:                }
1104:
1105:                /**
1106:                 * Creates new instance of DelegatingTreeModel for given array of 
1107:                 * TableModels.
1108:                 *
1109:                 * @param models a array of TreeModel
1110:                 */
1111:                DelegatingTreeModel(TreeModel[] models) {
1112:                    this .models = models;
1113:                }
1114:
1115:                /** 
1116:                 * Returns the root node of the tree or null, if the tree is empty.
1117:                 *
1118:                 * @return the root node of the tree or null
1119:                 */
1120:                public Object getRoot() {
1121:                    return models[0].getRoot();
1122:                }
1123:
1124:                /** 
1125:                 * Returns children for given parent on given indexes.
1126:                 *
1127:                 * @param   parent a parent of returned nodes
1128:                 * @param   from a start index
1129:                 * @param   to a end index
1130:                 *
1131:                 * @throws  UnknownTypeException if this TreeModel implementation is not
1132:                 *          able to resolve children for given node type
1133:                 *
1134:                 * @return  children for given parent on given indexes
1135:                 */
1136:                public Object[] getChildren(Object node, int from, int to)
1137:                        throws UnknownTypeException {
1138:                    TreeModel model = classNameToModel.get(node.getClass()
1139:                            .getName());
1140:                    if (model != null)
1141:                        try {
1142:                            return model.getChildren(node, from, to);
1143:                        } catch (UnknownTypeException e) {
1144:                        }
1145:                    int i, k = models.length;
1146:                    for (i = 0; i < k; i++) {
1147:                        try {
1148:                            Object[] v = models[i].getChildren(node, from, to);
1149:                            classNameToModel.put(node.getClass().getName(),
1150:                                    models[i]);
1151:                            return v;
1152:                        } catch (UnknownTypeException e) {
1153:                        }
1154:                    }
1155:                    throw new UnknownTypeException(node);
1156:                }
1157:
1158:                /**
1159:                 * Returns number of children for given node.
1160:                 * 
1161:                 * @param   node the parent node
1162:                 * @throws  UnknownTypeException if this TreeModel implementation is not
1163:                 *          able to resolve children for given node type
1164:                 *
1165:                 * @return  true if node is leaf
1166:                 * @since 1.1
1167:                 */
1168:                public int getChildrenCount(Object node)
1169:                        throws UnknownTypeException {
1170:                    TreeModel model = (TreeModel) classNameToModel.get(node
1171:                            .getClass().getName());
1172:                    if (model != null)
1173:                        try {
1174:                            return model.getChildrenCount(node);
1175:                        } catch (UnknownTypeException e) {
1176:                        }
1177:                    int i, k = models.length;
1178:                    for (i = 0; i < k; i++) {
1179:                        try {
1180:                            int result = models[i].getChildrenCount(node);
1181:                            classNameToModel.put(node.getClass().getName(),
1182:                                    models[i]);
1183:                            return result;
1184:                        } catch (UnknownTypeException e) {
1185:                        }
1186:                    }
1187:                    throw new UnknownTypeException(node);
1188:                }
1189:
1190:                /**
1191:                 * Returns true if node is leaf.
1192:                 * 
1193:                 * @throws  UnknownTypeException if this TreeModel implementation is not
1194:                 *          able to resolve dchildren for given node type
1195:                 * @return  true if node is leaf
1196:                 */
1197:                public boolean isLeaf(Object node) throws UnknownTypeException {
1198:                    TreeModel model = classNameToModel.get(node.getClass()
1199:                            .getName());
1200:                    if (model != null)
1201:                        try {
1202:                            return model.isLeaf(node);
1203:                        } catch (UnknownTypeException e) {
1204:                        }
1205:                    int i, k = models.length;
1206:                    for (i = 0; i < k; i++) {
1207:                        try {
1208:                            boolean result = models[i].isLeaf(node);
1209:                            classNameToModel.put(node.getClass().getName(),
1210:                                    models[i]);
1211:                            return result;
1212:                        } catch (UnknownTypeException e) {
1213:                        }
1214:                    }
1215:                    throw new UnknownTypeException(node);
1216:                }
1217:
1218:                /** 
1219:                 * Registers given listener.
1220:                 * 
1221:                 * @param l the listener to add
1222:                 */
1223:                public void addModelListener(ModelListener l) {
1224:                    int i, k = models.length;
1225:                    for (i = 0; i < k; i++)
1226:                        models[i].addModelListener(l);
1227:                }
1228:
1229:                /** 
1230:                 * Unregisters given listener.
1231:                 *
1232:                 * @param l the listener to remove
1233:                 */
1234:                public void removeModelListener(ModelListener l) {
1235:                    int i, k = models.length;
1236:                    for (i = 0; i < k; i++)
1237:                        models[i].removeModelListener(l);
1238:                }
1239:
1240:                public String toString() {
1241:                    return super .toString() + "\n" + toString("    ");
1242:                }
1243:
1244:                public String toString(String n) {
1245:                    int i, k = models.length - 1;
1246:                    if (k == -1)
1247:                        return "";
1248:                    StringBuffer sb = new StringBuffer();
1249:                    for (i = 0; i < k; i++) {
1250:                        sb.append(n);
1251:                        sb.append(models[i]);
1252:                        sb.append('\n');
1253:                    }
1254:                    sb.append(n);
1255:                    sb.append(models[i]);
1256:                    return new String(sb);
1257:                }
1258:            }
1259:
1260:            /**
1261:             * Creates {@link org.netbeans.spi.viewmodel.NodeActionsProvider} 
1262:             * for given NodeActionsProvider and
1263:             * {@link org.netbeans.spi.viewmodel.NodeActionsProviderFilter}.
1264:             * 
1265:             * @author   Jan Jancura
1266:             */
1267:            final static class CompoundNodeActionsProvider implements 
1268:                    NodeActionsProvider {
1269:
1270:                private NodeActionsProvider model;
1271:                private NodeActionsProviderFilter filter;
1272:
1273:                /**
1274:                 * Creates {@link org.netbeans.spi.viewmodel.NodeActionsProvider} 
1275:                 * for given NodeActionsProvider and
1276:                 * {@link org.netbeans.spi.viewmodel.NodeActionsProviderFilter}.
1277:                 */
1278:                CompoundNodeActionsProvider(NodeActionsProvider model,
1279:                        NodeActionsProviderFilter filter) {
1280:                    this .model = model;
1281:                    this .filter = filter;
1282:                }
1283:
1284:                /**
1285:                 * Performs default action for given node.
1286:                 *
1287:                 * @throws  UnknownTypeException if this NodeActionsProvider 
1288:                 *          implementation is not able to resolve actions 
1289:                 *          for given node type
1290:                 * @return  display name for given node
1291:                 */
1292:                public void performDefaultAction(Object node)
1293:                        throws UnknownTypeException {
1294:                    filter.performDefaultAction(model, node);
1295:                }
1296:
1297:                /**
1298:                 * Returns set of actions for given node.
1299:                 *
1300:                 * @throws  UnknownTypeException if this NodeActionsProvider implementation 
1301:                 *          is not able to resolve actions for given node type
1302:                 * @return  display name for given node
1303:                 */
1304:                public Action[] getActions(Object node)
1305:                        throws UnknownTypeException {
1306:                    return filter.getActions(model, node);
1307:                }
1308:
1309:                public String toString() {
1310:                    return super .toString() + "\n" + toString("    ");
1311:                }
1312:
1313:                public String toString(String n) {
1314:                    if (model instanceof  CompoundNodeActionsProvider)
1315:                        return n
1316:                                + filter
1317:                                + "\n"
1318:                                + ((CompoundNodeActionsProvider) model)
1319:                                        .toString(n + "  ");
1320:                    if (model instanceof  DelegatingNodeActionsProvider)
1321:                        return n
1322:                                + filter
1323:                                + "\n"
1324:                                + ((DelegatingNodeActionsProvider) model)
1325:                                        .toString(n + "  ");
1326:                    return n + filter + "\n" + n + "  " + model;
1327:                }
1328:            }
1329:
1330:            /**
1331:             * Creates one {@link org.netbeans.spi.viewmodel.TableModel}
1332:             * from given list of TableModels. DelegatingTableModel asks all underlaying 
1333:             * models for each concrete parameter, and returns first returned value.
1334:             *
1335:             * @author   Jan Jancura
1336:             */
1337:            final static class DelegatingTableModel implements  TableModel {
1338:
1339:                private TableModel[] models;
1340:                private HashMap<String, TableModel> classNameToModel = new HashMap<String, TableModel>();
1341:
1342:                /**
1343:                 * Creates new instance of DelegatingTableModel for given list of 
1344:                 * TableModels.
1345:                 *
1346:                 * @param models a list of TableModels
1347:                 */
1348:                DelegatingTableModel(List<TableModel> models) {
1349:                    this (convert(models));
1350:                }
1351:
1352:                private static TableModel[] convert(List<TableModel> l) {
1353:                    TableModel[] models = new TableModel[l.size()];
1354:                    return l.toArray(models);
1355:                }
1356:
1357:                /**
1358:                 * Creates new instance of DelegatingTableModel for given array of 
1359:                 * TableModels.
1360:                 *
1361:                 * @param models a array of TableModels
1362:                 */
1363:                DelegatingTableModel(TableModel[] models) {
1364:                    this .models = models;
1365:                }
1366:
1367:                /**
1368:                 * Returns value to be displayed in column <code>columnID</code>
1369:                 * and row <code>node</code>. Column ID is defined in by 
1370:                 * {@link ColumnModel#getID}, and rows are defined by values returned from 
1371:                 * {@TreeModel#getChildren}.
1372:                 *
1373:                 * @param node a object returned from {@TreeModel#getChildren} for this row
1374:                 * @param columnID a id of column defined by {@link ColumnModel#getID}
1375:                 * @throws UnknownTypeException if there is no TableModel defined for given
1376:                 *         parameter type
1377:                 *
1378:                 * @return value of variable representing given position in tree table.
1379:                 */
1380:                public Object getValueAt(Object node, String columnID)
1381:                        throws UnknownTypeException {
1382:                    TableModel model = classNameToModel.get(node.getClass()
1383:                            .getName());
1384:                    if (model != null)
1385:                        try {
1386:                            return model.getValueAt(node, columnID);
1387:                        } catch (UnknownTypeException e) {
1388:                        }
1389:                    int i, k = models.length;
1390:                    for (i = 0; i < k; i++) {
1391:                        try {
1392:                            Object v = models[i].getValueAt(node, columnID);
1393:                            classNameToModel.put(node.getClass().getName(),
1394:                                    models[i]);
1395:                            return v;
1396:                        } catch (UnknownTypeException e) {
1397:                        }
1398:                    }
1399:                    throw new UnknownTypeException(node);
1400:                }
1401:
1402:                /**
1403:                 * Returns true if value displayed in column <code>columnID</code>
1404:                 * and row <code>node</code> is read only. Column ID is defined in by 
1405:                 * {@link ColumnModel#getID}, and rows are defined by values returned from 
1406:                 * {@TreeModel#getChildren}.
1407:                 *
1408:                 * @param node a object returned from {@TreeModel#getChildren} for this row
1409:                 * @param columnID a id of column defined by {@link ColumnModel#getID}
1410:                 * @throws UnknownTypeException if there is no TableModel defined for given
1411:                 *         parameter type
1412:                 *
1413:                 * @return true if variable on given position is read only
1414:                 */
1415:                public boolean isReadOnly(Object node, String columnID)
1416:                        throws UnknownTypeException {
1417:                    TableModel model = classNameToModel.get(node.getClass()
1418:                            .getName());
1419:                    if (model != null)
1420:                        try {
1421:                            return model.isReadOnly(node, columnID);
1422:                        } catch (UnknownTypeException e) {
1423:                        }
1424:                    int i, k = models.length;
1425:                    for (i = 0; i < k; i++) {
1426:                        try {
1427:                            boolean ro = models[i].isReadOnly(node, columnID);
1428:                            classNameToModel.put(node.getClass().getName(),
1429:                                    models[i]);
1430:                            return ro;
1431:                        } catch (UnknownTypeException e) {
1432:                        }
1433:                    }
1434:                    throw new UnknownTypeException(node);
1435:                }
1436:
1437:                /**
1438:                 * Changes a value displayed in column <code>columnID</code>
1439:                 * and row <code>node</code>. Column ID is defined in by 
1440:                 * {@link ColumnModel#getID}, and rows are defined by values returned from 
1441:                 * {@TreeModel#getChildren}.
1442:                 *
1443:                 * @param node a object returned from {@TreeModel#getChildren} for this row
1444:                 * @param columnID a id of column defined by {@link ColumnModel#getID}
1445:                 * @param value a new value of variable on given position
1446:                 * @throws UnknownTypeException if there is no TableModel defined for given
1447:                 *         parameter type
1448:                 */
1449:                public void setValueAt(Object node, String columnID,
1450:                        Object value) throws UnknownTypeException {
1451:                    TableModel model = classNameToModel.get(node.getClass()
1452:                            .getName());
1453:                    if (model != null)
1454:                        try {
1455:                            model.setValueAt(node, columnID, value);
1456:                            return;
1457:                        } catch (UnknownTypeException e) {
1458:                        }
1459:                    int i, k = models.length;
1460:                    for (i = 0; i < k; i++) {
1461:                        try {
1462:                            models[i].setValueAt(node, columnID, value);
1463:                            classNameToModel.put(node.getClass().getName(),
1464:                                    models[i]);
1465:                            return;
1466:                        } catch (UnknownTypeException e) {
1467:                        }
1468:                    }
1469:                    throw new UnknownTypeException(node);
1470:                }
1471:
1472:                /** 
1473:                 * Registers given listener.
1474:                 * 
1475:                 * @param l the listener to add
1476:                 */
1477:                public void addModelListener(ModelListener l) {
1478:                    int i, k = models.length;
1479:                    for (i = 0; i < k; i++)
1480:                        models[i].addModelListener(l);
1481:                }
1482:
1483:                /** 
1484:                 * Unregisters given listener.
1485:                 *
1486:                 * @param l the listener to remove
1487:                 */
1488:                public void removeModelListener(ModelListener l) {
1489:                    int i, k = models.length;
1490:                    for (i = 0; i < k; i++)
1491:                        models[i].removeModelListener(l);
1492:                }
1493:
1494:                public String toString() {
1495:                    return super .toString() + "\n" + toString("    ");
1496:                }
1497:
1498:                public String toString(String n) {
1499:                    int i, k = models.length - 1;
1500:                    if (k == -1)
1501:                        return "";
1502:                    StringBuffer sb = new StringBuffer();
1503:                    for (i = 0; i < k; i++) {
1504:                        sb.append(n);
1505:                        sb.append(models[i]);
1506:                        sb.append('\n');
1507:                    }
1508:                    sb.append(n);
1509:                    sb.append(models[i]);
1510:                    return new String(sb);
1511:                }
1512:            }
1513:
1514:            /**
1515:             * Creates one {@link org.netbeans.spi.viewmodel.TableModel}
1516:             * from given list of TableModels. DelegatingTableModel asks all underlaying 
1517:             * models for each concrete parameter, and returns first returned value.
1518:             *
1519:             * @author   Jan Jancura
1520:             */
1521:            final static class DelegatingTreeExpansionModel implements 
1522:                    TreeExpansionModel {
1523:
1524:                private TreeExpansionModel[] models;
1525:                private HashMap<String, TreeExpansionModel> classNameToModel = new HashMap<String, TreeExpansionModel>();
1526:
1527:                /**
1528:                 * Creates new instance of DelegatingTableModel for given list of 
1529:                 * TableModels.
1530:                 *
1531:                 * @param models a list of TableModels
1532:                 */
1533:                DelegatingTreeExpansionModel(List<TreeExpansionModel> models) {
1534:                    this (convert(models));
1535:                }
1536:
1537:                private static TreeExpansionModel[] convert(
1538:                        List<TreeExpansionModel> l) {
1539:                    TreeExpansionModel[] models = new TreeExpansionModel[l
1540:                            .size()];
1541:                    return l.toArray(models);
1542:                }
1543:
1544:                /**
1545:                 * Creates new instance of DelegatingTableModel for given array of 
1546:                 * TableModels.
1547:                 *
1548:                 * @param models a array of TableModels
1549:                 */
1550:                private DelegatingTreeExpansionModel(TreeExpansionModel[] models) {
1551:                    this .models = models;
1552:                }
1553:
1554:                /**
1555:                 * Defines default state (collapsed, expanded) of given node.
1556:                 *
1557:                 * @param node a node
1558:                 * @return default state (collapsed, expanded) of given node
1559:                 */
1560:                public boolean isExpanded(Object node)
1561:                        throws UnknownTypeException {
1562:                    TreeExpansionModel model = classNameToModel.get(node
1563:                            .getClass().getName());
1564:                    if (model != null)
1565:                        try {
1566:                            return model.isExpanded(node);
1567:                        } catch (UnknownTypeException e) {
1568:                        }
1569:                    int i, k = models.length;
1570:                    for (i = 0; i < k; i++) {
1571:                        try {
1572:                            boolean result = models[i].isExpanded(node);
1573:                            classNameToModel.put(node.getClass().getName(),
1574:                                    models[i]);
1575:                            return result;
1576:                        } catch (UnknownTypeException e) {
1577:                        }
1578:                    }
1579:                    throw new UnknownTypeException(node);
1580:                }
1581:
1582:                /**
1583:                 * Called when given node is expanded.
1584:                 *
1585:                 * @param node a expanded node
1586:                 */
1587:                public void nodeExpanded(Object node) {
1588:                    int i, k = models.length;
1589:                    for (i = 0; i < k; i++) {
1590:                        models[i].nodeExpanded(node);
1591:                    }
1592:                }
1593:
1594:                /**
1595:                 * Called when given node is collapsed.
1596:                 *
1597:                 * @param node a collapsed node
1598:                 */
1599:                public void nodeCollapsed(Object node) {
1600:                    int i, k = models.length;
1601:                    for (i = 0; i < k; i++) {
1602:                        models[i].nodeCollapsed(node);
1603:                    }
1604:                }
1605:
1606:                public String toString() {
1607:                    return super .toString() + "\n" + toString("    ");
1608:                }
1609:
1610:                public String toString(String n) {
1611:                    int i, k = models.length - 1;
1612:                    if (k == -1)
1613:                        return "";
1614:                    StringBuffer sb = new StringBuffer();
1615:                    for (i = 0; i < k; i++) {
1616:                        sb.append(n);
1617:                        sb.append(models[i]);
1618:                        sb.append('\n');
1619:                    }
1620:                    sb.append(n);
1621:                    sb.append(models[i]);
1622:                    return new String(sb);
1623:                }
1624:            }
1625:
1626:            private static class DefaultTreeExpansionModel implements 
1627:                    TreeExpansionModel {
1628:
1629:                private Set<Object> expandedNodes = new WeakSet<Object>();
1630:                private Set<Object> collapsedNodes = new WeakSet<Object>();
1631:
1632:                /**
1633:                 * Defines default state (collapsed, expanded) of given node.
1634:                 *
1635:                 * @param node a node
1636:                 * @return default state (collapsed, expanded) of given node
1637:                 */
1638:                public boolean isExpanded(Object node)
1639:                        throws UnknownTypeException {
1640:                    synchronized (this ) {
1641:                        if (expandedNodes.contains(node)) {
1642:                            return true;
1643:                        }
1644:                        if (collapsedNodes.contains(node)) {
1645:                            return false;
1646:                        }
1647:                    }
1648:                    // Default behavior follows:
1649:                    return false;
1650:                }
1651:
1652:                /**
1653:                 * Called when given node is expanded.
1654:                 *
1655:                 * @param node a expanded node
1656:                 */
1657:                public void nodeExpanded(Object node) {
1658:                    synchronized (this ) {
1659:                        expandedNodes.add(node);
1660:                        collapsedNodes.remove(node);
1661:                    }
1662:                }
1663:
1664:                /**
1665:                 * Called when given node is collapsed.
1666:                 *
1667:                 * @param node a collapsed node
1668:                 */
1669:                public void nodeCollapsed(Object node) {
1670:                    synchronized (this ) {
1671:                        collapsedNodes.add(node);
1672:                        expandedNodes.remove(node);
1673:                    }
1674:                }
1675:
1676:            }
1677:
1678:            /**
1679:             * Creates one {@link org.netbeans.spi.viewmodel.NodeModel}
1680:             * from given list of NodeModels. DelegatingNodeModel asks all underlaying 
1681:             * models for each concrete parameter, and returns first returned value.
1682:             *
1683:             * @author   Jan Jancura
1684:             */
1685:            static final class DelegatingNodeModel implements  ExtendedNodeModel {
1686:
1687:                private NodeModel[] models;
1688:                private HashMap<String, NodeModel> classNameToModel = new HashMap<String, NodeModel>();
1689:
1690:                /**
1691:                 * Creates new instance of DelegatingNodeModel for given list of 
1692:                 * NodeModels.
1693:                 *
1694:                 * @param models a list of NodeModels
1695:                 */
1696:                DelegatingNodeModel(List<NodeModel> models) {
1697:                    this (convert(models));
1698:                }
1699:
1700:                private static NodeModel[] convert(List<NodeModel> l) {
1701:                    NodeModel[] models = new NodeModel[l.size()];
1702:                    return l.toArray(models);
1703:                }
1704:
1705:                /**
1706:                 * Creates new instance of DelegatingNodeModel for given array of 
1707:                 * NodeModels.
1708:                 *
1709:                 * @param models a array of NodeModels
1710:                 */
1711:                DelegatingNodeModel(NodeModel[] models) {
1712:                    this .models = models;
1713:
1714:                }
1715:
1716:                NodeModel[] getModels() {
1717:                    return models;
1718:                }
1719:
1720:                /**
1721:                 * Returns display name for given node.
1722:                 *
1723:                 * @throws  UnknownTypeException if this NodeModel implementation is not
1724:                 *          able to resolve display name for given node type
1725:                 * @return  display name for given node
1726:                 */
1727:                public String getDisplayName(Object node)
1728:                        throws UnknownTypeException {
1729:                    NodeModel model = classNameToModel.get(node.getClass()
1730:                            .getName());
1731:                    if (model != null)
1732:                        try {
1733:                            return model.getDisplayName(node);
1734:                        } catch (UnknownTypeException e) {
1735:                        }
1736:                    int i, k = models.length;
1737:                    for (i = 0; i < k; i++) {
1738:                        try {
1739:                            String dn = models[i].getDisplayName(node);
1740:                            classNameToModel.put(node.getClass().getName(),
1741:                                    models[i]);
1742:                            return dn;
1743:                        } catch (UnknownTypeException e) {
1744:                        }
1745:                    }
1746:                    throw new UnknownTypeException(node);
1747:                }
1748:
1749:                /**
1750:                 * Returns tooltip for given node.
1751:                 *
1752:                 * @throws  UnknownTypeException if this NodeModel implementation is not
1753:                 *          able to resolve tooltip for given node type
1754:                 * @return  tooltip for given node
1755:                 */
1756:                public String getShortDescription(Object node)
1757:                        throws UnknownTypeException {
1758:                    NodeModel model = classNameToModel.get(node.getClass()
1759:                            .getName());
1760:                    if (model != null)
1761:                        try {
1762:                            return model.getShortDescription(node);
1763:                        } catch (UnknownTypeException e) {
1764:                        }
1765:                    int i, k = models.length;
1766:                    for (i = 0; i < k; i++) {
1767:                        try {
1768:                            String dn = models[i].getShortDescription(node);
1769:                            classNameToModel.put(node.getClass().getName(),
1770:                                    models[i]);
1771:                            return dn;
1772:                        } catch (UnknownTypeException e) {
1773:                        }
1774:                    }
1775:                    throw new UnknownTypeException(node);
1776:                }
1777:
1778:                /**
1779:                 * Returns icon for given node.
1780:                 *
1781:                 * @throws  UnknownTypeException if this NodeModel implementation is not
1782:                 *          able to resolve icon for given node type
1783:                 * @return  icon for given node
1784:                 */
1785:                public String getIconBase(Object node)
1786:                        throws UnknownTypeException {
1787:                    NodeModel model = classNameToModel.get(node.getClass()
1788:                            .getName());
1789:                    if (model != null)
1790:                        try {
1791:                            return model.getIconBase(node);
1792:                        } catch (UnknownTypeException e) {
1793:                        }
1794:                    int i, k = models.length;
1795:                    for (i = 0; i < k; i++) {
1796:                        try {
1797:                            String dn = models[i].getIconBase(node);
1798:                            classNameToModel.put(node.getClass().getName(),
1799:                                    models[i]);
1800:                            return dn;
1801:                        } catch (UnknownTypeException e) {
1802:                        }
1803:                    }
1804:                    throw new UnknownTypeException(node);
1805:                }
1806:
1807:                /** 
1808:                 * Registers given listener.
1809:                 * 
1810:                 * @param l the listener to add
1811:                 */
1812:                public void addModelListener(ModelListener l) {
1813:                    int i, k = models.length;
1814:                    for (i = 0; i < k; i++)
1815:                        models[i].addModelListener(l);
1816:                }
1817:
1818:                /** 
1819:                 * Unregisters given listener.
1820:                 *
1821:                 * @param l the listener to remove
1822:                 */
1823:                public void removeModelListener(ModelListener l) {
1824:                    int i, k = models.length;
1825:                    for (i = 0; i < k; i++)
1826:                        models[i].removeModelListener(l);
1827:                }
1828:
1829:                public String toString() {
1830:                    return toString("    ");
1831:                }
1832:
1833:                public String toString(String n) {
1834:                    int i, k = models.length - 1;
1835:                    if (k == -1)
1836:                        return "";
1837:                    StringBuffer sb = new StringBuffer();
1838:                    for (i = 0; i < k; i++) {
1839:                        sb.append(n);
1840:                        sb.append(models[i]);
1841:                        sb.append('\n');
1842:                    }
1843:                    sb.append(n);
1844:                    sb.append(models[i]);
1845:                    return new String(sb);
1846:                }
1847:
1848:                // Extensions:
1849:
1850:                private boolean defaultCanRename() {
1851:                    return false;
1852:                }
1853:
1854:                private boolean defaultCanCopy() {
1855:                    return false;
1856:                }
1857:
1858:                private boolean defaultCanCut() {
1859:                    return false;
1860:                }
1861:
1862:                private Transferable defaultClipboardCopy() throws IOException {
1863:                    return null;
1864:                }
1865:
1866:                private Transferable defaultClipboardCut() throws IOException {
1867:                    return null;
1868:                }
1869:
1870:                /*
1871:                private Transferable defaultDrag() throws IOException {
1872:                    return null;
1873:                }
1874:                 */
1875:
1876:                private PasteType[] defaultGetPasteTypes(Transferable t) {
1877:                    return null;
1878:                }
1879:
1880:                /*
1881:                private PasteType defaultGetDropType(Transferable t, int action,
1882:                                                    int index) {
1883:                    return null;
1884:                }
1885:                 */
1886:
1887:                private void defaultSetName(String name) {
1888:                    // nothing
1889:                }
1890:
1891:                public boolean canRename(Object node)
1892:                        throws UnknownTypeException {
1893:                    UnknownTypeException uex = null;
1894:                    NodeModel model = classNameToModel.get(node.getClass()
1895:                            .getName());
1896:                    if (model != null) {
1897:                        if (model instanceof  ExtendedNodeModel) {
1898:                            try {
1899:                                return ((ExtendedNodeModel) model)
1900:                                        .canRename(node);
1901:                            } catch (UnknownTypeException e) {
1902:                                uex = e;
1903:                            }
1904:                        } else {
1905:                            return defaultCanRename();
1906:                        }
1907:                    }
1908:                    int i, k = models.length;
1909:                    boolean isExtended = false;
1910:                    for (i = 0; i < k; i++) {
1911:                        if (models[i] instanceof  ExtendedNodeModel) {
1912:                            try {
1913:                                boolean cr = ((ExtendedNodeModel) models[i])
1914:                                        .canRename(node);
1915:                                classNameToModel.put(node.getClass().getName(),
1916:                                        models[i]);
1917:                                return cr;
1918:                            } catch (UnknownTypeException e) {
1919:                                uex = e;
1920:                            }
1921:                            isExtended = true;
1922:                        }
1923:                    }
1924:                    if (!isExtended) {
1925:                        return defaultCanRename();
1926:                    }
1927:                    if (uex != null) {
1928:                        throw uex;
1929:                    } else {
1930:                        throw new UnknownTypeException(node);
1931:                    }
1932:                }
1933:
1934:                public boolean canCopy(Object node) throws UnknownTypeException {
1935:                    UnknownTypeException uex = null;
1936:                    NodeModel model = classNameToModel.get(node.getClass()
1937:                            .getName());
1938:                    if (model != null) {
1939:                        if (model instanceof  ExtendedNodeModel) {
1940:                            try {
1941:                                return ((ExtendedNodeModel) model)
1942:                                        .canCopy(node);
1943:                            } catch (UnknownTypeException e) {
1944:                                uex = e;
1945:                            }
1946:                        } else {
1947:                            return defaultCanCopy();
1948:                        }
1949:                    }
1950:                    int i, k = models.length;
1951:                    boolean isExtended = false;
1952:                    for (i = 0; i < k; i++) {
1953:                        if (models[i] instanceof  ExtendedNodeModel) {
1954:                            try {
1955:                                boolean cr = ((ExtendedNodeModel) models[i])
1956:                                        .canCopy(node);
1957:                                classNameToModel.put(node.getClass().getName(),
1958:                                        models[i]);
1959:                                return cr;
1960:                            } catch (UnknownTypeException e) {
1961:                                uex = e;
1962:                            }
1963:                            isExtended = true;
1964:                        }
1965:                    }
1966:                    if (!isExtended) {
1967:                        return defaultCanCopy();
1968:                    }
1969:                    if (uex != null) {
1970:                        throw uex;
1971:                    } else {
1972:                        throw new UnknownTypeException(node);
1973:                    }
1974:                }
1975:
1976:                public boolean canCut(Object node) throws UnknownTypeException {
1977:                    UnknownTypeException uex = null;
1978:                    NodeModel model = classNameToModel.get(node.getClass()
1979:                            .getName());
1980:                    if (model != null) {
1981:                        if (model instanceof  ExtendedNodeModel) {
1982:                            try {
1983:                                return ((ExtendedNodeModel) model).canCut(node);
1984:                            } catch (UnknownTypeException e) {
1985:                                uex = e;
1986:                            }
1987:                        } else {
1988:                            return defaultCanCut();
1989:                        }
1990:                    }
1991:                    int i, k = models.length;
1992:                    boolean isExtended = false;
1993:                    for (i = 0; i < k; i++) {
1994:                        if (models[i] instanceof  ExtendedNodeModel) {
1995:                            try {
1996:                                boolean cr = ((ExtendedNodeModel) models[i])
1997:                                        .canCut(node);
1998:                                classNameToModel.put(node.getClass().getName(),
1999:                                        models[i]);
2000:                                return cr;
2001:                            } catch (UnknownTypeException e) {
2002:                                uex = e;
2003:                            }
2004:                            isExtended = true;
2005:                        }
2006:                    }
2007:                    if (!isExtended) {
2008:                        return defaultCanCut();
2009:                    }
2010:                    if (uex != null) {
2011:                        throw uex;
2012:                    } else {
2013:                        throw new UnknownTypeException(node);
2014:                    }
2015:                }
2016:
2017:                public Transferable clipboardCopy(Object node)
2018:                        throws IOException, UnknownTypeException {
2019:                    UnknownTypeException uex = null;
2020:                    NodeModel model = classNameToModel.get(node.getClass()
2021:                            .getName());
2022:                    if (model != null) {
2023:                        if (model instanceof  ExtendedNodeModel) {
2024:                            try {
2025:                                return ((ExtendedNodeModel) model)
2026:                                        .clipboardCopy(node);
2027:                            } catch (UnknownTypeException e) {
2028:                                uex = e;
2029:                            }
2030:                        } else {
2031:                            return defaultClipboardCopy();
2032:                        }
2033:                    }
2034:                    int i, k = models.length;
2035:                    boolean isExtended = false;
2036:                    for (i = 0; i < k; i++) {
2037:                        if (models[i] instanceof  ExtendedNodeModel) {
2038:                            try {
2039:                                Transferable t = ((ExtendedNodeModel) models[i])
2040:                                        .clipboardCopy(node);
2041:                                classNameToModel.put(node.getClass().getName(),
2042:                                        models[i]);
2043:                                return t;
2044:                            } catch (UnknownTypeException e) {
2045:                                uex = e;
2046:                            }
2047:                            isExtended = true;
2048:                        }
2049:                    }
2050:                    if (!isExtended) {
2051:                        return defaultClipboardCopy();
2052:                    }
2053:                    if (uex != null) {
2054:                        throw uex;
2055:                    } else {
2056:                        throw new UnknownTypeException(node);
2057:                    }
2058:                }
2059:
2060:                public Transferable clipboardCut(Object node)
2061:                        throws IOException, UnknownTypeException {
2062:                    UnknownTypeException uex = null;
2063:                    NodeModel model = classNameToModel.get(node.getClass()
2064:                            .getName());
2065:                    if (model != null) {
2066:                        if (model instanceof  ExtendedNodeModel) {
2067:                            try {
2068:                                return ((ExtendedNodeModel) model)
2069:                                        .clipboardCut(node);
2070:                            } catch (UnknownTypeException e) {
2071:                                uex = e;
2072:                            }
2073:                        } else {
2074:                            return defaultClipboardCut();
2075:                        }
2076:                    }
2077:                    int i, k = models.length;
2078:                    boolean isExtended = false;
2079:                    for (i = 0; i < k; i++) {
2080:                        if (models[i] instanceof  ExtendedNodeModel) {
2081:                            try {
2082:                                Transferable t = ((ExtendedNodeModel) models[i])
2083:                                        .clipboardCut(node);
2084:                                classNameToModel.put(node.getClass().getName(),
2085:                                        models[i]);
2086:                                return t;
2087:                            } catch (UnknownTypeException e) {
2088:                                uex = e;
2089:                            }
2090:                            isExtended = true;
2091:                        }
2092:                    }
2093:                    if (!isExtended) {
2094:                        return defaultClipboardCut();
2095:                    }
2096:                    if (uex != null) {
2097:                        throw uex;
2098:                    } else {
2099:                        throw new UnknownTypeException(node);
2100:                    }
2101:                }
2102:
2103:                /*
2104:                public Transferable drag(Object node) throws IOException,
2105:                                                             UnknownTypeException {
2106:                    UnknownTypeException uex = null;
2107:                    NodeModel model = (NodeModel) classNameToModel.get (
2108:                        node.getClass ().getName ()
2109:                    );
2110:                    if (model != null) {
2111:                        if (model instanceof ExtendedNodeModel) {
2112:                            try {
2113:                                return ((ExtendedNodeModel) model).drag (node);
2114:                            } catch (UnknownTypeException e) {
2115:                                uex = e;
2116:                            }
2117:                        } else {
2118:                            return defaultDrag();
2119:                        }
2120:                    }
2121:                    int i, k = models.length;
2122:                    boolean isExtended = false;
2123:                    for (i = 0; i < k; i++) {
2124:                        if (models[i] instanceof ExtendedNodeModel) {
2125:                            try {
2126:                                Transferable t = ((ExtendedNodeModel) models [i]).drag (node);
2127:                                classNameToModel.put (node.getClass ().getName (), models [i]);
2128:                                return t;
2129:                            } catch (UnknownTypeException e) {
2130:                                uex = e;
2131:                            }
2132:                            isExtended = true;
2133:                        }
2134:                    }
2135:                    if (!isExtended) {
2136:                        return defaultDrag();
2137:                    }
2138:                    if (uex != null) {
2139:                        throw uex;
2140:                    } else {
2141:                        throw new UnknownTypeException (node);
2142:                    }
2143:                }
2144:                 */
2145:
2146:                public PasteType[] getPasteTypes(Object node, Transferable t)
2147:                        throws UnknownTypeException {
2148:                    UnknownTypeException uex = null;
2149:                    NodeModel model = classNameToModel.get(node.getClass()
2150:                            .getName());
2151:                    if (model != null) {
2152:                        if (model instanceof  ExtendedNodeModel) {
2153:                            try {
2154:                                return ((ExtendedNodeModel) model)
2155:                                        .getPasteTypes(node, t);
2156:                            } catch (UnknownTypeException e) {
2157:                                uex = e;
2158:                            }
2159:                        } else {
2160:                            return defaultGetPasteTypes(t);
2161:                        }
2162:                    }
2163:                    int i, k = models.length;
2164:                    boolean isExtended = false;
2165:                    for (i = 0; i < k; i++) {
2166:                        if (models[i] instanceof  ExtendedNodeModel) {
2167:                            try {
2168:                                PasteType[] p = ((ExtendedNodeModel) models[i])
2169:                                        .getPasteTypes(node, t);
2170:                                classNameToModel.put(node.getClass().getName(),
2171:                                        models[i]);
2172:                                return p;
2173:                            } catch (UnknownTypeException e) {
2174:                                uex = e;
2175:                            }
2176:                            isExtended = true;
2177:                        }
2178:                    }
2179:                    if (!isExtended) {
2180:                        return defaultGetPasteTypes(t);
2181:                    }
2182:                    if (uex != null) {
2183:                        throw uex;
2184:                    } else {
2185:                        throw new UnknownTypeException(node);
2186:                    }
2187:                }
2188:
2189:                /*
2190:                public PasteType getDropType(Object node, Transferable t, int action,
2191:                                             int index) throws UnknownTypeException {
2192:                    UnknownTypeException uex = null;
2193:                    NodeModel model = (NodeModel) classNameToModel.get (
2194:                        node.getClass ().getName ()
2195:                    );
2196:                    if (model != null) {
2197:                        if (model instanceof ExtendedNodeModel) {
2198:                            try {
2199:                                return ((ExtendedNodeModel) model).getDropType (node, t, action, index);
2200:                            } catch (UnknownTypeException e) {
2201:                                uex = e;
2202:                            }
2203:                        } else {
2204:                            return defaultGetDropType(t, action, index);
2205:                        }
2206:                    }
2207:                    int i, k = models.length;
2208:                    boolean isExtended = false;
2209:                    for (i = 0; i < k; i++) {
2210:                        if (models[i] instanceof ExtendedNodeModel) {
2211:                            try {
2212:                                PasteType p = ((ExtendedNodeModel) models [i]).getDropType (node, t, action, index);
2213:                                classNameToModel.put (node.getClass ().getName (), models [i]);
2214:                                return p;
2215:                            } catch (UnknownTypeException e) {
2216:                                uex = e;
2217:                            }
2218:                            isExtended = true;
2219:                        }
2220:                    }
2221:                    if (!isExtended) {
2222:                        return defaultGetDropType(t, action, index);
2223:                    }
2224:                    if (uex != null) {
2225:                        throw uex;
2226:                    } else {
2227:                        throw new UnknownTypeException (node);
2228:                    }
2229:                }
2230:                 */
2231:
2232:                public void setName(Object node, String name)
2233:                        throws UnknownTypeException {
2234:                    UnknownTypeException uex = null;
2235:                    NodeModel model = classNameToModel.get(node.getClass()
2236:                            .getName());
2237:                    if (model != null) {
2238:                        if (model instanceof  ExtendedNodeModel) {
2239:                            try {
2240:                                ((ExtendedNodeModel) model).setName(node, name);
2241:                                return;
2242:                            } catch (UnknownTypeException e) {
2243:                                uex = e;
2244:                            }
2245:                        } else {
2246:                            defaultSetName(name);
2247:                            return;
2248:                        }
2249:                    }
2250:                    int i, k = models.length;
2251:                    boolean isExtended = false;
2252:                    for (i = 0; i < k; i++) {
2253:                        if (models[i] instanceof  ExtendedNodeModel) {
2254:                            try {
2255:                                ((ExtendedNodeModel) models[i]).setName(node,
2256:                                        name);
2257:                                classNameToModel.put(node.getClass().getName(),
2258:                                        models[i]);
2259:                                return;
2260:                            } catch (UnknownTypeException e) {
2261:                                uex = e;
2262:                            }
2263:                            isExtended = true;
2264:                        }
2265:                    }
2266:                    if (!isExtended) {
2267:                        defaultSetName(name);
2268:                        return;
2269:                    }
2270:                    if (uex != null) {
2271:                        throw uex;
2272:                    } else {
2273:                        throw new UnknownTypeException(node);
2274:                    }
2275:                }
2276:
2277:                public String getIconBaseWithExtension(Object node)
2278:                        throws UnknownTypeException {
2279:                    UnknownTypeException uex = null;
2280:                    NodeModel model = classNameToModel.get(node.getClass()
2281:                            .getName());
2282:                    if (model != null) {
2283:                        try {
2284:                            if (model instanceof  ExtendedNodeModel) {
2285:                                return ((ExtendedNodeModel) model)
2286:                                        .getIconBaseWithExtension(node);
2287:                            } else {
2288:                                String base = model.getIconBase(node);
2289:                                if (base != null) {
2290:                                    return base + ".gif";
2291:                                } else {
2292:                                    return null;
2293:                                }
2294:                            }
2295:                        } catch (UnknownTypeException e) {
2296:                            uex = e;
2297:                        }
2298:                    }
2299:                    int i, k = models.length;
2300:                    for (i = 0; i < k; i++) {
2301:                        try {
2302:                            String ib;
2303:                            if (models[i] instanceof  ExtendedNodeModel) {
2304:                                ib = ((ExtendedNodeModel) models[i])
2305:                                        .getIconBaseWithExtension(node);
2306:                            } else {
2307:                                String base = models[i].getIconBase(node);
2308:                                if (base != null) {
2309:                                    ib = base + ".gif";
2310:                                } else {
2311:                                    ib = null;
2312:                                }
2313:                            }
2314:                            classNameToModel.put(node.getClass().getName(),
2315:                                    models[i]);
2316:                            return ib;
2317:                        } catch (UnknownTypeException e) {
2318:                            uex = e;
2319:                        }
2320:                    }
2321:                    if (uex != null) {
2322:                        throw uex;
2323:                    } else {
2324:                        throw new UnknownTypeException(node);
2325:                    }
2326:
2327:                }
2328:            }
2329:
2330:            /**
2331:             * Empty impleemntation of {@link org.netbeans.spi.viewmodel.TreeModel}.
2332:             *
2333:             * @author   Jan Jancura
2334:             */
2335:            private static final class EmptyTreeModel implements  TreeModel {
2336:
2337:                /** 
2338:                 * Returns {@link org.netbeans.spi.viewmodel.TreeModel#ROOT}.
2339:                 *
2340:                 * @return {@link org.netbeans.spi.viewmodel.TreeModel#ROOT}
2341:                 */
2342:                public Object getRoot() {
2343:                    return ROOT;
2344:                }
2345:
2346:                /** 
2347:                 * Returns empty array.
2348:                 *
2349:                 * @return empty array
2350:                 */
2351:                public Object[] getChildren(Object parent, int from, int to) {
2352:                    return new Object[0];
2353:                }
2354:
2355:                /**
2356:                 * Returns number of children for given node.
2357:                 * 
2358:                 * @param   node the parent node
2359:                 * @throws  UnknownTypeException if this TreeModel implementation is not
2360:                 *          able to resolve children for given node type
2361:                 *
2362:                 * @return  true if node is leaf
2363:                 */
2364:                public int getChildrenCount(Object node) {
2365:                    return 0;
2366:                }
2367:
2368:                /**
2369:                 * Returns false.
2370:                 *
2371:                 * @return false
2372:                 */
2373:                public boolean isLeaf(Object node) {
2374:                    return false;
2375:                }
2376:
2377:                /** 
2378:                 * Do nothing.
2379:                 *
2380:                 * @param l the listener to be added
2381:                 */
2382:                public void addModelListener(ModelListener l) {
2383:                }
2384:
2385:                /** 
2386:                 * Do nothing.
2387:                 *
2388:                 * @param l the listener to be removed
2389:                 */
2390:                public void removeModelListener(ModelListener l) {
2391:                }
2392:            }
2393:
2394:            /**
2395:             * Empty impleemntation of {@link org.netbeans.spi.viewmodel.NodeModel}.
2396:             *
2397:             * @author   Jan Jancura
2398:             */
2399:            private static final class EmptyNodeModel implements  NodeModel {
2400:
2401:                /**
2402:                 * Returns display name for given node.
2403:                 *
2404:                 * @throws  UnknownTypeException if this NodeModel implementation is not
2405:                 *          able to resolve display name for given node type
2406:                 * @return  display name for given node
2407:                 */
2408:                public String getDisplayName(Object node)
2409:                        throws UnknownTypeException {
2410:                    throw new UnknownTypeException(node);
2411:                }
2412:
2413:                /**
2414:                 * Returns icon for given node.
2415:                 *
2416:                 * @throws  UnknownTypeException if this NodeModel implementation is not
2417:                 *          able to resolve icon for given node type
2418:                 * @return  icon for given node
2419:                 */
2420:                public String getIconBase(Object node)
2421:                        throws UnknownTypeException {
2422:                    throw new UnknownTypeException(node);
2423:                }
2424:
2425:                /**
2426:                 * Returns tooltip for given node.
2427:                 *
2428:                 * @throws  UnknownTypeException if this NodeModel implementation is not
2429:                 *          able to resolve tooltip for given node type
2430:                 * @return  tooltip for given node
2431:                 */
2432:                public String getShortDescription(Object node)
2433:                        throws UnknownTypeException {
2434:                    throw new UnknownTypeException(node);
2435:                }
2436:
2437:                /** 
2438:                 * Do nothing.
2439:                 *
2440:                 * @param l the listener to be added
2441:                 */
2442:                public void addModelListener(ModelListener l) {
2443:                }
2444:
2445:                /** 
2446:                 * Do nothing.
2447:                 *
2448:                 * @param l the listener to be removed
2449:                 */
2450:                public void removeModelListener(ModelListener l) {
2451:                }
2452:            }
2453:
2454:            /**
2455:             * Empty impleemntation of {@link org.netbeans.spi.viewmodel.TableModel}.
2456:             *
2457:             * @author   Jan Jancura
2458:             */
2459:            private static final class EmptyTableModel implements  TableModel {
2460:
2461:                /**
2462:                 * Returns value to be displayed in column <code>columnID</code>
2463:                 * and row identified by <code>node</code>. Column ID is defined in by 
2464:                 * {@link ColumnModel#getID}, and rows are defined by values returned from 
2465:                 * {@link org.netbeans.spi.viewmodel.TreeModel#getChildren}.
2466:                 *
2467:                 * @param node a object returned from 
2468:                 *         {@link org.netbeans.spi.viewmodel.TreeModel#getChildren} for this row
2469:                 * @param columnID a id of column defined by {@link ColumnModel#getID}
2470:                 * @throws UnknownTypeException if there is no TableModel defined for given
2471:                 *         parameter type
2472:                 *
2473:                 * @return value of variable representing given position in tree table.
2474:                 */
2475:                public Object getValueAt(Object node, String columnID)
2476:                        throws UnknownTypeException {
2477:                    throw new UnknownTypeException(node);
2478:                }
2479:
2480:                /**
2481:                 * Returns true if value displayed in column <code>columnID</code>
2482:                 * and row <code>node</code> is read only. Column ID is defined in by 
2483:                 * {@link ColumnModel#getID}, and rows are defined by values returned from 
2484:                 * {@link TreeModel#getChildren}.
2485:                 *
2486:                 * @param node a object returned from {@link TreeModel#getChildren} for this row
2487:                 * @param columnID a id of column defined by {@link ColumnModel#getID}
2488:                 * @throws UnknownTypeException if there is no TableModel defined for given
2489:                 *         parameter type
2490:                 *
2491:                 * @return true if variable on given position is read only
2492:                 */
2493:                public boolean isReadOnly(Object node, String columnID)
2494:                        throws UnknownTypeException {
2495:                    throw new UnknownTypeException(node);
2496:                }
2497:
2498:                /**
2499:                 * Changes a value displayed in column <code>columnID</code>
2500:                 * and row <code>node</code>. Column ID is defined in by 
2501:                 * {@link ColumnModel#getID}, and rows are defined by values returned from 
2502:                 * {@link TreeModel#getChildren}.
2503:                 *
2504:                 * @param node a object returned from {@link TreeModel#getChildren} for this row
2505:                 * @param columnID a id of column defined by {@link ColumnModel#getID}
2506:                 * @param value a new value of variable on given position
2507:                 * @throws UnknownTypeException if there is no TableModel defined for given
2508:                 *         parameter type
2509:                 */
2510:                public void setValueAt(Object node, String columnID,
2511:                        Object value) throws UnknownTypeException {
2512:                    throw new UnknownTypeException(node);
2513:                }
2514:
2515:                /** 
2516:                 * Do nothing.
2517:                 *
2518:                 * @param l the listener to be added
2519:                 */
2520:                public void addModelListener(ModelListener l) {
2521:                }
2522:
2523:                /** 
2524:                 * Do nothing.
2525:                 *
2526:                 * @param l the listener to be removed
2527:                 */
2528:                public void removeModelListener(ModelListener l) {
2529:                }
2530:            }
2531:
2532:            /**
2533:             * Empty impleemntation of {@link org.netbeans.spi.viewmodel.TableModel}.
2534:             *
2535:             * @author   Jan Jancura
2536:             */
2537:            private static final class EmptyNodeActionsProvider implements 
2538:                    NodeActionsProvider {
2539:
2540:                /**
2541:                 * Performs default action for given node.
2542:                 *
2543:                 * @throws  UnknownTypeException if this NodeActionsProvider implementation 
2544:                 *          is not able to resolve actions for given node type
2545:                 * @return  display name for given node
2546:                 */
2547:                public void performDefaultAction(Object node)
2548:                        throws UnknownTypeException {
2549:                    throw new UnknownTypeException(node);
2550:                }
2551:
2552:                /**
2553:                 * Returns set of actions for given node.
2554:                 *
2555:                 * @throws  UnknownTypeException if this NodeActionsProvider implementation 
2556:                 *          is not able to resolve actions for given node type
2557:                 * @return  display name for given node
2558:                 */
2559:                public Action[] getActions(Object node)
2560:                        throws UnknownTypeException {
2561:                    throw new UnknownTypeException(node);
2562:                }
2563:            }
2564:
2565:            /**
2566:             * Creates one {@link org.netbeans.spi.viewmodel.NodeActionsProvider}
2567:             * from given list of NodeActionsProviders. DelegatingNodeActionsProvider asks all 
2568:             * underlaying models for each concrete parameter, and returns first 
2569:             * returned value.
2570:             *
2571:             * @author   Jan Jancura
2572:             */
2573:            static final class DelegatingNodeActionsProvider implements 
2574:                    NodeActionsProvider {
2575:
2576:                private NodeActionsProvider[] models;
2577:                private HashMap<String, NodeActionsProvider> classNameToModel = new HashMap<String, NodeActionsProvider>();
2578:
2579:                /**
2580:                 * Creates new instance of DelegatingNodeActionsProvider for given list of 
2581:                 * NodeActionsProvider.
2582:                 *
2583:                 * @param models a list of NodeActionsProvider
2584:                 */
2585:                public DelegatingNodeActionsProvider(
2586:                        List<NodeActionsProvider> models) {
2587:                    this (convert(models));
2588:                }
2589:
2590:                private static NodeActionsProvider[] convert(
2591:                        List<NodeActionsProvider> l) {
2592:                    NodeActionsProvider[] models = new NodeActionsProvider[l
2593:                            .size()];
2594:                    return l.toArray(models);
2595:                }
2596:
2597:                /**
2598:                 * Creates new instance of DelegatingNodeActionsProvider for given array of 
2599:                 * NodeActionsProvider.
2600:                 *
2601:                 * @param models a array of NodeActionsProvider
2602:                 */
2603:                public DelegatingNodeActionsProvider(
2604:                        NodeActionsProvider[] models) {
2605:                    this .models = models;
2606:                }
2607:
2608:                /**
2609:                 * Returns set of actions for given node.
2610:                 *
2611:                 * @throws  UnknownTypeException if this NodeActionsProvider implementation 
2612:                 *          is not able to resolve actions for given node type
2613:                 * @return  display name for given node
2614:                 */
2615:                public Action[] getActions(Object node)
2616:                        throws UnknownTypeException {
2617:                    NodeActionsProvider model = classNameToModel.get(node
2618:                            .getClass().getName());
2619:                    if (model != null)
2620:                        try {
2621:                            return model.getActions(node);
2622:                        } catch (UnknownTypeException e) {
2623:                        }
2624:                    int i, k = models.length;
2625:                    for (i = 0; i < k; i++) {
2626:                        try {
2627:                            Action[] dn = models[i].getActions(node);
2628:                            classNameToModel.put(node.getClass().getName(),
2629:                                    models[i]);
2630:                            return dn;
2631:                        } catch (UnknownTypeException e) {
2632:                        }
2633:                    }
2634:                    throw new UnknownTypeException(node);
2635:                }
2636:
2637:                /**
2638:                 * Performs default action for given node.
2639:                 *
2640:                 * @throws  UnknownTypeException if this NodeActionsProvider implementation 
2641:                 *          is not able to resolve actions for given node type
2642:                 * @return  display name for given node
2643:                 */
2644:                public void performDefaultAction(Object node)
2645:                        throws UnknownTypeException {
2646:                    NodeActionsProvider model = classNameToModel.get(node
2647:                            .getClass().getName());
2648:                    if (model != null)
2649:                        try {
2650:                            model.performDefaultAction(node);
2651:                            return;
2652:                        } catch (UnknownTypeException e) {
2653:                        }
2654:                    int i, k = models.length;
2655:                    for (i = 0; i < k; i++) {
2656:                        try {
2657:                            models[i].performDefaultAction(node);
2658:                            classNameToModel.put(node.getClass().getName(),
2659:                                    models[i]);
2660:                            return;
2661:                        } catch (UnknownTypeException e) {
2662:                        }
2663:                    }
2664:                    throw new UnknownTypeException(node);
2665:                }
2666:
2667:                public String toString() {
2668:                    return super .toString() + "\n" + toString("    ");
2669:                }
2670:
2671:                public String toString(String n) {
2672:                    int i, k = models.length - 1;
2673:                    if (k == -1)
2674:                        return "";
2675:                    StringBuffer sb = new StringBuffer();
2676:                    for (i = 0; i < k; i++) {
2677:                        sb.append(n);
2678:                        sb.append(models[i]);
2679:                        sb.append('\n');
2680:                    }
2681:                    sb.append(n);
2682:                    sb.append(models[i]);
2683:                    return new String(sb);
2684:                }
2685:            }
2686:
2687:            /**
2688:             * Implements set of tree view features.
2689:             */
2690:            public static final class TreeFeatures {
2691:
2692:                private JComponent view;
2693:
2694:                private TreeFeatures(JComponent view) {
2695:                    this .view = view;
2696:                }
2697:
2698:                /**
2699:                 * Returns <code>true</code> if given node is expanded.
2700:                 *
2701:                 * @param node a node to be checked
2702:                 * @return <code>true</code> if given node is expanded
2703:                 */
2704:                public boolean isExpanded(Object node) {
2705:                    return ((TreeTable) view).isExpanded(node);
2706:                }
2707:
2708:                /**
2709:                 * Expands given list of nodes.
2710:                 *
2711:                 * @param node a list of nodes to be expanded
2712:                 */
2713:                public void expandNode(Object node) {
2714:                    ((TreeTable) view).expandNode(node);
2715:                }
2716:
2717:                /**
2718:                 * Collapses given node.
2719:                 *
2720:                 * @param node a node to be expanded
2721:                 */
2722:                public void collapseNode(Object node) {
2723:                    ((TreeTable) view).collapseNode(node);
2724:                }
2725:            }
2726:
2727:            /**
2728:             * This model encapsulates all currently supported models.
2729:             *
2730:             * @see Models#createCompoundModel
2731:             * @author   Jan Jancura
2732:             */
2733:            public static final class CompoundModel implements  TreeModel,
2734:                    ExtendedNodeModel, NodeActionsProvider, TableModel,
2735:                    TreeExpansionModel {
2736:
2737:                private TreeModel treeModel;
2738:                private ExtendedNodeModel nodeModel;
2739:                private NodeActionsProvider nodeActionsProvider;
2740:                private ColumnModel[] columnModels;
2741:                private TableModel tableModel;
2742:                private TreeExpansionModel treeExpansionModel;
2743:
2744:                // <RAVE>
2745:                // New field, setter/getter for propertiesHelpID, which is used
2746:                // for property sheet help
2747:                private String propertiesHelpID = null;
2748:
2749:                // </RAVE>
2750:
2751:                // init ....................................................................
2752:
2753:                /**
2754:                 * Creates a new instance of {@link CompoundModel} for given models.
2755:                 *
2756:                 * @param treeModel a tree model to delegate on
2757:                 * @param nodeModel a node model to delegate on
2758:                 * @param nodeActionsProvider a node actions provider to delegate on
2759:                 * @param nodeActionsProvider a columns modeol to delegate on
2760:                 */
2761:                private CompoundModel(TreeModel treeModel,
2762:                        TreeExpansionModel treeExpansionModel,
2763:                        ExtendedNodeModel nodeModel,
2764:                        NodeActionsProvider nodeActionsProvider,
2765:                        List<ColumnModel> columnModels, TableModel tableModel,
2766:                        String propertiesHelpID) {
2767:                    if (treeModel == null)
2768:                        throw new NullPointerException();
2769:                    if (treeModel == null)
2770:                        throw new NullPointerException();
2771:                    if (nodeModel == null)
2772:                        throw new NullPointerException();
2773:                    if (tableModel == null)
2774:                        throw new NullPointerException();
2775:                    if (nodeActionsProvider == null)
2776:                        throw new NullPointerException();
2777:
2778:                    this .treeModel = treeModel;
2779:                    this .treeExpansionModel = treeExpansionModel;
2780:                    this .nodeModel = nodeModel;
2781:                    this .tableModel = tableModel;
2782:                    this .nodeActionsProvider = nodeActionsProvider;
2783:                    this .columnModels = columnModels
2784:                            .toArray(new ColumnModel[columnModels.size()]);
2785:                    this .propertiesHelpID = propertiesHelpID;
2786:                }
2787:
2788:                // <RAVE>
2789:                /**
2790:                 * Get a help ID for this model.
2791:                 * @return The help ID defined for the properties sheets,
2792:                 *         or <code>null</code>.
2793:                 * @since 1.7
2794:                 */
2795:                public String getHelpId() {
2796:                    return propertiesHelpID;
2797:                }
2798:
2799:                // </RAVE>
2800:
2801:                // TreeModel ...............................................................
2802:
2803:                /** 
2804:                 * Returns the root node of the tree or null, if the tree is empty.
2805:                 *
2806:                 * @return the root node of the tree or null
2807:                 */
2808:                public Object getRoot() {
2809:                    return treeModel.getRoot();
2810:                }
2811:
2812:                /** 
2813:                 * Returns children for given parent on given indexes.
2814:                 *
2815:                 * @param   parent a parent of returned nodes
2816:                 * @throws  UnknownTypeException if this TreeModel implementation is not
2817:                 *          able to resolve dchildren for given node type
2818:                 *
2819:                 * @return  children for given parent on given indexes
2820:                 */
2821:                public Object[] getChildren(Object parent, int from, int to)
2822:                        throws UnknownTypeException {
2823:                    return treeModel.getChildren(parent, from, to);
2824:                }
2825:
2826:                /**
2827:                 * Returns number of children for given node.
2828:                 * 
2829:                 * @param   node the parent node
2830:                 * @throws  UnknownTypeException if this TreeModel implementation is not
2831:                 *          able to resolve children for given node type
2832:                 *
2833:                 * @return  true if node is leaf
2834:                 */
2835:                public int getChildrenCount(Object node)
2836:                        throws UnknownTypeException {
2837:                    return treeModel.getChildrenCount(node);
2838:                }
2839:
2840:                /**
2841:                 * Returns true if node is leaf.
2842:                 * 
2843:                 * @throws  UnknownTypeException if this TreeModel implementation is not
2844:                 *          able to resolve dchildren for given node type
2845:                 * @return  true if node is leaf
2846:                 */
2847:                public boolean isLeaf(Object node) throws UnknownTypeException {
2848:                    return treeModel.isLeaf(node);
2849:                }
2850:
2851:                // NodeModel ...............................................................
2852:
2853:                /**
2854:                 * Returns display name for given node.
2855:                 *
2856:                 * @throws  UnknownTypeException if this NodeModel implementation is not
2857:                 *          able to resolve display name for given node type
2858:                 * @return  display name for given node
2859:                 */
2860:                public String getDisplayName(Object node)
2861:                        throws UnknownTypeException {
2862:                    if (nodeModel instanceof  DelegatingNodeModel) {
2863:                        NodeModel[] subModels = ((DelegatingNodeModel) nodeModel)
2864:                                .getModels();
2865:                        if (subModels.length == 0) {
2866:                            if (TreeModel.ROOT.equals(node)) {
2867:                                ColumnModel[] columns = getColumns();
2868:                                for (ColumnModel cm : columns) {
2869:                                    if (cm.getType() == null) {
2870:                                        return cm.getDisplayName();
2871:                                    }
2872:                                }
2873:                            }
2874:                            return ""; // Nothing when there are no models
2875:                        }
2876:                    }
2877:                    return nodeModel.getDisplayName(node);
2878:                }
2879:
2880:                /**
2881:                 * Returns tooltip for given node.
2882:                 *
2883:                 * @throws  UnknownTypeException if this NodeModel implementation is not
2884:                 *          able to resolve tooltip for given node type
2885:                 * @return  tooltip for given node
2886:                 */
2887:                public String getShortDescription(Object node)
2888:                        throws UnknownTypeException {
2889:                    if (nodeModel instanceof  DelegatingNodeModel) {
2890:                        NodeModel[] subModels = ((DelegatingNodeModel) nodeModel)
2891:                                .getModels();
2892:                        if (subModels.length == 0) {
2893:                            if (TreeModel.ROOT.equals(node)) {
2894:                                ColumnModel[] columns = getColumns();
2895:                                for (ColumnModel cm : columns) {
2896:                                    if (cm.getType() == null) {
2897:                                        return cm.getShortDescription();
2898:                                    }
2899:                                }
2900:                            }
2901:                        }
2902:                    }
2903:                    return nodeModel.getShortDescription(node);
2904:                }
2905:
2906:                /**
2907:                 * Returns icon for given node.
2908:                 *
2909:                 * @throws  UnknownTypeException if this NodeModel implementation is not
2910:                 *          able to resolve icon for given node type
2911:                 * @return  icon for given node
2912:                 */
2913:                public String getIconBase(Object node)
2914:                        throws UnknownTypeException {
2915:                    if (nodeModel instanceof  DelegatingNodeModel) {
2916:                        NodeModel[] subModels = ((DelegatingNodeModel) nodeModel)
2917:                                .getModels();
2918:                        if (subModels.length == 0) {
2919:                            return null; // Nothing when there are no models
2920:                        }
2921:                    }
2922:                    return nodeModel.getIconBase(node);
2923:                }
2924:
2925:                // NodeActionsProvider .....................................................
2926:
2927:                /**
2928:                 * Performs default action for given node.
2929:                 *
2930:                 * @throws  UnknownTypeException if this NodeActionsProvider implementation 
2931:                 *          is not able to resolve actions for given node type
2932:                 * @return  display name for given node
2933:                 */
2934:                public void performDefaultAction(Object node)
2935:                        throws UnknownTypeException {
2936:                    nodeActionsProvider.performDefaultAction(node);
2937:                }
2938:
2939:                /**
2940:                 * Returns set of actions for given node.
2941:                 *
2942:                 * @throws  UnknownTypeException if this NodeActionsProvider implementation 
2943:                 *          is not able to resolve actions for given node type
2944:                 * @return  display name for given node
2945:                 */
2946:                public Action[] getActions(Object node)
2947:                        throws UnknownTypeException {
2948:                    return nodeActionsProvider.getActions(node);
2949:                }
2950:
2951:                // ColumnsModel ............................................................
2952:
2953:                /**
2954:                 * Returns sorted array of 
2955:                 * {@link org.netbeans.spi.viewmodel.ColumnModel}s.
2956:                 *
2957:                 * @return sorted array of ColumnModels
2958:                 */
2959:                public ColumnModel[] getColumns() {
2960:                    return columnModels;
2961:                }
2962:
2963:                // TableModel ..............................................................
2964:
2965:                public Object getValueAt(Object node, String columnID)
2966:                        throws UnknownTypeException {
2967:                    return tableModel.getValueAt(node, columnID);
2968:                }
2969:
2970:                public boolean isReadOnly(Object node, String columnID)
2971:                        throws UnknownTypeException {
2972:                    return tableModel.isReadOnly(node, columnID);
2973:                }
2974:
2975:                public void setValueAt(Object node, String columnID,
2976:                        Object value) throws UnknownTypeException {
2977:                    tableModel.setValueAt(node, columnID, value);
2978:                }
2979:
2980:                // TreeExpansionModel ......................................................
2981:
2982:                /**
2983:                 * Defines default state (collapsed, expanded) of given node.
2984:                 *
2985:                 * @param node a node
2986:                 * @return default state (collapsed, expanded) of given node
2987:                 */
2988:                public boolean isExpanded(Object node)
2989:                        throws UnknownTypeException {
2990:                    if (treeExpansionModel == null)
2991:                        return false;
2992:                    return treeExpansionModel.isExpanded(node);
2993:                }
2994:
2995:                /**
2996:                 * Called when given node is expanded.
2997:                 *
2998:                 * @param node a expanded node
2999:                 */
3000:                public void nodeExpanded(Object node) {
3001:                    if (treeExpansionModel != null)
3002:                        treeExpansionModel.nodeExpanded(node);
3003:                }
3004:
3005:                /**
3006:                 * Called when given node is collapsed.
3007:                 *
3008:                 * @param node a collapsed node
3009:                 */
3010:                public void nodeCollapsed(Object node) {
3011:                    if (treeExpansionModel != null)
3012:                        treeExpansionModel.nodeCollapsed(node);
3013:                }
3014:
3015:                // listeners ...............................................................
3016:
3017:                /** 
3018:                 * Registers given listener.
3019:                 * 
3020:                 * @param l the listener to add
3021:                 */
3022:                public void addModelListener(ModelListener l) {
3023:                    treeModel.addModelListener(l);
3024:                    if (nodeModel != treeModel) {
3025:                        nodeModel.addModelListener(l);
3026:                    }
3027:                    if (tableModel != treeModel && tableModel != nodeModel) {
3028:                        tableModel.addModelListener(l);
3029:                    }
3030:                }
3031:
3032:                /** 
3033:                 * Unregisters given listener.
3034:                 *
3035:                 * @param l the listener to remove
3036:                 */
3037:                public void removeModelListener(ModelListener l) {
3038:                    treeModel.removeModelListener(l);
3039:                    if (nodeModel != treeModel) {
3040:                        nodeModel.removeModelListener(l);
3041:                    }
3042:                    if (tableModel != treeModel && tableModel != nodeModel) {
3043:                        tableModel.removeModelListener(l);
3044:                    }
3045:                }
3046:
3047:                public String toString() {
3048:                    return super .toString() + "\n  TreeModel = " + treeModel
3049:                            + "\n  NodeModel = " + nodeModel
3050:                            + "\n  TableModel = " + tableModel
3051:                            + "\n  NodeActionsProvider = "
3052:                            + nodeActionsProvider + "\n  ColumnsModel = "
3053:                            + java.util.Arrays.asList(columnModels);
3054:                }
3055:
3056:                // ExtendedNodeModel
3057:
3058:                public boolean canRename(Object node)
3059:                        throws UnknownTypeException {
3060:                    return nodeModel.canRename(node);
3061:                }
3062:
3063:                public boolean canCopy(Object node) throws UnknownTypeException {
3064:                    return nodeModel.canCopy(node);
3065:                }
3066:
3067:                public boolean canCut(Object node) throws UnknownTypeException {
3068:                    return nodeModel.canCut(node);
3069:                }
3070:
3071:                public Transferable clipboardCopy(Object node)
3072:                        throws IOException, UnknownTypeException {
3073:                    return nodeModel.clipboardCopy(node);
3074:                }
3075:
3076:                public Transferable clipboardCut(Object node)
3077:                        throws IOException, UnknownTypeException {
3078:                    return nodeModel.clipboardCut(node);
3079:                }
3080:
3081:                /*
3082:                public Transferable drag(Object node) throws IOException,
3083:                                                             UnknownTypeException {
3084:                    return nodeModel.drag(node);
3085:                }
3086:                 */
3087:
3088:                public PasteType[] getPasteTypes(Object node, Transferable t)
3089:                        throws UnknownTypeException {
3090:                    return nodeModel.getPasteTypes(node, t);
3091:                }
3092:
3093:                /*
3094:                public PasteType getDropType(Object node, Transferable t, int action,
3095:                                             int index) throws UnknownTypeException {
3096:                    return nodeModel.getDropType(node, t, action, index);
3097:                }
3098:                 */
3099:
3100:                public void setName(Object node, String name)
3101:                        throws UnknownTypeException {
3102:                    nodeModel.setName(node, name);
3103:                }
3104:
3105:                public String getIconBaseWithExtension(Object node)
3106:                        throws UnknownTypeException {
3107:                    return nodeModel.getIconBaseWithExtension(node);
3108:                }
3109:            }
3110:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.