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: /*
0043: *
0044: * Created on Jun 10, 2003
0045: * @author Trey Spiva
0046: */
0047: package org.netbeans.modules.uml.ui.swing.projecttree;
0048:
0049: import java.util.ArrayList;
0050: import java.util.Comparator;
0051: import java.util.Iterator;
0052:
0053: import javax.swing.JTree;
0054: import javax.swing.SwingUtilities;
0055: import javax.swing.event.TreeModelEvent;
0056: import javax.swing.event.TreeModelListener;
0057: import javax.swing.tree.DefaultMutableTreeNode;
0058: import javax.swing.tree.TreePath;
0059:
0060: import org.netbeans.modules.uml.ui.controls.projecttree.DefaultNodeFactory;
0061: import org.netbeans.modules.uml.ui.controls.projecttree.IProjectTreeControl;
0062: import org.netbeans.modules.uml.ui.controls.projecttree.IProjectTreeEngine;
0063: import org.netbeans.modules.uml.ui.controls.projecttree.IProjectTreeItem;
0064: import org.netbeans.modules.uml.ui.controls.projecttree.IProjectTreeModelListener;
0065: import org.netbeans.modules.uml.ui.controls.projecttree.ProjectTreeItemImpl;
0066: import org.netbeans.modules.uml.ui.controls.projecttree.ProjectTreeModelEvent;
0067: import org.netbeans.modules.uml.ui.controls.projecttree.ProjectTreeNode;
0068: import org.netbeans.modules.uml.ui.controls.projecttree.ProjectTreeNodeFactory;
0069: import org.netbeans.modules.uml.ui.controls.projecttree.TreeElementNode;
0070: import org.netbeans.modules.uml.ui.support.ProductHelper;
0071: import org.netbeans.modules.uml.ui.support.projecttreesupport.ITreeElement;
0072: import org.netbeans.modules.uml.ui.support.projecttreesupport.ITreeItem;
0073: import org.netbeans.modules.uml.ui.support.projecttreesupport.ProjectTreeComparable;
0074: import org.netbeans.modules.uml.core.IApplication;
0075: import org.netbeans.modules.uml.core.coreapplication.ICoreProduct;
0076: import org.netbeans.modules.uml.core.metamodel.core.foundation.IElement;
0077: import org.netbeans.modules.uml.core.metamodel.structure.IProject;
0078: import org.netbeans.modules.uml.core.support.umlutils.DataFormatter;
0079: import org.netbeans.modules.uml.core.support.umlutils.ETArrayList;
0080: import org.netbeans.modules.uml.core.support.umlutils.ETList;
0081: import org.netbeans.modules.uml.core.support.umlutils.IDataFormatter;
0082: import org.netbeans.modules.uml.core.support.umlutils.InvalidArguments;
0083: import org.netbeans.modules.uml.core.workspacemanagement.IWSProject;
0084: import org.netbeans.modules.uml.core.workspacemanagement.IWorkspace;
0085: import javax.swing.tree.TreeNode;
0086: import org.netbeans.modules.uml.ui.controls.projecttree.ProjectTreeModelAdapter;
0087:
0088: /**
0089: * The Swing implementation of the project tree model. The
0090: * <code>ProductProjectTreeModel</code> contains the bussiness logic required
0091: * to maintain the project tree data. The <code>ProjectTreeSwingModel</code>
0092: * implements the Swing TreeModel interface.
0093: *
0094: * @see ProjectTreeSwingModel
0095: * @author Trey Spiva
0096: */
0097: public class DesignCenterSwingModel extends ProjectTreeModelAdapter
0098: implements ISwingProjectTreeModel {
0099: /** The list of tree listeners to notify when an event occurs. */
0100: private ArrayList<TreeModelListener> m_ModelListeners = new ArrayList<TreeModelListener>();
0101: public static String DESIGN_CENTER_NAME = ProjectTreeResources
0102: .getString("DesignCenterSwingModel.Design_Center_DisplayName"); //$NON-NLS-1$
0103: public static String DESIGN_CENTER_DESCRIPTION = ProjectTreeResources
0104: .getString("DesignCenterSwingModel.Design_Center_Description"); //$NON-NLS-1$
0105:
0106: /** The product to use that specifies the tree structure.*/
0107: private ICoreProduct m_Product = null;
0108:
0109: /** A table of the projects that are open. */
0110: //private HashMap < String, IProject > m_ProjectList = new HashMap < String, IProject >();
0111: protected ProjectTreeNode m_TreeRoot = null;
0112:
0113: /** The collection of project tree engines that are used by the model. */
0114: private ArrayList<IProjectTreeEngine> m_TreeEngines = new ArrayList<IProjectTreeEngine>();
0115:
0116: /** The collection of project tree engines that are used by the model. */
0117: private ArrayList<IProjectTreeModelListener> m_Listeners = new ArrayList<IProjectTreeModelListener>();
0118:
0119: /** The data that populates the project tree. */
0120: //private IProjectTreeModel m_ProjectTreeData = null;
0121: private ProjectTreeNodeFactory m_Factory = new DefaultNodeFactory();
0122:
0123: public DesignCenterSwingModel(ICoreProduct product) {
0124: initialize();
0125: setProduct(product);
0126: }
0127:
0128: public DesignCenterSwingModel() {
0129: }
0130:
0131: /**
0132: * Retreives the project tree model name. The model name can be used to
0133: * determine the type of project tree that is being displayed.
0134: */
0135: public String getModelName() {
0136: return "DesignCenter"; //$NON-NLS-1$
0137: }
0138:
0139: /**
0140: * Retrieves the node factory to use when creating nodes for the model.
0141: *
0142: * @return The factory to use.
0143: */
0144: public ProjectTreeNodeFactory getNodeFactory() {
0145: return m_Factory;
0146: }
0147:
0148: /**
0149: * Retrieves the collection of TreeModelListeners that are reqistered
0150: * with the model.
0151: *
0152: * @return The tree modeled listeners.
0153: */
0154: //protected ArrayList getModelListeners()
0155: protected ArrayList<TreeModelListener> getModelListeners() {
0156: return m_ModelListeners;
0157: }
0158:
0159: public IProjectTreeEngine getFirstEngine() {
0160: return m_TreeEngines.get(0);
0161: }
0162:
0163: //**************************************************
0164: // ISwingProjectTreeModel Implmentation
0165: //**************************************************
0166:
0167: /* (non-Javadoc)
0168: * @see org.netbeans.modules.uml.ui.swing.projecttree.ISwingProjectTreeModel#getTreeItem(javax.swing.tree.TreePath)
0169: */
0170: public ITreeItem getTreeItem(TreePath path) {
0171: ITreeItem retVal = null;
0172:
0173: if (path.getLastPathComponent() != null) {
0174: if (path.getLastPathComponent() instanceof ITreeItem) {
0175: retVal = (ITreeItem) path.getLastPathComponent();
0176: }
0177: }
0178:
0179: return retVal;
0180: }
0181:
0182: /* (non-Javadoc)
0183: * @see org.netbeans.modules.uml.ui.controls.projecttree.IProjectTreeModel#clear()
0184: */
0185: public void clear() {
0186: clear(true);
0187:
0188: if (getRoot() != null) {
0189: try {
0190: fireTreeStructureChanged(getRoot(), new TreePath(
0191: getRoot()));
0192: } catch (Exception e) {
0193: //we get null pointer sometimes, just ignore it.
0194: }
0195: }
0196: }
0197:
0198: //**************************************************
0199: // The TreeModel methods.
0200: //**************************************************
0201:
0202: /* (non-Javadoc)
0203: * @see javax.swing.tree.TreeModel#getRoot()
0204: */
0205: public Object getRoot() {
0206: return getRootItem();
0207: }
0208:
0209: /* (non-Javadoc)
0210: * @see javax.swing.tree.TreeModel#getChild(java.lang.Object, int)
0211: */
0212: public ITreeItem getChildItem(Object parent, int index) {
0213: ITreeItem retVal = null;
0214:
0215: if (parent instanceof ITreeItem) {
0216: ITreeItem parItem = (ITreeItem) parent;
0217: if (parItem.getChildCount() > 0) {
0218: retVal = ((ITreeItem) parent).getChild(index);
0219: }
0220: }
0221:
0222: return retVal;
0223: }
0224:
0225: /* (non-Javadoc)
0226: * @see javax.swing.tree.TreeModel#getChildCount(java.lang.Object)
0227: */
0228: public int getChildCount(Object parent) {
0229: int retVal = 0;
0230:
0231: if (parent instanceof ITreeItem) {
0232: ITreeItem item = (ITreeItem) parent;
0233: retVal = item.getChildCount();
0234:
0235: if ((retVal <= 0) && (item.isInitalized() == false)) {
0236: retVal = 1;
0237: }
0238: }
0239:
0240: return retVal;
0241: }
0242:
0243: public ITreeItem getRootItem() {
0244: return m_TreeRoot;
0245: }
0246:
0247: /* (non-Javadoc)
0248: * @see javax.swing.tree.TreeModel#isLeaf(java.lang.Object)
0249: */
0250: public boolean isLeaf(Object node) {
0251: int children = getChildCount(node);
0252: return (children == 0);
0253: }
0254:
0255: /**
0256: * Locates the nodes that represents the model element.
0257: *
0258: * @param element The model element to locate.
0259: * @return The tree Node. <code>null</code> is returned if the node
0260: * is not found.
0261: */
0262: public ETList<ITreeItem> findNodes(Comparator<ITreeItem> comparator) {
0263: ETList<ITreeItem> retVal = new ETArrayList<ITreeItem>();
0264:
0265: findNodes(getRootItem(), comparator, retVal);
0266:
0267: return retVal;
0268: }
0269:
0270: /**
0271: * Locate the node that represents the model element.
0272: *
0273: * @param element The model element to locate.
0274: * @return The tree Node. <code>null</code> is returned if the node
0275: * is not found.
0276: */
0277: public ETList<ITreeItem> findNodes(final IElement element) {
0278:
0279: return findNodes(new Comparator<ITreeItem>() {
0280: public int compare(ITreeItem o1, ITreeItem o2) {
0281: return 0;
0282: }
0283:
0284: public boolean equals(Object obj) {
0285: return obj.equals(element);
0286: }
0287: });
0288: }
0289:
0290: /**
0291: * Retrieves the index of a child node.
0292: *
0293: * @param parent The parent of the child node.
0294: * @param child The child node to find.
0295: * @return The index value. -1 if the second parameter is not a child of the
0296: * parent node. The method <code>equals</code> is used to find the
0297: * child node.
0298: */
0299: public int getIndexOfChild(ITreeItem parent, ITreeItem child) {
0300: int retVal = -1;
0301:
0302: if ((parent != null) && (child != null)) {
0303: for (int index = 0; (index < parent.getChildCount())
0304: && (retVal < 0); index++) {
0305: if (child.equals(parent.getChild(index)) == true) {
0306: retVal = index;
0307: }
0308: }
0309: }
0310:
0311: return retVal;
0312: }
0313:
0314: /**
0315: * The IProject will be associated to the node that represents the IWSProject
0316: * element.
0317: *
0318: * @param pProject The project that has been opened.
0319: * @return The ITreeItem that is the project node.
0320: */
0321: public ITreeItem projectOpened(IProject pProject) {
0322: ITreeElement retVal = null;
0323: if (pProject != null) {
0324: retVal = getProjectNode(pProject.getNameWithAlias());
0325: if (retVal != null) {
0326: retVal.setElement(pProject);
0327: }
0328: }
0329:
0330: return retVal;
0331: }
0332:
0333: /**
0334: * Adds a listener for the TreeModelEvent posted after the tree changes.
0335: *
0336: * @param listener The lisener to add.
0337: */
0338: public void addProjectTreeModelListener(
0339: IProjectTreeModelListener listener) {
0340: m_Listeners.add(listener);
0341: }
0342:
0343: /**
0344: * Removes a listener previously added with <code>addProjectTreeModelListener</code>
0345: *
0346: * @param listener The listener to remove.
0347: */
0348: public void removeProjectTreeModelListener(
0349: IProjectTreeModelListener listener) {
0350: m_Listeners.remove(listener);
0351: }
0352:
0353: /**
0354: * @param element
0355: * @param item
0356: * @param items
0357: */
0358: protected void findNodes(ITreeItem parentItem,
0359: Comparator<ITreeItem> comparator, ETList<ITreeItem> items) {
0360: if ((parentItem != null) && (items != null)) {
0361: // if(parentItem.equals(element) == true)
0362: if (comparator.equals(parentItem) == true) {
0363: items.add(parentItem);
0364: }
0365:
0366: int childCnt = parentItem.getChildCount();
0367: for (int index = 0; index < childCnt; index++) {
0368: ITreeItem child = parentItem.getChild(index);
0369: findNodes(child, comparator, items);
0370: }
0371: }
0372: }
0373:
0374: /**
0375: * Locate the node that represents the model element.
0376: *
0377: * @param filename The name of the file that specifies the diagram.
0378: * @return The tree Nodes. <code>null</code> is returned if the node
0379: * is not found.
0380: */
0381: public ETList<ITreeItem> findDiagramNodes(final String filename) {
0382: return findNodes(new Comparator<ITreeItem>() {
0383: public int compare(ITreeItem o1, ITreeItem o2) {
0384: return 0;
0385: }
0386:
0387: public boolean equals(Object obj) {
0388: return obj.equals(filename);
0389: }
0390: });
0391: }
0392:
0393: /**
0394: * Sorts the children of a node. The children will be sorted occuring to
0395: * the default sort order.
0396: *
0397: * @param parent The parent who children are to be sorted.
0398: */
0399: public void sortChildren(ITreeItem parent) {
0400: sortChildren(parent, new ProjectTreeComparable());
0401: }
0402:
0403: /**
0404: * Sorts the children of a node. The children will be sorted occuring to
0405: * the Comparable interface.
0406: *
0407: * @param parent The parent who children are to be sorted.
0408: * @param compare The comparable interface used to sort the children.
0409: * @see Comparable
0410: */
0411: public void sortChildren(ITreeItem parent, Comparator compare) {
0412: if (parent != null) {
0413: parent.sortChildren();
0414:
0415: ETList<ITreeItem> items = new ETArrayList<ITreeItem>();
0416: items.add(parent);
0417: notifyOfStructureChange(items);
0418: parent.setIsInitalized(true);
0419: }
0420: }
0421:
0422: /**
0423: * Test if it is OK to delete a tree item. The registered IProjectTreeEngine
0424: * instances are first given chance to deny the delete operation.
0425: *
0426: * @param item The item to test.
0427: * @return <b>true</b> if it is OK to delete the tree item, <b>false</b> if
0428: * it is not OK to delete the tree item.
0429: */
0430: public boolean canDelete(IProjectTreeItem item) {
0431: boolean retVal = true;
0432:
0433: for (Iterator<IProjectTreeEngine> iter = m_TreeEngines
0434: .iterator(); iter.hasNext();) {
0435: IProjectTreeEngine engine = iter.next();
0436: if (engine.canDelete(item) == false) {
0437: retVal = false;
0438: break;
0439: }
0440: }
0441:
0442: return retVal;
0443: }
0444:
0445: /**
0446: * Test if it is OK to edit a tree item. The registered IProjectTreeEngine
0447: * instances are first given chance to deny the edit operation.
0448: *
0449: * @param item The item to test.
0450: * @return <b>true</b> if it is OK to delete the tree item, <b>false</b> if
0451: * it is not OK to delete the tree item.
0452: */
0453: public boolean canEdit(IProjectTreeItem item) {
0454: boolean retVal = true;
0455:
0456: for (Iterator<IProjectTreeEngine> iter = m_TreeEngines
0457: .iterator(); iter.hasNext();) {
0458: IProjectTreeEngine engine = iter.next();
0459: if (engine.canEdit(item) == false) {
0460: retVal = false;
0461: break;
0462: }
0463: }
0464:
0465: return retVal;
0466: }
0467:
0468: /* (non-Javadoc)
0469: * @see javax.swing.tree.TreeModel#getChild(java.lang.Object, int)
0470: */
0471: public Object getChild(Object parent, int index) {
0472: return getChildItem(parent, index);
0473: }
0474:
0475: /* (non-Javadoc)
0476: * @see javax.swing.tree.TreeModel#valueForPathChanged(javax.swing.tree.TreePath, java.lang.Object)
0477: */
0478: public void valueForPathChanged(TreePath path, Object newValue) {
0479: // TODO Auto-generated method stub
0480:
0481: }
0482:
0483: /* (non-Javadoc)
0484: * @see javax.swing.tree.TreeModel#getIndexOfChild(java.lang.Object, java.lang.Object)
0485: */
0486: public int getIndexOfChild(Object parent, Object child) {
0487: int retVal = 0;
0488: boolean parentIsItem = parent instanceof ITreeItem;
0489: boolean childIsItem = child instanceof ITreeItem;
0490:
0491: if ((parentIsItem == true) && (childIsItem == true)) {
0492: retVal = getIndexOfChild((ITreeItem) parent,
0493: (ITreeItem) child);
0494: }
0495:
0496: return retVal;
0497: }
0498:
0499: /* (non-Javadoc)
0500: * @see javax.swing.tree.TreeModel#addTreeModelListener(javax.swing.event.TreeModelListener)
0501: */
0502: public void addTreeModelListener(TreeModelListener l) {
0503: m_ModelListeners.add(l);
0504:
0505: }
0506:
0507: /* (non-Javadoc)
0508: * @see javax.swing.tree.TreeModel#removeTreeModelListener(javax.swing.event.TreeModelListener)
0509: */
0510: public void removeTreeModelListener(TreeModelListener l) {
0511: m_ModelListeners.remove(l);
0512: }
0513:
0514: /**
0515: * Sends the treeStructureChanged event to all registered TreeModelListeners.
0516: *
0517: * @parms items The tree items that has been changed.
0518: */
0519: public void notifyOfStructureChange(ETList<ITreeItem> items) {
0520: for (Iterator<ITreeItem> iter = items.iterator(); iter
0521: .hasNext();) {
0522: ITreeItem item = iter.next();
0523:
0524: if (item != null) {
0525: item.setIsInitalized(false);
0526: //item.removeAllChildren();
0527:
0528: fireTreeStructureChanged(this , new TreePath(item
0529: .getPath()));
0530: }
0531: }
0532: }
0533:
0534: /**
0535: * Notifies all listeners that a child was removed from its parent.
0536: * The mannor that the controls are notified is specific to the platform.
0537: * <br>
0538: * <b>Example:</b> For a Swing control the registered TreeModelListener will
0539: * recieve the treeNodesRemoved event.
0540: *
0541: * @parms parent The parent tree item that is affected.
0542: * @param childIndex The index of the child that was removed.
0543: * @param node The child node that was removed.
0544: */
0545: public void notifyOfRemovedChildren(ITreeItem parent,
0546: int[] childIndices, ITreeItem[] removedChildren) {
0547: if ((removedChildren != null) && (childIndices != null)) {
0548: // fireTreeNodesRemoved(this, getPathToRoot(parent), childIndices,
0549: // removedChildren);
0550: fireTreeNodesRemoved(this , parent.getPath(), childIndices,
0551: removedChildren);
0552: }
0553: }
0554:
0555: /**
0556: * Notifies all listeners that a child was added to a parent by sending
0557: * the TreeModelListener event treeNodesInserted.
0558: *
0559: * @parms parent The parent tree item that is affected.
0560: * @param childIndices The index of the child nodes that was added.
0561: * @param children The children nodes that was added.
0562: */
0563: public void notifyOfAddedChildren(ITreeItem parent,
0564: int[] childIndices/*,
0565: ITreeItem[] children*/) {
0566: if (/*(children != null) && (*/(childIndices != null)) {
0567: ITreeItem temp = getChildItem(parent, childIndices[0]);
0568: ITreeItem[] children = new ITreeItem[childIndices.length];
0569: for (int index = 0; index < childIndices.length; index++) {
0570: children[index] = parent.getChild(childIndices[index]);
0571: }
0572:
0573: fireTreeNodesInserted(this , getPathToRoot(parent),
0574: childIndices, children);
0575: }
0576: }
0577:
0578: /**
0579: * Notifies all listeners that the content of some nodes has changed by
0580: * sending the TreeModelListener event treeNodesChanged.
0581: *
0582: * @parms parent The parent tree item that is affected.
0583: * @param childIndices The index of the child nodes that was added.
0584: * @param children The children nodes that was added.
0585: */
0586: public void notifyOfNodesChanged(ITreeItem parent,
0587: int[] childIndices, ITreeItem[] nodes) {
0588: if ((nodes != null) && (childIndices != null)) {
0589: // fireTreeNodesChanged(this, getPathToRoot(parent), childIndices,
0590: // nodes);
0591:
0592: if (parent != null) {
0593: if (childIndices != null) {
0594: int cCount = childIndices.length;
0595: if (cCount > 0) {
0596: Object[] cChildren = new Object[cCount];
0597: for (int counter = 0; counter < cCount; counter++) {
0598: cChildren[counter] = parent
0599: .getChild(childIndices[counter]);
0600: }
0601:
0602: fireTreeNodesChanged(this ,
0603: getPathToRoot(parent), childIndices,
0604: cChildren);
0605: }
0606: } else if (parent == getRoot()) {
0607: fireTreeNodesChanged(this , getPathToRoot(parent),
0608: null, null);
0609: }
0610: }
0611: }
0612: }
0613:
0614: /**
0615: * Builds the parents of node up to and including the root node,
0616: * where the original node is the last element in the returned array.
0617: * The length of the returned array gives the node's depth in the
0618: * tree.
0619: *
0620: * @param aNode the TreeNode to get the path for
0621: */
0622: public Object[] getPathToRoot(ITreeItem node) {
0623: return getPathToRoot(node, 0);
0624: }
0625:
0626: /**
0627: * Builds the parents of node up to and including the root node,
0628: * where the original node is the last element in the returned array.
0629: * The length of the returned array gives the node's depth in the
0630: * tree.
0631: *
0632: * @param aNode the TreeNode to get the path for
0633: * @param depth an int giving the number of steps already taken towards
0634: * the root (on recursive calls), used to size the returned array
0635: * @return an array of TreeNodes giving the path from the root to the
0636: * specified node
0637: */
0638: protected ITreeItem[] getPathToRoot(ITreeItem aNode, int depth) {
0639: ITreeItem[] retNodes = null;
0640:
0641: // This method recurses, traversing towards the root in order
0642: // size the array. On the way back, it fills in the nodes,
0643: // starting from the root and working back to the original node.
0644:
0645: // Check for null, in case someone passed in a null node, or
0646: // they passed in an element that isn't rooted at root.
0647: if (aNode == null) {
0648: if (depth > 0) {
0649: retNodes = new ITreeItem[depth];
0650: }
0651: } else {
0652: depth++;
0653: if (aNode == getRoot()) {
0654: retNodes = new ITreeItem[depth];
0655: } else {
0656: retNodes = getPathToRoot(aNode.getParentItem(), depth);
0657: }
0658:
0659: retNodes[retNodes.length - depth] = aNode;
0660: }
0661:
0662: return retNodes;
0663: }
0664:
0665: /**
0666: * Fires the projectOpened event to every registered IProjectTreeListener
0667: *
0668: * @param node The node that is affected.
0669: * @param project The project that is closed.
0670: */
0671: public void fireProjectOpened(ITreeElement node, IProject project) {
0672: ProjectTreeModelEvent event = new ProjectTreeModelEvent(this ,
0673: node, project, false);
0674:
0675: for (Iterator<IProjectTreeModelListener> iter = m_Listeners
0676: .iterator(); iter.hasNext();) {
0677: IProjectTreeModelListener curListener = iter.next();
0678: curListener.projectOpened(event);
0679: }
0680: }
0681:
0682: /**
0683: * Fires the projectClosed event to every registered IProjectTreeListener
0684: *
0685: * @param node The node that is affected.
0686: * @param project The project that is closed.
0687: */
0688: public void fireProjectClosed(ITreeElement node, IProject project) {
0689: ProjectTreeModelEvent event = new ProjectTreeModelEvent(this ,
0690: node, project, true);
0691:
0692: for (Iterator<IProjectTreeModelListener> iter = m_Listeners
0693: .iterator(); iter.hasNext();) {
0694: IProjectTreeModelListener curListener = iter.next();
0695: curListener.projectClosed(event);
0696: }
0697: }
0698:
0699: // **************************************************
0700: // Event Helper Methods
0701: //**************************************************
0702:
0703: /**
0704: * Notifies all listeners that have registered interest for
0705: * notification on this event type. The event instance
0706: * is lazily created using the parameters passed into
0707: * the fire method.
0708: *
0709: * @param source the node being changed
0710: * @param path the path to the root node
0711: * @param childIndicies the indices of the changed elements
0712: * @param children the changed elements
0713: * @see EventListenerList
0714: */
0715: protected void fireTreeNodesChanged(final Object source,
0716: final Object[] path, final int[] childIndices,
0717: final Object[] children) {
0718: final ArrayList<TreeModelListener> listeners = m_ModelListeners;
0719:
0720: SwingUtilities.invokeLater(new Runnable() {
0721: public void run() {
0722: TreeModelEvent e = null;
0723:
0724: // Process the listeners last to first, notifying
0725: // those that are interested in this event
0726: for (int i = listeners.size() - 1; i >= 0; i--) {
0727: try {
0728: // Lazily create the event:
0729: if (e == null) {
0730: e = new TreeModelEvent(source, path,
0731: childIndices, children);
0732: }
0733: TreeModelListener listener = listeners.get(i);
0734: listener.treeNodesChanged(e);
0735: } catch (Exception exc) {
0736: exc.printStackTrace();
0737: //just ignore this exception for the time being.
0738: }
0739: }
0740: }
0741: });
0742: }
0743:
0744: /**
0745: * Notifies all listeners that have registered interest for
0746: * notification on this event type. The event instance
0747: * is lazily created using the parameters passed into
0748: * the fire method.
0749: *
0750: * @param source the node where new elements are being inserted
0751: * @param path the path to the root node
0752: * @param childIndicies the indices of the new elements
0753: * @param children the new elements
0754: * @see EventListenerList
0755: */
0756: protected void fireTreeNodesInserted(final Object source,
0757: final Object[] path, final int[] childIndices,
0758: final Object[] children) {
0759: TreeModelEvent e = null;
0760:
0761: // Process the listeners last to first, notifying
0762: // those that are interested in this event
0763: for (int i = m_ModelListeners.size() - 1; i >= 0; i--) {
0764: try {
0765: // Lazily create the event:
0766: if (e == null) {
0767: TreePath treePath = new TempTreePath(path);
0768: TreePath parentPath = treePath.getParentPath();
0769: e = new TreeModelEvent(source, treePath,
0770: childIndices, children);
0771: }
0772: TreeModelListener listener = m_ModelListeners.get(i);
0773: listener.treeNodesInserted(e);
0774: } catch (Exception exc) {
0775: exc.printStackTrace();
0776: //just catch it for the time being.
0777: }
0778: }
0779: }
0780:
0781: /**
0782: * Notifies all listeners that have registered interest for
0783: * notification on this event type. The event instance
0784: * is lazily created using the parameters passed into
0785: * the fire method.
0786: *
0787: * @param source the node where elements are being removed
0788: * @param path the path to the root node from the childrens parent.
0789: * @param childIndicies the indices of the removed elements
0790: * @param children the removed elements
0791: * @see EventListenerList
0792: */
0793: protected void fireTreeNodesRemoved(Object source, Object[] path,
0794: int[] childIndices, Object[] children) {
0795: TreeModelEvent e = null;
0796: // Process the listeners last to first, notifying
0797: // those that are interested in this event
0798: for (int i = m_ModelListeners.size() - 1; i >= 0; i--) {
0799: try {
0800: // Lazily create the event:
0801: if (e == null) {
0802: e = new TreeModelEvent(source, path, childIndices,
0803: children);
0804: }
0805: TreeModelListener listener = m_ModelListeners.get(i);
0806: listener.treeNodesRemoved(e);
0807: } catch (Exception exc) {
0808: exc.printStackTrace();
0809: //just ignore it for the time being.
0810: }
0811: }
0812: }
0813:
0814: /**
0815: * Notifies all listeners that have registered interest for
0816: * notification on this event type. The event instance
0817: * is lazily created using the parameters passed into
0818: * the fire method.
0819: *
0820: * @param source the node where the tree model has changed
0821: * @param path the path to the root node
0822: * @param childIndicies the indices of the affected elements
0823: * @param children the affected elements
0824: * @see EventListenerList
0825: */
0826: protected void fireTreeStructureChanged(Object source,
0827: Object[] path, int[] childIndices, Object[] children) {
0828: TreeModelEvent e = null;
0829:
0830: // Process the listeners last to first, notifying
0831: // those that are interested in this event
0832: for (int i = m_ModelListeners.size() - 1; i >= 0; i--) {
0833: try {
0834: // Lazily create the event:
0835: if (e == null) {
0836: e = new TreeModelEvent(source, path, childIndices,
0837: children);
0838: }
0839: TreeModelListener listener = m_ModelListeners.get(i);
0840: listener.treeStructureChanged(e);
0841: } catch (Exception exc) {
0842: exc.printStackTrace();
0843: //just ignore it for the time being.
0844: }
0845: }
0846: }
0847:
0848: /**
0849: * Notifies all listeners that have registered interest for
0850: * notification on this event type. The event instance
0851: * is lazily created using the parameters passed into
0852: * the fire method.
0853: *
0854: * @param source the node where the tree model has changed
0855: * @param path the path to the root node
0856: * @see EventListenerList
0857: */
0858: protected void fireTreeStructureChanged(Object source, TreePath path) {
0859: TreeModelEvent e = null;
0860:
0861: // Process the listeners last to first, notifying
0862: // those that are interested in this event
0863: for (int i = m_ModelListeners.size() - 1; i >= 0; i--) {
0864: try {
0865: // Lazily create the event:
0866: if (e == null) {
0867: e = new TreeModelEvent(source, path);
0868: }
0869: TreeModelListener listener = m_ModelListeners.get(i);
0870: listener.treeStructureChanged(e);
0871: } catch (Exception exp) {
0872: exp.printStackTrace();
0873: //just ignore it.
0874: }
0875: }
0876: }
0877:
0878: /**
0879: * Initialize the model to the project. This is a good
0880: * place to initialize all sinks and project tree engines.
0881: */
0882: public void initialize() {
0883: try {
0884: attachSinks();
0885: attachEngines();
0886:
0887: IProjectTreeItem item = new ProjectTreeItemImpl();
0888: item.setData(null);
0889: item.setDescription(DESIGN_CENTER_DESCRIPTION);
0890: item.setItemText(DESIGN_CENTER_NAME);
0891:
0892: m_TreeRoot = new ProjectTreeNode(item);
0893: m_TreeRoot.setExpanded(false);
0894: m_TreeRoot.setAllowsChildren(true);
0895: m_TreeRoot.setIsInitalized(false);
0896: m_TreeRoot.setName(DESIGN_CENTER_DESCRIPTION);
0897:
0898: //create a dummy node
0899: // IProjectTreeItem dummyItem = new ProjectTreeItemImpl();
0900: // dummyItem.setData(null);
0901: // dummyItem.setDescription(DESIGN_CENTER_DESCRIPTION);
0902: // dummyItem.setItemText(DESIGN_CENTER_DESCRIPTION);
0903: // ProjectTreeNode node = new ProjectTreeNode(dummyItem);
0904: // m_TreeRoot.addChild(node);
0905:
0906: } catch (InvalidArguments e) {
0907: // TODO: Figure out what to do about error handling.
0908: }
0909: }
0910:
0911: public String getProjectTreeName() {
0912: return ProjectTreeResources
0913: .getString("DesignCenterSwingModel.Design_Center_Description"); //$NON-NLS-1$
0914: }
0915:
0916: public IProjectTreeItem addWorkspace(ITreeItem pParent,
0917: IWorkspace space) {
0918: IProjectTreeItem item = new ProjectTreeItemImpl();
0919: item.setData(space);
0920: item.setDescription(IProjectTreeControl.WORKSPACE_DESCRIPTION);
0921: item.setItemText(space.getName());
0922: item.setAsAddinNode(true);
0923:
0924: ITreeItem projectNode = new ProjectTreeNode(item);
0925: projectNode
0926: .setName(ProjectTreeResources
0927: .getString("DesignCenterSwingModel.Design_Center_Description")); //$NON-NLS-1$
0928: projectNode.setExpanded(false);
0929: projectNode.setIsInitalized(false);
0930:
0931: addItem(pParent, projectNode);
0932:
0933: //addProjects(space);
0934:
0935: if (getRoot() != null) {
0936: try {
0937: fireTreeStructureChanged(getRoot(), new TreePath(
0938: getRoot()));
0939: } catch (Exception e) {
0940: //we get null pointer sometimes, just ignore it.
0941: }
0942: }
0943: return item;
0944: }
0945:
0946: /**
0947: * Initializes and attaches the engines required by the model.
0948: */
0949: protected void attachEngines() {
0950: //This has to be uncommented after resolving cyclic dependency issues
0951: //ADDesignCenterEngine adEngine = new ADDesignCenterEngine();
0952: //adEngine.initialize(this);
0953:
0954: //addEngine(adEngine);
0955: }
0956:
0957: public void addEngine(IProjectTreeEngine engine) {
0958: m_TreeEngines.add(engine);
0959: }
0960:
0961: public void removeEngine(IProjectTreeEngine engine) {
0962: m_TreeEngines.remove(engine);
0963: }
0964:
0965: /**
0966: * Attaches all of the required listeners.
0967: */
0968: protected void attachSinks() throws InvalidArguments {
0969: }
0970:
0971: protected void detachSinks() throws InvalidArguments {
0972: }
0973:
0974: /**
0975: * Clears the content of the model.
0976: *
0977: * @param reload <b>true</b> if the workspace is to be reloaded.
0978: * <b>false</b> if the model is to be left empty.
0979: */
0980: public void clear(boolean reload) {
0981: //there could be multiple workspaces in design center, so I need to find the right workspace
0982: //and then expand that.
0983: if (m_TreeRoot != null) {
0984: // ITreeItem item = getWorkspaceNode(space, m_TreeRoot);
0985: // m_TreeRoot.removeAllChildren();
0986: // m_TreeRoot = null;
0987:
0988: int childCount = m_TreeRoot.getChildCount();
0989: for (int index = 0; index < childCount; index++) {
0990: TreeNode node = m_TreeRoot.getChildAt(index);
0991: if (node instanceof ITreeItem) {
0992: ITreeItem item = (ITreeItem) node;
0993: item.removeAllChildren();
0994: item.setIsInitalized(false);
0995: } else if (node instanceof DefaultMutableTreeNode) {
0996: ITreeItem item = (ITreeItem) node;
0997: item.removeAllChildren();
0998: }
0999: }
1000: }
1001:
1002: if (reload == true) {
1003: //addProjects(space);
1004: //setWorkspace(space);
1005:
1006: // IProjectTreeItem item = new ProjectTreeItemImpl();
1007: // item.setData(null);
1008: // item.setDescription(DESIGN_CENTER_DESCRIPTION);
1009: // item.setItemText(DESIGN_CENTER_NAME);
1010: //
1011: // m_TreeRoot = new ProjectTreeNode(item);
1012: // m_TreeRoot.setExpanded(false);
1013: // m_TreeRoot.setAllowsChildren(true);
1014: // m_TreeRoot.setIsInitalized(false);
1015: // m_TreeRoot.setName(DESIGN_CENTER_DESCRIPTION);
1016: }
1017: }
1018:
1019: public ITreeItem getWorkspaceNode(IWorkspace space,
1020: ITreeItem startNode) {
1021: ITreeItem retItem = null;
1022: if (m_TreeRoot != null && startNode == null) {
1023: //start from the root node.
1024: startNode = m_TreeRoot;
1025: }
1026:
1027: if (space != null) {
1028: int count = startNode.getChildCount();
1029: if (count > 0) {
1030: for (int i = 0; i < count && retItem == null; i++) {
1031: ITreeItem item = startNode.getChild(i);
1032: String name = item.getDisplayedName();
1033: if (name != null && name.equals(space.getName())) {
1034: Object obj = item.getData().getData();
1035: if (obj instanceof IWorkspace) {
1036: retItem = item;
1037: }
1038: } else {
1039: retItem = getWorkspaceNode(space, item);
1040: }
1041: }
1042: }
1043: }
1044: return retItem;
1045: }
1046:
1047: /**
1048: * Retrieves the product that specifies the tree structure.
1049: *
1050: * @return The product.
1051: */
1052: public ICoreProduct getProduct() {
1053: return m_Product;
1054: }
1055:
1056: /**
1057: * Sets the product that specifies the tree structure.
1058: *
1059: * @param product The new product.
1060: */
1061: public void setProduct(ICoreProduct product) {
1062: DataFormatter formater;
1063: m_Product = product;
1064:
1065: IWorkspace space = getWorkspace();
1066: if (space != null) {
1067: setWorkspace(space);
1068: }
1069: }
1070:
1071: public void closeProject(IProject proj) {
1072: //This has to be uncommented after resolving cyclic dependency issues
1073: //ICoreProduct pCore = ProductHelper.getCoreProduct();
1074: // if (pCore != null)
1075: //{
1076: // IDesignCenterManager pManager = pCore.getDesignCenterManager();
1077: // if (pManager != null)
1078: // {
1079: // if (pManager instanceof IADDesignCenterManager)
1080: // {
1081: // IADDesignCenterManager pADManager = (IADDesignCenterManager)pManager;
1082: // IDesignPatternCatalog pCatalog = pADManager.getDesignPatternCatalog();
1083: // if (pCatalog != null)
1084: // {
1085: //
1086: // pCatalog.closeProject(proj);
1087: // }
1088: // }
1089: // }
1090: // }
1091: }
1092:
1093: public IWorkspace getWorkspace() {
1094: // This has to be uncommented after resolving cyclic dependency issues
1095: return null; //DesignPatternUtilities.getDesignPatternCatalogWorkspace();
1096: }
1097:
1098: /**
1099: * @param workspace
1100: */
1101: public void setWorkspace(IWorkspace workspace) {
1102: // if (workspace != null)
1103: // {
1104: // IProjectTreeItem item = new ProjectTreeItemImpl();
1105: // item.setData(workspace);
1106: // item.setDescription(IProjectTreeControl.WORKSPACE_DESCRIPTION);
1107: // item.setItemText(workspace.getName());
1108: //
1109: // ProjectTreeNode node = new ProjectTreeNode(item);
1110: //
1111: // // The C++ version relies on the expansion of the workspace to
1112: // // gather the project information. Since the Java version has
1113: // // done away with the configuration manager (the model is the
1114: // // configuration manager). I will gather the project information
1115: // // here.
1116: // m_TreeRoot.addChild(node);
1117: // addProjects(workspace);
1118: // }
1119: }
1120:
1121: /**
1122: * @return
1123: */
1124: public ETArrayList<String> getUnfilteredProjects() {
1125: // TODO Auto-generated method stub
1126: return null;
1127: }
1128:
1129: /**
1130: * Message this to remove node from its parent. This will message
1131: * nodesWereRemoved to create the appropriate event. This is the
1132: * preferred way to remove a node as it handles the event creation
1133: * for you.
1134: */
1135: public void removeNodeFromParent(ITreeItem node) {
1136: ITreeItem parent = node.getParentItem();
1137:
1138: if (parent == null) {
1139: throw new IllegalArgumentException(
1140: ProjectTreeResources
1141: .getString("DesignCenterSwingModel.node_does_not_have_a_parent._4")); //$NON-NLS-1$
1142: }
1143:
1144: int[] childIndex = { getIndexOfChild(parent, node) };
1145: ITreeItem[] removedArray = { node };
1146:
1147: parent.removeChild(node);
1148: notifyOfRemovedChildren(parent, childIndex, removedArray);
1149: }
1150:
1151: /**
1152: * Retrieves the node that represents a project. The project is located by
1153: * name of the project.
1154: *
1155: * @param projName The name of the project to locate.
1156: * @return The project node.
1157: */
1158: protected ITreeElement getProjectNode(IProject project) {
1159: ITreeElement retVal = null;
1160:
1161: if (project != null) {
1162:
1163: IWorkspace ws = getWorkspace();
1164: String name = project.getNameWithAlias();
1165:
1166: boolean useFormatter = false;
1167: if (ws != null) {
1168: IWSProject wsProject = ws.getWSProjectByName(project
1169: .getName());
1170: if (wsProject != null) {
1171: useFormatter = wsProject.isOpen();
1172: }
1173: }
1174:
1175: if (useFormatter == true) {
1176: IDataFormatter formatter = ProductHelper
1177: .getDataFormatter();
1178: retVal = getProjectNode(formatter
1179: .formatElement(project));
1180: }
1181: }
1182:
1183: return retVal;
1184: }
1185:
1186: /**
1187: * Retrieves the node that represents a project. The project is located by
1188: * name of the project.
1189: *
1190: * @param projName The name of the project to locate.
1191: * @return The project node.
1192: */
1193: protected ITreeElement getProjectNode(String projName) {
1194: ITreeElement foundProject = null;
1195:
1196: ITreeItem dpcItem = getCatalogNode();
1197: if (dpcItem != null) {
1198: int numChildren = dpcItem.getChildCount();
1199: for (int index = 0; (index < numChildren)
1200: && (foundProject == null); index++) {
1201: ITreeItem curItem = dpcItem.getChild(index);
1202: if (curItem != null) {
1203: IProjectTreeItem data = curItem.getData();
1204: if (data.isProject() == true) {
1205: if (data.getItemText().equals(projName) == true) {
1206: if (curItem instanceof ITreeElement) {
1207: foundProject = (ITreeElement) curItem;
1208: break;
1209: }
1210: }
1211: }
1212: }
1213: }
1214: }
1215: return foundProject;
1216: }
1217:
1218: private ITreeItem getCatalogNode() {
1219: ITreeItem dpcItem = null;
1220: ITreeItem rootItem = getRootItem();
1221: if (rootItem != null) {
1222: int numChildren = rootItem.getChildCount();
1223: if (numChildren == 1) {
1224: dpcItem = rootItem.getChild(0);
1225: }
1226: }
1227: return dpcItem;
1228: }
1229:
1230: /**
1231: * @param workspace
1232: */
1233: private void addProjects(IWorkspace workspace) {
1234: try {
1235: // The design center shouldn't be adding projects. The design center engine
1236: // derives from this engine so make sure we're controlling the real project tree
1237: // and not the design center tree before adding projects
1238: if (!isProjectTree()) {
1239: // This has to be uncommented after resolving the cyclic dependency issues
1240: IWorkspace pWork = null; //DesignPatternUtilities.getDesignPatternCatalogWorkspace();
1241: if (pWork != null) {
1242: ETList<IWSProject> wsProjects = pWork
1243: .getWSProjects();
1244: for (int index = 0; index < wsProjects.size(); index++) {
1245: IWSProject wsProject = wsProjects.get(index);
1246:
1247: String name = wsProject.getNameWithAlias();
1248:
1249: if (name.length() > 0) {
1250: addProject(name, getCatalogNode(), null);
1251: }
1252: }
1253: }
1254: }
1255: } catch (Exception e) {
1256: }
1257: }
1258:
1259: /**
1260: * @param name
1261: * @param workspace
1262: * @param app
1263: */
1264: protected ITreeElement addProject(String name, ITreeItem parent,
1265: IWorkspace workspace, IApplication app) {
1266: // TODO: I have to determine how to get the aliased Name
1267: IProject project = app.getProjectByName(workspace, name);
1268:
1269: ITreeElement projectNode = addProject(name, parent, project);
1270: return projectNode;
1271: }
1272:
1273: public ITreeElement addProject(String name, ITreeItem parent,
1274: IProject project) {
1275: ITreeElement projectNode = new TreeElementNode();
1276: projectNode.setName(name);
1277: projectNode.setElement(project);
1278: projectNode.setDisplayedName(name);
1279:
1280: if (projectNode.getData() != null) {
1281: projectNode.getData().setSortPriority(1);
1282: projectNode.getData().setDescription(
1283: IProjectTreeControl.PROJECT_DESCRIPTION);
1284: }
1285:
1286: addItem(parent, projectNode);
1287: return projectNode;
1288: }
1289:
1290: /**
1291: * Adds a node to the tree with a description and an alternate element.
1292: *
1293: * @param pParent The parent item for the one to create
1294: * @param sText The node text for this new item
1295: * @param nSortPriority The sort priority. The lower the number the higher it will appear in the sibling list
1296: * @param pElement The element this item represents
1297: * @param pProjectTreeSupportTreeItem The ITreeItem from the project tree builder where we build the tree.
1298: * @param sDescription The description of this item. Placed as part of the HTREEITEM's itemData
1299: * @return The created project tree item
1300: */
1301: public IProjectTreeItem addItem(IProjectTreeItem parent,
1302: String name, String text, long sortPriority,
1303: IElement element, Object supportTreeItem, String description) {
1304: ITreeItem parentItem = null;
1305: if (parent.getPath() != null) {
1306: ITreeItem[] path = parent.getPath();
1307: parentItem = path[path.length - 1];
1308: }
1309:
1310: return addItem(parentItem, name, text, sortPriority, element,
1311: supportTreeItem, description);
1312: }
1313:
1314: protected int findLocation(ITreeItem parent, ITreeItem node) {
1315: int retVal = 0;
1316:
1317: //ProjectTreeComparable comparable = new ProjectTreeComparable();
1318: int max = parent.getChildCount();
1319: retVal = max;
1320: for (int index = 0; index < max; index++) {
1321: ITreeItem curChild = parent.getChild(index);
1322: if (curChild != null) {
1323: if (ProjectTreeComparable.compareTo(curChild, node) == ProjectTreeComparable.GREATER_THAN) {
1324: retVal = index;
1325: break;
1326: }
1327: }
1328: }
1329:
1330: // if(retVal >= max)
1331: // {
1332: // retVal = max - 1;
1333: // }
1334:
1335: return retVal;
1336: }
1337:
1338: /**
1339: * Adds a node to the tree with a description and an alternate element.
1340: *
1341: * @param pParent The parent item for the one to create
1342: * @param name The name of the node. This is not the displayed text.
1343: * @param sText The node text for this new item. This is the displayed text.
1344: * @param nSortPriority The sort priority. The lower the number the higher it will appear in the sibling list
1345: * @param pElement The element this item represents
1346: * @param pProjectTreeSupportTreeItem The ITreeItem from the project tree builder where we build the tree.
1347: * @param sDescription The description of this item. Placed as part of the HTREEITEM's itemData
1348: * @return The created project tree item
1349: */
1350: public IProjectTreeItem addItem(ITreeItem parent, String name,
1351: String text, long sortPriority, IElement element,
1352: Object supportTreeItem, String description) {
1353: IProjectTreeItem retVal = new ProjectTreeItemImpl();
1354: retVal.setItemText(text);
1355: retVal.setModelElement(element);
1356: retVal.setDescription(description);
1357: retVal.setSortPriority((int) sortPriority);
1358:
1359: if (supportTreeItem instanceof ITreeItem) {
1360: retVal
1361: .setProjectTreeSupportTreeItem((ITreeItem) supportTreeItem);
1362: }
1363:
1364: ProjectTreeNode node = new ProjectTreeNode(retVal);
1365: //parent.addChild(node);
1366: node.setName(name);
1367:
1368: int location = findLocation(parent, node);
1369: parent.insertAt(node, location);
1370: node.setParentItem(parent);
1371:
1372: Object[] path = node.getPath();
1373: if (path != null) {
1374: ITreeItem[] treeItems = new ITreeItem[path.length];
1375: for (int index = 0; index < path.length; index++) {
1376: if (path[index] instanceof ITreeItem) {
1377: treeItems[index] = (ITreeItem) path[index];
1378:
1379: }
1380: }
1381: retVal.setPath(treeItems);
1382: }
1383:
1384: int[] childIndices = { location };
1385: notifyOfAddedChildren(parent, childIndices);
1386:
1387: // ITreeItem[] nodes = { (ITreeItem)node };
1388: // notifyOfNodesChanged(parent,
1389: // childIndices,
1390: // nodes);
1391: return retVal;
1392: }
1393:
1394: public void addItem(ITreeItem parent, ITreeItem folder) {
1395: // I have to call setParentItem and pass in null because the
1396: // call to addChild does not like it when a childs parent is
1397: // already set. Since the process of building the tree can
1398: // cause the parent to be set I must first remove the parents.
1399:
1400: if (parent != null && folder != null) {
1401: folder.setParentItem(null);
1402: int count = parent.getChildCount();
1403: boolean found = false;
1404:
1405: for (int i = 0; i < count; i++) {
1406: ITreeItem item = parent.getChild(i);
1407: if (item.equals(folder)) {
1408: found = true;
1409: break;
1410: }
1411: }
1412:
1413: if (!found) {
1414: //parent.addChild(folder);
1415: int location = findLocation(parent, folder);
1416: parent.insertAt(folder, location);
1417: folder.setParentItem(parent);
1418:
1419: // For some reason when I notify about an insert a gap is created.
1420: // So, I am not going to notify about the gap and only notify the
1421: // nodes that they have changed.
1422: int[] childIndices = { location };
1423: notifyOfAddedChildren(parent, childIndices);
1424:
1425: // ITreeItem[] nodes = { folder };
1426: // notifyOfNodesChanged(parent,
1427: // childIndices,
1428: // nodes);
1429: }
1430:
1431: }
1432: }
1433:
1434: /**
1435: * Inserts the new node into the parent child list at a specified location.
1436: * The notifyOfAddedChildren will be sent after the node is added.
1437: *
1438: * @param parent The parent to recieve the new node.
1439: * @param node The node to be added.
1440: * @param index The index to insert the node. If the index is greater than
1441: * the number of children the node will be appended to the
1442: * end of the child list.
1443: */
1444: public void insertItem(ITreeItem parent, ITreeItem node, int index) {
1445: parent.insertAt(node, index);
1446:
1447: int[] childIndices = { index };
1448: notifyOfAddedChildren(parent, childIndices);
1449: }
1450:
1451: /**
1452: * Remove all instances of the model element from the tree.
1453: *
1454: * @param element The element to remove.
1455: */
1456: public void removeAll(IElement element) {
1457: ETList<ITreeItem> nodes = findNodes(element);
1458: if ((nodes != null) && (nodes.size() > 0)) {
1459: for (Iterator<ITreeItem> iter = nodes.iterator(); iter
1460: .hasNext();) {
1461: ITreeItem node = iter.next();
1462: removeNodeFromParent(node);
1463: }
1464: }
1465: }
1466:
1467: public boolean isProjectTree() {
1468: return false;
1469: }
1470:
1471: public void setProjectTree(JTree tree) {
1472: tree.setShowsRootHandles(true);
1473: tree.setRootVisible(true);
1474: tree.collapseRow(0);
1475: }
1476:
1477: public class TempTreePath extends TreePath {
1478: /**
1479: * Tests two TreePaths for equality by checking each element of the
1480: * paths for equality. Two paths are considered equal if they are of
1481: * the same length, and contain
1482: * the same elements (<code>.equals</code>).
1483: *
1484: * @param o the Object to compare
1485: */
1486: public boolean equals(Object o) {
1487: if (o == this ) {
1488: return true;
1489: }
1490:
1491: if (o instanceof TreePath) {
1492: TreePath oTreePath = (TreePath) o;
1493: if (getPathCount() != oTreePath.getPathCount())
1494: return false;
1495: for (TreePath path = this ; path != null; path = path
1496: .getParentPath()) {
1497: if (!(path.getLastPathComponent().equals(oTreePath
1498: .getLastPathComponent()))) {
1499: return false;
1500: }
1501: oTreePath = oTreePath.getParentPath();
1502: }
1503:
1504: return true;
1505: }
1506: return false;
1507: }
1508:
1509: /**
1510: * @param path
1511: */
1512: public TempTreePath(Object[] path) {
1513: super(path);
1514: }
1515: }
1516: }
|