001: /* ====================================================================
002: * The JRefactory License, Version 1.0
003: *
004: * Copyright (c) 2001 JRefactory. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * 1. Redistributions of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * 3. The end-user documentation included with the redistribution,
019: * if any, must include the following acknowledgment:
020: * "This product includes software developed by the
021: * JRefactory (http://www.sourceforge.org/projects/jrefactory)."
022: * Alternately, this acknowledgment may appear in the software itself,
023: * if and wherever such third-party acknowledgments normally appear.
024: *
025: * 4. The names "JRefactory" must not be used to endorse or promote
026: * products derived from this software without prior written
027: * permission. For written permission, please contact seguin@acm.org.
028: *
029: * 5. Products derived from this software may not be called "JRefactory",
030: * nor may "JRefactory" appear in their name, without prior written
031: * permission of Chris Seguin.
032: *
033: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
034: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
035: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
036: * DISCLAIMED. IN NO EVENT SHALL THE CHRIS SEGUIN OR
037: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
038: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
039: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
040: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
041: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
042: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
043: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
044: * SUCH DAMAGE.
045: * ====================================================================
046: *
047: * This software consists of voluntary contributions made by many
048: * individuals on behalf of JRefactory. For more information on
049: * JRefactory, please see
050: * <http://www.sourceforge.org/projects/jrefactory>.
051: */
052: package org.acm.seguin.ide.common;
053:
054: import java.awt.Dimension;
055: import java.awt.Component;
056: import java.io.IOException;
057: import java.util.Iterator;
058: import java.util.Enumeration;
059: import java.util.List;
060: import java.util.ArrayList;
061: import javax.swing.*;
062: import javax.swing.tree.*;
063: import org.acm.seguin.summary.PackageSummary;
064: import org.acm.seguin.util.FileSettings;
065: import net.sourceforge.jrefactory.uml.PackageSummaryListModel;
066: import net.sourceforge.jrefactory.uml.UMLPackage;
067:
068: /**
069: * Just the package selector area
070: *
071: *@author Chris Seguin
072: *@created October 18, 2001
073: */
074: public class PackageSelectorArea extends JPanel {
075: /**
076: * The list box of packages
077: */
078: protected JTree packages;
079: private JScrollPane pane;
080: public DefaultTreeModel model;
081: public ANode rootNode;
082:
083: /** The instance of BugCellRenderer. */
084: private static final NavigatorRenderer navigatorRenderer = new NavigatorRenderer();
085:
086: /**
087: * Constructor for the PackageSelectorArea object
088: */
089: public PackageSelectorArea() {
090: // Setup the UI
091: setLayout(null);
092: super .setSize(220, 300);
093:
094: // Create the list
095: packages = new JTree();
096: packages.setCellRenderer(navigatorRenderer);
097:
098: rootNode = new RootNode("Modules", null);
099: model = new DefaultTreeModel(rootNode);
100: packages.setModel(model);
101:
102: pane = new JScrollPane(packages);
103: pane.setBounds(10, 10, 200, 280);
104: add(pane);
105: }
106:
107: /**
108: * Gets the ScrollPane attribute of the PackageSelectorArea object
109: *
110: *@return The ScrollPane value
111: */
112: public JScrollPane getScrollPane() {
113: return pane;
114: }
115:
116: /**
117: * Gets the Selection attribute of the PackageSelectorArea object
118: *
119: *@return The Selection value
120: */
121: public PackageSummary getSelection() {
122: TreePath selection = packages.getSelectionPath();
123: return (PackageSummary) ((ANode) selection
124: .getLastPathComponent()).getUserObject();
125: }
126:
127: /**
128: * Loads the package into the listbox
129: */
130: public void loadPackages() {
131: //PackageSummaryListModel model = new PackageSummaryListModel();
132:
133: // Get the list of packages
134: Iterator iter = PackageSummary.getAllPackages();
135: if (iter == null) {
136: return;
137: }
138:
139: // Add in the packages
140: UMLPackage view = null;
141: PackageSummary packageSummary = null;
142: PackageListFilter filter = PackageListFilter.get();
143: while (iter.hasNext()) {
144: packageSummary = (PackageSummary) iter.next();
145: if (filter.isIncluded(packageSummary)) {
146: //model.add(packageSummary);
147: String name = packageSummary.getName();
148: addSummaryFirst(rootNode, name, packageSummary);
149: }
150: }
151:
152: // Set the model
153: packages.setModel(model);
154: model.nodeStructureChanged(rootNode);
155: model.reload();
156: saveKnownModules();
157: }
158:
159: public void saveKnownModules() {
160: System.out.println("saveKnownModules()");
161: StringBuffer buf = new StringBuffer();
162: Enumeration nodes = rootNode.children();
163: while (nodes.hasMoreElements()) {
164: ANode node = (ANode) nodes.nextElement();
165: if (node instanceof ModuleNode) {
166: String name = node.getName();
167: if (buf.length() > 0) {
168: buf.append(";");
169: }
170: buf.append(name);
171: }
172: }
173: FileSettings bundle = FileSettings.getRefactorySettings("proj");
174: bundle.setString("known.modules", buf.toString());
175: bundle.save();
176: }
177:
178: /**
179: * Load the summaries
180: */
181: public void loadSummaries() {
182: }
183:
184: private void addSummaryFirst(ANode toNode, String name,
185: PackageSummary summary) {
186: //System.out.println("summary.isTopLevel()="+summary.isTopLevel());
187: //System.out.println("summary.getDirectory()="+summary.getDirectory());
188: String file = null;
189: try {
190: file = summary.getDirectory().getCanonicalPath();
191: } catch (Exception e) {
192: }
193: if (file == null) {
194: file = "JDK";
195: } else if (file.length() > name.length()) {
196: file = file.substring(0, file.length() - name.length());
197: if (file.endsWith("\\")) {
198: file = file.substring(0, file.length() - 1);
199: } else if (file.endsWith("/")) {
200: file = file.substring(0, file.length() - 1);
201: }
202: }
203: ANode childNode = null;
204: for (Enumeration children = toNode.children(); children
205: .hasMoreElements();) {
206: ANode child = (ANode) children.nextElement();
207: if (child.getName().equals(file)) {
208: childNode = child;
209: }
210: }
211: if (childNode == null) {
212: childNode = new ModuleNode(file, null);
213: toNode.add(childNode);
214: //System.out.println("created node "+file);
215: model.reload();
216: }
217: addSummary(childNode, name, summary);
218: }
219:
220: private void addSummary(ANode toNode, String name,
221: PackageSummary summary) {
222: //System.out.println("toNode="+toNode+", name="+name+", summary="+summary.getName());
223: if (name.indexOf(".") > 0) {
224: ANode childNode = null;
225: String x = name.substring(0, name.indexOf("."));
226: for (Enumeration children = toNode.children(); children
227: .hasMoreElements();) {
228: ANode child = (ANode) children.nextElement();
229: if (child.getName().equals(x)) {
230: childNode = child;
231: }
232: }
233: if (childNode == null) {
234: childNode = new PackageNode(x, null);
235: toNode.add(childNode);
236: //System.out.println("created node "+x);
237: }
238: addSummary(childNode,
239: name.substring(name.indexOf(".") + 1), summary);
240: } else {
241: ANode childNode = null;
242: for (Enumeration children = toNode.children(); children
243: .hasMoreElements();) {
244: ANode child = (ANode) children.nextElement();
245: if (child.getName().equals(name)) {
246: childNode = child;
247: }
248: }
249: if (childNode == null) {
250: //System.out.println("Adding child node "+name);
251: toNode.add(new PackageNode(name, summary));
252: } else {
253: //System.out.println("Found child node "+name);
254: //System.out.println(" childNode.getUserObject()="+childNode.getUserObject());{
255: NodeData data = (NodeData) childNode.getUserObject();
256: if (data.summary == null && summary != null) {
257: data.summary = summary;
258: }
259: }
260: }
261: }
262:
263: protected static class NodeData {
264: PackageSummary summary;
265:
266: public NodeData(PackageSummary summary) {
267: this .summary = summary;
268: }
269:
270: public int getBeginLine() {
271: return 0;
272: }
273:
274: public PackageSummary getPackageSummary() {
275: return summary;
276: }
277: }
278:
279: /**
280: * Description of the Class
281: *
282: * @author Chris Seguin
283: */
284: protected static class ANode extends DefaultMutableTreeNode {
285: String name;
286:
287: /**
288: * Constructor for the ANode object
289: *
290: * @param name Description of Parameter
291: * @param summary Description of Parameter
292: */
293: public ANode(String name, PackageSummary summary) {
294: this .name = name;
295: setUserObject(new NodeData(summary));
296: }
297:
298: /**
299: * Gets the Line attribute of the ANode object
300: *
301: * @return The Line value
302: */
303: public int getLine() {
304: return ((NodeData) getUserObject()).getBeginLine();
305: }
306:
307: /**
308: * Gets the Name attribute of the ANode object
309: *
310: * @return The Name value
311: */
312: public String getName() {
313: return name;
314: }
315:
316: /**
317: * Description of the Method
318: *
319: * @return Description of the Returned Value
320: */
321: public String toString() {
322: return name;
323: }
324:
325: public void sort(java.util.Comparator comparator) {
326: if (children != null) {
327: List sortedChildren = new ArrayList(children);
328: removeAllChildren();
329: java.util.Collections.sort(sortedChildren, comparator);
330: for (Iterator i = sortedChildren.iterator(); i
331: .hasNext();) {
332: add((ANode) i.next());
333: }
334: }
335: Enumeration i = children();
336: while (i.hasMoreElements()) {
337: ANode child = (ANode) i.nextElement();
338: if (!child.isLeaf()) {
339: child.sort(comparator);
340: }
341: }
342: }
343: }
344:
345: /**
346: * Description of the Class
347: *
348: * @author Chris Seguin
349: */
350: protected static class RootNode extends ANode {
351: /**
352: * Constructor for the ASourceFile object
353: *
354: * @param name Description of Parameter
355: * @param summary Description of Parameter
356: */
357: public RootNode(String name, PackageSummary summary) {
358: super (name, summary);
359: }
360: }
361:
362: protected static class PackageNode extends ANode {
363: public PackageNode(String name, PackageSummary summary) {
364: super (name, summary);
365: }
366: }
367:
368: protected static class ModuleNode extends ANode {
369: public ModuleNode(String name, PackageSummary summary) {
370: super (name, summary);
371: }
372: }
373:
374: private static class NavigatorRenderer extends
375: DefaultTreeCellRenderer {
376: private ImageIcon packageIcon;
377: private ImageIcon emptyPackageIcon;
378: private ImageIcon modulesIcon;
379: private Object value;
380:
381: public NavigatorRenderer() {
382: ClassLoader classLoader = this .getClass().getClassLoader();
383: packageIcon = new ImageIcon(
384: classLoader
385: .getResource("org/acm/seguin/ide/common/icons/package.gif"));
386: emptyPackageIcon = new ImageIcon(
387: classLoader
388: .getResource("org/acm/seguin/ide/common/icons/emptyPackage.gif"));
389: modulesIcon = new ImageIcon(
390: classLoader
391: .getResource("org/acm/seguin/ide/common/icons/modules.gif"));
392: }
393:
394: public Component getTreeCellRendererComponent(JTree tree,
395: Object value, boolean sel, boolean expanded,
396: boolean leaf, int row, boolean hasFocus) {
397: DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
398: Object obj = node.getUserObject();
399:
400: this .value = obj;
401:
402: super .getTreeCellRendererComponent(tree, value, sel,
403: expanded, leaf, row, hasFocus);
404:
405: // Set the icon, depending on what kind of node it is
406: if (node.isRoot()) {
407: setIcon(modulesIcon);
408: } else if (leaf) {
409: setIcon(packageIcon);
410: } else if (node instanceof ModuleNode) {
411: setIcon(modulesIcon);
412: } else if (obj instanceof NodeData) {
413: if (((NodeData) obj).getPackageSummary() != null) {
414: setIcon(packageIcon);
415: } else {
416: setIcon(emptyPackageIcon);
417: }
418: } else {
419: setIcon(emptyPackageIcon);
420: }
421: return this;
422: }
423: }
424: }
|