0001: /*
0002: This program is free software; you can redistribute it and/or
0003: modify it under the terms of the GNU General Public License
0004: as published by the Free Software Foundation; either version 2
0005: of the License, or any later version.
0006: This program is distributed in the hope that it will be useful,
0007: but WITHOUT ANY WARRANTY; without even the implied warranty of
0008: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0009: GNU General Public License for more detaProjectTreeSelectionListenerils.
0010: You should have received a copy of the GNU General Public License
0011: along with this program; if not, write to the Free Software
0012: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
0013: */
0014: package org.acm.seguin.ide.common;
0015:
0016: import java.awt.BorderLayout;
0017: import java.awt.Color;
0018: import java.awt.Component;
0019: import java.awt.Frame;
0020: import java.awt.event.ActionEvent;
0021: import java.awt.event.ActionListener;
0022:
0023: import java.io.Reader;
0024: import java.util.ArrayList;
0025: import java.util.Enumeration;
0026: import java.util.HashMap;
0027: import java.util.Iterator;
0028:
0029: import java.util.List;
0030: import java.util.Map;
0031: import javax.swing.ImageIcon;
0032:
0033: import javax.swing.JPanel;
0034: import javax.swing.JTree;
0035: import javax.swing.Timer;
0036: import javax.swing.event.TreeSelectionEvent;
0037: import javax.swing.event.TreeSelectionListener;
0038: import javax.swing.text.Segment;
0039: import javax.swing.tree.*;
0040: import net.sourceforge.jrefactory.ast.*;
0041: import net.sourceforge.jrefactory.parser.JavaParser;
0042: import net.sourceforge.jrefactory.parser.JavaParserVisitorAdapter;
0043: import net.sourceforge.jrefactory.parser.ParseException;
0044: import net.sourceforge.jrefactory.parser.TokenMgrError;
0045:
0046: import org.acm.seguin.util.FileSettings;
0047:
0048: /**
0049: * Main GUI for JRefactory
0050: *
0051: * @author <a href="mailto:JRefactoryPlugin@ladyshot.demon.co.uk">Mike Atkinson</a>
0052: * @since 0.0.1
0053: * @created 23 July 2003
0054: * @version $Id: Navigator.java,v 1.5 2003/12/04 13:51:32 mikeatkinson Exp $
0055: */
0056: public final class Navigator extends JPanel {
0057: private Frame view;
0058: private JTree tree;
0059: private DefaultTreeModel model;
0060: private final DefaultMutableTreeNode DEFAULT_NODE;
0061: private final static String NAME = "Navigator";
0062: private static Map viewToNavigation = new HashMap();
0063: private final static int DEFAULT_PARSER_PRIORITY = Thread.MIN_PRIORITY;
0064:
0065: private static AlphabeticalOrderComparator alphabeticalOrderComparator = new AlphabeticalOrderComparator();
0066:
0067: private static StandardOrderComparator standardOrderComparator = new StandardOrderComparator();
0068:
0069: /**
0070: * The instance of BugCellRenderer.
0071: *
0072: * @since 2.9.12
0073: */
0074: private final static Navigator.NavigatorRenderer navigatorRenderer = new Navigator.NavigatorRenderer();
0075:
0076: /**
0077: * Constructor for the Navigator object
0078: *
0079: * @param aView Description of Parameter
0080: * @since 2.9.12
0081: */
0082: public Navigator(Frame aView) {
0083: super (new BorderLayout());
0084: //System.out.println("new Navigator(" + view + ")");
0085: view = aView;
0086: viewCreated(view);
0087: //JavaStylePlugin.addNavigator(this);
0088: tree = new JTree();
0089: DEFAULT_NODE = new DefaultMutableTreeNode("classes");
0090: model = new DefaultTreeModel(DEFAULT_NODE);
0091: tree.setModel(model);
0092: tree.setCellRenderer(navigatorRenderer);
0093: tree.addTreeSelectionListener(new TreeSelectionListener() {
0094: public void valueChanged(TreeSelectionEvent evt) {
0095: DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree
0096: .getLastSelectedPathComponent();
0097:
0098: if (node != null) {
0099: if (node.isLeaf() && node instanceof ANode) {
0100: ANode aNode = (ANode) node;
0101: //gotoViolation(violation);
0102: (new RunGotoNode(aNode, view)).run();
0103: } else if (node instanceof AConstructor
0104: || node instanceof AMethod
0105: || node instanceof AClass
0106: || node instanceof AnInterface) {
0107: ANode aNode = (ANode) node;
0108: //gotoViolation(violation);
0109: (new RunGotoNode(aNode, view)).run();
0110: }
0111: }
0112: }
0113: });
0114: add(tree);
0115: }
0116:
0117: /**
0118: * Description of the Method
0119: *
0120: * @since 2.9.12
0121: */
0122: public void reconfigure() {
0123: // reset the properties like popup display, etc.
0124: //FIXME: for (Iterator it = viewToNavigation.keySet().iterator(); it.hasNext();){
0125: //FIXME: Navigation nav = (Navigation) viewToNavigation.get(it.next());
0126: //FIXME: nav.reconfigure();
0127: //FIXME: }
0128: }
0129:
0130: /**
0131: * Description of the Method
0132: *
0133: * @param aFile Description of Parameter
0134: * @since 2.9.12
0135: */
0136: public void updateTree(DefaultTreeModel aFile) {
0137: ASourceFile root = (ASourceFile) aFile.getRoot();
0138: root.sort(standardOrderComparator);
0139: String filename = root.getName();
0140: Enumeration children = DEFAULT_NODE.children();
0141: //System.out.println(" filename="+filename);
0142: while (children.hasMoreElements()) {
0143: ASourceFile sourceFile = (ASourceFile) children
0144: .nextElement();
0145: //System.out.println(" child="+sourceFile.getName());
0146: if (filename.equals(sourceFile.getName())) {
0147: //TreePath path = new TreePath(sourceFile.getPath());
0148: List paths = new ArrayList();
0149: for (Enumeration x = sourceFile.depthFirstEnumeration(); x
0150: .hasMoreElements();) {
0151: TreeNode[] nds = ((ANode) x.nextElement())
0152: .getPath();
0153: paths.add(new PathData(nds, tree
0154: .isExpanded(new TreePath(nds))));
0155: }
0156: sourceFile.removeAllChildren();
0157: for (Enumeration newChildren = root.children(); newChildren
0158: .hasMoreElements();) {
0159: sourceFile.add((DefaultMutableTreeNode) newChildren
0160: .nextElement());
0161: }
0162: //System.out.println("updateTree(): structureChanged");
0163: int oldCount = paths.size();
0164: int newCount = 0;
0165: for (Enumeration np = sourceFile
0166: .depthFirstEnumeration(); np.hasMoreElements();) {
0167: np.nextElement();
0168: newCount++;
0169: }
0170: Enumeration np = sourceFile.depthFirstEnumeration();
0171: for (Iterator p = paths.iterator(); p.hasNext();) {
0172: PathData pathdata = (PathData) p.next();
0173: if (!np.hasMoreElements()) {
0174: break;
0175: }
0176: TreeNode[] newPath = ((ANode) np.nextElement())
0177: .getPath();
0178: if (!comparePaths(pathdata.path, newPath)) {
0179: //System.out.println("paths different");
0180: //System.out.println(" newPath=");
0181: //for (int i=0; i<newPath.length; i++) {
0182: // System.out.println(" "+newPath[i]);
0183: //}
0184: //System.out.println(" pd.path=");
0185: //for (int i=0; i<pd.path.length; i++) {
0186: // System.out.println(" "+pd.path[i]);
0187: //}
0188: model
0189: .nodeStructureChanged(newPath[newPath.length - 1]);
0190: model
0191: .nodeStructureChanged(newPath[newPath.length - 2]);
0192: if (newPath.length >= 3) {
0193: model
0194: .nodeStructureChanged(newPath[newPath.length - 3]);
0195: }
0196: if (oldCount > newCount) {
0197: if (!p.hasNext()) {
0198: break;
0199: }
0200: pathdata = (PathData) p.next();
0201: //System.out.println(" new pd.path=");
0202: //for (int i=0; i<pd.path.length; i++) {
0203: // System.out.println(" "+pd.path[i]);
0204: //}
0205: } else if (newCount > oldCount) {
0206: if (!np.hasMoreElements()) {
0207: break;
0208: }
0209: newPath = ((ANode) np.nextElement())
0210: .getPath();
0211: //System.out.println(" new newPath=");
0212: //for (int i=0; i<newPath.length; i++) {
0213: // System.out.println(" "+newPath[i]);
0214: //}
0215: }
0216: }
0217: if (pathdata.expanded) {
0218: //System.out.println("expanded");
0219: //for (int i=0; i<newPath.length; i++) {
0220: // System.out.println(" "+newPath[i]);
0221: //}
0222: tree.expandPath(new TreePath(newPath));
0223: }
0224: }
0225:
0226: return;
0227: }
0228: }
0229: DEFAULT_NODE.add(root);
0230: //TreeNode c = root.getChildAt(0);
0231: //System.out.println("updateTree(): node added");
0232: //System.out.println(" name="+((ANode)c).getName());
0233: model.nodesWereInserted(DEFAULT_NODE, new int[] { model
0234: .getIndexOfChild(DEFAULT_NODE, root) });
0235: }
0236:
0237: /**
0238: * Description of the Method
0239: *
0240: * @param aFile Description of Parameter
0241: * @since 2.9.12
0242: */
0243: public void removeNodeFromTree(DefaultTreeModel aFile) {
0244: ASourceFile root = (ASourceFile) aFile.getRoot();
0245: String filename = root.getName();
0246: Enumeration children = DEFAULT_NODE.children();
0247: while (children.hasMoreElements()) {
0248: ASourceFile sourcefile = (ASourceFile) children
0249: .nextElement();
0250: if (filename.equals(sourcefile.getName())) {
0251: model.removeNodeFromParent(sourcefile);
0252: return;
0253: }
0254: }
0255: }
0256:
0257: /**
0258: * Description of the Method
0259: *
0260: * @param view Description of Parameter
0261: * @since 2.9.12
0262: */
0263: public void viewCreated(Frame view) {
0264: viewToNavigation.put(view, new Navigation(view, this ));
0265: }
0266:
0267: /**
0268: * Adds a feature to the buffer attribute of the Navigator object
0269: *
0270: * @param buffer The feature to be added to the buffer attribute
0271: * @since 2.9.12
0272: */
0273: public void addBuffer(Object buffer) {
0274: for (Iterator i = viewToNavigation.keySet().iterator(); i
0275: .hasNext();) {
0276: Navigation nav = (Navigation) viewToNavigation
0277: .get(i.next());
0278: nav.addBuffer(buffer);
0279: }
0280: }
0281:
0282: /**
0283: * Description of the Method
0284: *
0285: * @param buffer Description of Parameter
0286: * @since 2.9.12
0287: */
0288: public void removeBuffer(Object buffer) {
0289: for (Iterator i = viewToNavigation.keySet().iterator(); i
0290: .hasNext();) {
0291: Navigation nav = (Navigation) viewToNavigation
0292: .get(i.next());
0293: nav.removeBuffer(buffer);
0294: }
0295: }
0296:
0297: /**
0298: * Description of the Method
0299: *
0300: * @param view Description of Parameter
0301: * @param buffer Description of Parameter
0302: * @param offset Description of Parameter
0303: * @param length Description of Parameter
0304: * @since 2.9.12
0305: */
0306: public void contentInserted(Frame view, Object buffer, int offset,
0307: int length) {
0308: for (Iterator i = viewToNavigation.keySet().iterator(); i
0309: .hasNext();) {
0310: Navigation nav = (Navigation) (viewToNavigation.get(i
0311: .next()));
0312: JavaParserThread jpt = (JavaParserThread) nav.mapBufferToParser
0313: .get(buffer);
0314: if (jpt != null) {
0315: jpt.contentInserted(offset, length);
0316: }
0317: }
0318: }
0319:
0320: /**
0321: * Description of the Method
0322: *
0323: * @param view Description of Parameter
0324: * @param buffer Description of Parameter
0325: * @param offset Description of Parameter
0326: * @param length Description of Parameter
0327: * @since 2.9.12
0328: */
0329: public void contentRemoved(Frame view, Object buffer, int offset,
0330: int length) {
0331: for (Iterator i = viewToNavigation.keySet().iterator(); i
0332: .hasNext();) {
0333: Navigation nav = (Navigation) (viewToNavigation.get(i
0334: .next()));
0335: JavaParserThread jpt = (JavaParserThread) nav.mapBufferToParser
0336: .get(buffer);
0337: if (jpt != null) {
0338: jpt.contentRemoved(offset, length);
0339: }
0340: }
0341: }
0342:
0343: /**
0344: * Description of the Method
0345: *
0346: * @param view Description of Parameter
0347: * @param buffer Description of Parameter
0348: * @since 2.9.12
0349: */
0350: public void transactionComplete(Frame view, Object buffer) {
0351: for (Iterator i = viewToNavigation.keySet().iterator(); i
0352: .hasNext();) {
0353: Navigation nav = (Navigation) (viewToNavigation.get(i
0354: .next()));
0355: JavaParserThread jpt = (JavaParserThread) nav.mapBufferToParser
0356: .get(buffer);
0357: if (jpt != null) {
0358: jpt.transactionComplete();
0359: }
0360: }
0361: }
0362:
0363: /**
0364: * Description of the Method
0365: *
0366: * @param path1 Description of Parameter
0367: * @param path2 Description of Parameter
0368: * @return Description of the Returned Value
0369: * @since 2.9.12
0370: */
0371: private boolean comparePaths(TreeNode[] path1, TreeNode[] path2) {
0372: if (path1.length != path2.length) {
0373: return false;
0374: }
0375: for (int i = 0; i < path1.length; i++) {
0376: if (!path1[i].toString().equals(path2[i].toString())) {
0377: return false;
0378: }
0379: }
0380: return true;
0381: }
0382:
0383: /**
0384: * Description of the Method
0385: *
0386: * @param view Description of Parameter
0387: * @since 2.9.12
0388: */
0389: public static void viewClosed(Frame view) {
0390: Navigation nav = (Navigation) (viewToNavigation.get(view));
0391: nav.stop();
0392: viewToNavigation.remove(view);
0393: }
0394:
0395: /**
0396: * Description of the Class
0397: *
0398: * @author Mike Atkinson
0399: * @since 2.9.12
0400: */
0401: private class PathData {
0402: TreeNode[] path;
0403: boolean expanded;
0404:
0405: /**
0406: * Constructor for the PathData object
0407: *
0408: * @param path Description of Parameter
0409: * @param expanded Description of Parameter
0410: * @since 2.9.12
0411: */
0412: PathData(TreeNode[] path, boolean expanded) {
0413: this .path = path;
0414: this .expanded = expanded;
0415: }
0416: }
0417:
0418: /**
0419: * Description of the Class
0420: *
0421: * @author Mike Atkinson
0422: * @since 2.9.12
0423: */
0424: private static class AlphabeticalOrderComparator implements
0425: java.util.Comparator {
0426: /**
0427: * Description of the Method
0428: *
0429: * @param lhs Description of Parameter
0430: * @param rhs Description of Parameter
0431: * @return Description of the Returned Value
0432: * @since 2.9.12
0433: */
0434: public int compare(Object lhs, Object rhs) {
0435: if (lhs instanceof AClass) {
0436: if (rhs instanceof AClass) {
0437: int value = ((ANode) lhs).getName().compareTo(
0438: ((ANode) rhs).getName());
0439: //System.out.println("class lhs="+((ANode)lhs).getName()+", rhs="+((ANode)rhs).getName() +" => "+value);
0440: return value;
0441: } else {
0442: return 1;
0443: }
0444: } else if (rhs instanceof AClass) {
0445: return -1;
0446: }
0447: int value = ((ANode) lhs).getName().compareTo(
0448: ((ANode) rhs).getName());
0449: //System.out.println("other lhs="+((ANode)lhs).getName()+", rhs="+((ANode)rhs).getName() +" => "+value);
0450: return value;
0451: }
0452:
0453: }
0454:
0455: /**
0456: * Description of the Class
0457: *
0458: * @author Mike Atkinson
0459: * @since 2.9.12
0460: */
0461: private static class StandardOrderComparator implements
0462: java.util.Comparator {
0463: /**
0464: * Description of the Method
0465: *
0466: * @param lhs Description of Parameter
0467: * @param rhs Description of Parameter
0468: * @return Description of the Returned Value
0469: * @since 2.9.12
0470: */
0471: public int compare(Object lhs, Object rhs) {
0472: if (lhs instanceof AField) {
0473: if (rhs instanceof AField) {
0474: return ((AField) lhs).getName().compareTo(
0475: ((AField) rhs).getName());
0476: }
0477: return -1;
0478: } else if (rhs instanceof AField) {
0479: return 1;
0480: }
0481: if (lhs instanceof AConstructor) {
0482: if (rhs instanceof AConstructor) {
0483: return ((AConstructor) lhs).getName().compareTo(
0484: ((AConstructor) rhs).getName());
0485: }
0486: return -1;
0487: } else if (rhs instanceof AConstructor) {
0488: return 1;
0489: }
0490: if (lhs instanceof AMethod) {
0491: if (rhs instanceof AMethod) {
0492: return ((AMethod) lhs).getName().compareTo(
0493: ((AMethod) rhs).getName());
0494: }
0495: return -1;
0496: } else if (rhs instanceof AMethod) {
0497: return 1;
0498: }
0499: if (lhs instanceof AnInterface) {
0500: if (rhs instanceof AnInterface) {
0501: return ((AnInterface) lhs).getName().compareTo(
0502: ((AnInterface) rhs).getName());
0503: }
0504: return -1;
0505: } else if (rhs instanceof AnInterface) {
0506: return 1;
0507: }
0508: if (lhs instanceof AClass) {
0509: if (rhs instanceof AClass) {
0510: return ((AClass) lhs).getName().compareTo(
0511: ((AClass) rhs).getName());
0512: }
0513: return -1;
0514: } else if (rhs instanceof AClass) {
0515: return 1;
0516: }
0517: return ((ANode) lhs).getName().compareTo(
0518: ((ANode) rhs).getName());
0519: }
0520: }
0521:
0522: /**
0523: * Description of the Class
0524: *
0525: * @author Chris Seguin
0526: * @since 2.9.12
0527: */
0528: private static class Navigation {
0529: Map mapBufferToParser = new HashMap();
0530: Timer timerPopup = null;
0531: //private List buffers;
0532: private final Frame view;
0533: private final Navigator navigator;
0534:
0535: /**
0536: * Constructor for the Navigation object
0537: *
0538: * @param view Description of Parameter
0539: * @param navigator Description of Parameter
0540: * @since 2.9.12
0541: */
0542: public Navigation(Frame view, Navigator navigator) {
0543: //System.out.println("new Navigation(" + view + ")");
0544: this .view = view;
0545: this .navigator = navigator;
0546: }
0547:
0548: /**
0549: * Description of the Method
0550: *
0551: * @since 2.9.12
0552: */
0553: public void stop() {
0554: IDEPlugin.log(IDEInterface.MESSAGE, NAME,
0555: "Stopping DotComplete for view " + view.getName());
0556: // stop all parsers (kind of round about b/c otherwise we get ConcurrentModEx)
0557: IDEPlugin.log(IDEInterface.MESSAGE, NAME, "buffers "
0558: + mapBufferToParser.keySet().size());
0559: Object[] buffers = new Object[mapBufferToParser.keySet()
0560: .size()];
0561: int buf = 0;
0562: for (Iterator it = mapBufferToParser.keySet().iterator(); it
0563: .hasNext(); buf++) {
0564: buffers[buf] = (Object) it.next();
0565: }
0566: for (int i = 0, l = buffers.length; i < l; i++) {
0567: removeBuffer(buffers[i]);
0568: }
0569:
0570: // unlock and popups and dispose them
0571: IDEPlugin.log(IDEInterface.MESSAGE, NAME, "Done");
0572: }
0573:
0574: /**
0575: * Adds a feature to the Buffer attribute of the Navigation object
0576: *
0577: * @param buffer The feature to be added to the Buffer attribute
0578: * @since 2.9.12
0579: */
0580: synchronized void addBuffer(Object buffer) {
0581: try {
0582: if (IDEPlugin.getFilePathForBuffer(buffer).trim()
0583: .toLowerCase().endsWith(".java")) {
0584: if (!mapBufferToParser.containsKey(buffer)) {
0585: // first, get the class path source
0586: JavaParserThread jpt = new JavaParserThread(
0587: view, navigator);
0588: jpt.init(buffer, IDEPlugin
0589: .getFilePathForBuffer(buffer),
0590: new java.io.StringReader(IDEPlugin
0591: .getText(view, buffer)));
0592: mapBufferToParser.put(buffer, jpt);
0593: jpt.start();
0594: }
0595: }
0596: } catch (Exception e) {
0597: IDEPlugin.log(IDEInterface.MESSAGE, NAME, e
0598: .getMessage());
0599: }
0600: }
0601:
0602: /**
0603: * Description of the Method
0604: *
0605: * @param buffer Description of Parameter
0606: * @since 2.9.12
0607: */
0608: synchronized void removeBuffer(Object buffer) {
0609: IDEPlugin.log(IDEInterface.MESSAGE, NAME,
0610: "removing buffer!");
0611: JavaParserThread jpt = (JavaParserThread) mapBufferToParser
0612: .get(buffer);
0613: if (jpt != null) {
0614: jpt.stopSoon();
0615: try {
0616: IDEPlugin
0617: .log(
0618: IDEInterface.DEBUG,
0619: NAME,
0620: "Waiting 5 seconds for thread to stop "
0621: + IDEPlugin
0622: .getFilePathForBuffer(buffer));
0623: jpt.join(5 * 1000);
0624: IDEPlugin
0625: .log(
0626: IDEInterface.DEBUG,
0627: NAME,
0628: "Joined successfully! "
0629: + IDEPlugin
0630: .getFilePathForBuffer(buffer));
0631: } catch (InterruptedException e) {
0632: IDEPlugin
0633: .log(
0634: IDEInterface.ERROR,
0635: "Error waiting for Parse thread to exit",
0636: e);
0637: }
0638: }
0639: mapBufferToParser.remove(buffer);
0640: PTVData data = new PTVData(IDEPlugin
0641: .getFilePathForBuffer(buffer));
0642: navigator.removeNodeFromTree(data.model);
0643: }
0644: }
0645:
0646: /**
0647: * Description of the Class
0648: *
0649: * @author Chris Seguin
0650: * @since 2.9.12
0651: */
0652: private final static class JavaParserThread extends Thread {
0653: JavaParser parser;
0654: private Object buffer = null;
0655: private String path = null;
0656: private Reader reader = null;
0657: private boolean docChange;
0658: private boolean dirty;
0659: private boolean firstPass;
0660: private boolean generateSyntaxErrorInfo = false;
0661: private boolean generateSemanticErrorInfo = false;
0662: private Navigator navigator;
0663: private Frame view;
0664:
0665: private boolean bRun = true; // adding for safer stopping of parse thread
0666: private Timer docTimer = null;
0667: private FileSettings settings;
0668:
0669: /**
0670: * Constructor for the JavaParserThread object
0671: *
0672: * @param view Description of Parameter
0673: * @param navigator Description of Parameter
0674: * @since 2.9.12
0675: */
0676: public JavaParserThread(Frame view, Navigator navigator) {
0677: this .view = view;
0678: this .navigator = navigator;
0679: setName("JavaParser");
0680: setPriority(DEFAULT_PARSER_PRIORITY);
0681: parser = new JavaParser((Reader) null);
0682: settings = FileSettings.getRefactoryPrettySettings();
0683: docChange = false;
0684: dirty = false;
0685: firstPass = true;
0686: }
0687:
0688: /**
0689: * Sets the DocChange attribute of the JavaParserThread object
0690: *
0691: * @param docChange The new DocChange value
0692: * @since 2.9.12
0693: */
0694: public void setDocChange(boolean docChange) {
0695: this .docChange = docChange;
0696: }
0697:
0698: /**
0699: * Description of the Method
0700: *
0701: * @param reader Description of Parameter
0702: * @param path Description of Parameter
0703: * @since 2.9.12
0704: */
0705: public void init(Reader reader, String path) {
0706: this .reader = reader;
0707: this .path = path;
0708: }
0709:
0710: /**
0711: * Description of the Method
0712: *
0713: * @param buffer Description of Parameter
0714: * @param path Description of Parameter
0715: * @param reader Description of Parameter
0716: * @since 2.9.12
0717: */
0718: public void init(Object buffer, String path, Reader reader) {
0719: init(reader, path);
0720: this .buffer = buffer;
0721: docChange = true;
0722: }
0723:
0724: /**
0725: * Main processing method for the JavaParserThread object
0726: *
0727: * @since 2.9.12
0728: */
0729: public void run() {
0730: if (reader == null) {
0731: throw new IllegalStateException(
0732: "Must call init() before run().");
0733: }
0734:
0735: if (buffer != null) {
0736: do {
0737: // sleep until a change is made to the document
0738: while (!docChange) {
0739: try {
0740: synchronized (this ) {
0741: wait();
0742: }
0743: } catch (InterruptedException iex) {
0744: docChange = false;
0745: bRun = false;
0746: return;
0747: }
0748: }
0749: docChange = false;
0750:
0751: // only do the parsing if the
0752: boolean enableNavigator = true;
0753: try {
0754: enableNavigator = settings
0755: .getBoolean("navigator.enable");
0756: } catch (Exception snfe) {
0757: // Default is sufficient
0758: }
0759: if (firstPass || enableNavigator) {
0760: firstPass = false;
0761: //System.out.println("buffer="+buffer);
0762: String text = IDEPlugin.getText(view, buffer);
0763: //String name = IDEPlugin.getFilePathForBuffer(buffer);
0764: reader = new java.io.StringReader(text);
0765: IDEPlugin.log(IDEInterface.MESSAGE, NAME,
0766: "PARSE @"
0767: + new java.util.Date()
0768: .toString() + " - "
0769: + path);
0770: try {
0771: oneParsePass();
0772: } catch (NullPointerException e) {
0773: e.printStackTrace();
0774: IDEPlugin.log(IDEInterface.ERROR,
0775: "Navigator: NPE, Error parsing "
0776: + path, e);
0777: } catch (Throwable t) {
0778: IDEPlugin.log(IDEInterface.ERROR,
0779: "Navigator: Error parsing " + path,
0780: t);
0781: }
0782: }
0783: } while (bRun);
0784: //if (generateSyntaxErrorInfo || generateSemanticErrorInfo) {
0785: // errorTable.replace(getPath(), new ErrorTable());
0786: //}
0787: } else {
0788: oneParsePass();
0789: }
0790: }
0791:
0792: /**
0793: * Called when text is inserted into the buffer. Reparses the buffer when more than 16 characters are inserted or
0794: * ; or }
0795: *
0796: * @param offset Description of Parameter
0797: * @param length Description of Parameter
0798: * @since 2.9.12
0799: */
0800: public void contentInserted(int offset, int length) {
0801: IDEPlugin.log(IDEInterface.DEBUG, this , "insertUpdate: "
0802: + length + "]");
0803: if (length >= 16) {
0804: docChange = true;
0805: //System.out.println("contentInserted(" + offset + "," + length + ") more than 16 chars so notify");
0806: synchronized (this ) {
0807: notify();
0808: }
0809: } else {
0810: String text = IDEPlugin.getText(view, buffer);
0811: char[] array = text.substring(offset, offset + length)
0812: .toCharArray();
0813:
0814: for (int i = 0; i < length; i++) {
0815: //System.out.println("array["+i+"]='"+array[i]+"'");
0816: if (array[i] == ';' || array[i] == '}') {
0817: docChange = true;
0818: //System.out.println("contentInserted(" + offset + "," + length + ") array[" + i + "]=" + array[i] + " so notify");
0819: synchronized (this ) {
0820: notify();
0821: }
0822: break;
0823: }
0824: }
0825: }
0826:
0827: if (!docChange) {
0828: //System.out.println("docChange==false");
0829: if (docTimer == null) {
0830: //System.out.println("starting timer");
0831: docTimer = new Timer(5000, new DocRunner(this ));
0832: docTimer.start();
0833: } else {
0834: //System.out.println("restarting timer");
0835: docTimer.restart();
0836: }
0837: }
0838: }
0839:
0840: /**
0841: * Description of the Method
0842: *
0843: * @param offset Description of Parameter
0844: * @param length Description of Parameter
0845: * @since 2.9.12
0846: */
0847: public void contentRemoved(int offset, int length) {
0848: // Called when text is removed from the buffer.
0849: // Reparses the buffer when more than 2 characters are deleted
0850: IDEPlugin.log(IDEInterface.DEBUG, this , "removeUpdate: "
0851: + length + "]");
0852: if (length >= 16) {
0853: docChange = true;
0854: //System.out.println("contentRemoved(" + offset + "," + length + ") more than 16 chars so notify");
0855: synchronized (this ) {
0856: notify();
0857: }
0858: } else {
0859: if (docTimer == null) {
0860: //System.out.println("starting timer");
0861: docTimer = new Timer(5000, new DocRunner(this ));
0862: docTimer.start();
0863: } else {
0864: //System.out.println("restarting timer");
0865: docTimer.restart();
0866: }
0867: }
0868: }
0869:
0870: /**
0871: * Called after an undo or compound edit has finished.
0872: *
0873: * @since 2.9.12
0874: */
0875: public void transactionComplete() {
0876: //System.out.println("transactionComplete() so notify");
0877: synchronized (this ) {
0878: notify();
0879: }
0880: }
0881:
0882: /**
0883: * Avoids using Thread.stop()
0884: *
0885: * @since 2.9.12
0886: */
0887: public synchronized void stopSoon() {
0888: if (buffer != null) {
0889: docChange = true;
0890: bRun = false;
0891: }
0892: notify();
0893: }
0894:
0895: /**
0896: * Description of the Method
0897: *
0898: * @since 2.9.12
0899: */
0900: private void oneParsePass() {
0901: parser.ReInit(reader);
0902:
0903: preParse();
0904: try {
0905:
0906: ASTCompilationUnit compilationUnit = parser
0907: .CompilationUnit();
0908: ParseTreeVisitor visitor = new ParseTreeVisitor();
0909: PTVData data = new PTVData(path);
0910: visitor.visit(compilationUnit, data);
0911: navigator.updateTree(data.model);
0912: IDEPlugin.bufferParsed(view, buffer, compilationUnit);
0913: IDEPlugin.bufferNavigatorTree(view, buffer,
0914: (TreeNode) data.model.getRoot());
0915: } catch (ParseException pex) {
0916: //if (generateSyntaxErrorInfo) {
0917: // error(pex.currentToken.next, "Syntax error.");
0918: //}
0919: //pex.printStackTrace(System.err);
0920: } catch (TokenMgrError tme) {
0921: //tme.printStackTrace(System.err);
0922: }
0923: postParse();
0924: }
0925:
0926: /**
0927: * Description of the Method
0928: *
0929: * @since 2.9.12
0930: */
0931: private void preParse() {
0932: }
0933:
0934: /**
0935: * Description of the Method
0936: *
0937: * @since 2.9.12
0938: */
0939: private synchronized void postParse() {
0940: }
0941:
0942: /**
0943: * Description of the Class
0944: *
0945: * @author Mike Atkinson
0946: * @since 2.9.12
0947: */
0948: private class DocRunner implements ActionListener {
0949: JavaParserThread runner;
0950:
0951: /**
0952: * Constructor for the DocRunner object
0953: *
0954: * @param jpt Description of Parameter
0955: * @since 2.9.12
0956: */
0957: public DocRunner(JavaParserThread jpt) {
0958: runner = jpt;
0959: }
0960:
0961: /**
0962: * Description of the Method
0963: *
0964: * @param event Description of Parameter
0965: * @since 2.9.12
0966: */
0967: public void actionPerformed(ActionEvent event) {
0968: docTimer.stop();
0969: docTimer = null;
0970: //System.out.println("stopped timer - notify");
0971: docChange = true;
0972: synchronized (runner) {
0973: runner.notify();
0974: }
0975: }
0976: }
0977:
0978: }
0979:
0980: /**
0981: * Description of the Class
0982: *
0983: * @author Chris Seguin
0984: * @since 2.9.12
0985: */
0986: private static class ParseTreeVisitor extends
0987: JavaParserVisitorAdapter {
0988: /**
0989: * Description of the Method
0990: *
0991: * @param node Description of Parameter
0992: * @param data Description of Parameter
0993: * @return Description of the Returned Value
0994: * @since 2.9.12
0995: */
0996: public Object visit(ASTInterfaceDeclaration node, Object data) {
0997: String className = node.getUnmodifedInterfaceDeclaration()
0998: .getImage();
0999: PTVData ptv = (PTVData) data;
1000: ptv.push(new AClass(className, node));
1001: super .visit(node, data);
1002: ptv.pop();
1003: return ptv;
1004: }
1005:
1006: /**
1007: * Description of the Method
1008: *
1009: * @param node Description of Parameter
1010: * @param data Description of Parameter
1011: * @return Description of the Returned Value
1012: * @since 2.9.12
1013: */
1014: public Object visit(ASTNestedInterfaceDeclaration node,
1015: Object data) {
1016: String className = node.getUnmodifedInterfaceDeclaration()
1017: .getImage();
1018: PTVData ptv = (PTVData) data;
1019: ptv.push(new AClass(className, node));
1020: super .visit(node, data);
1021: ptv.pop();
1022: return ptv;
1023: }
1024:
1025: /**
1026: * Outer class declaration
1027: *
1028: * @param node Description of Parameter
1029: * @param data Description of Parameter
1030: * @return Description of the Returned Value
1031: * @since 2.9.12
1032: */
1033: public Object visit(ASTClassDeclaration node, Object data) {
1034: String className = ((ASTUnmodifiedClassDeclaration) node
1035: .jjtGetFirstChild()).getImage();
1036: PTVData ptv = (PTVData) data;
1037: ptv.push(new AClass(className, node));
1038: super .visit(node, data);
1039: ptv.pop();
1040: return ptv;
1041: }
1042:
1043: /**
1044: * Description of the Method
1045: *
1046: * @param node Description of Parameter
1047: * @param data Description of Parameter
1048: * @return Description of the Returned Value
1049: * @since 2.9.12
1050: */
1051: public Object visit(ASTNestedClassDeclaration node, Object data) {
1052: String className = ((ASTUnmodifiedClassDeclaration) node
1053: .jjtGetFirstChild()).getImage();
1054: PTVData ptv = (PTVData) data;
1055: ptv.push(new AClass(className, node));
1056: super .visit(node, data);
1057: ptv.pop();
1058: return ptv;
1059: }
1060:
1061: /**
1062: * Description of the Method
1063: *
1064: * @param node Description of Parameter
1065: * @param data Description of Parameter
1066: * @return Description of the Returned Value
1067: * @since 2.9.12
1068: */
1069: public Object visit(ASTClassBody node, Object data) {
1070: if (node.jjtGetParent() instanceof ASTUnmodifiedClassDeclaration) {
1071: return super .visit(node, data);
1072: }
1073: PTVData ptv = (PTVData) data;
1074: ptv.push(new AClass("<anonymous>", node));
1075: super .visit(node, data);
1076: ptv.pop();
1077: return ptv;
1078: }
1079:
1080: /**
1081: * Description of the Method
1082: *
1083: * @param node Description of Parameter
1084: * @param data Description of Parameter
1085: * @return Description of the Returned Value
1086: * @since 2.9.12
1087: */
1088: public Object visit(ASTMethodDeclaration node, Object data) {
1089: for (int n = 0; n < node.jjtGetNumChildren(); n++) {
1090: SimpleNode child = (SimpleNode) node.jjtGetChild(n);
1091: if (child instanceof ASTMethodDeclarator) {
1092: String methodName = child.getImage();
1093: PTVData ptv = (PTVData) data;
1094: ptv.push(new AMethod(methodName, node));
1095: super .visit(node, data);
1096: ptv.pop();
1097: return ptv;
1098: }
1099: }
1100: super .visit(node, data);
1101: return data;
1102: }
1103:
1104: /**
1105: * Description of the Method
1106: *
1107: * @param node Description of Parameter
1108: * @param data Description of Parameter
1109: * @return Description of the Returned Value
1110: * @since 2.9.12
1111: */
1112: public Object visit(ASTConstructorDeclaration node, Object data) {
1113: String constructorName = node.getName();
1114: PTVData ptv = (PTVData) data;
1115: ptv.push(new AConstructor(constructorName, node));
1116: super .visit(node, data);
1117: ptv.pop();
1118: return ptv;
1119: }
1120:
1121: /**
1122: * Description of the Method
1123: *
1124: * @param node Description of Parameter
1125: * @param data Description of Parameter
1126: * @return Description of the Returned Value
1127: * @since 2.9.12
1128: */
1129: public Object visit(ASTFieldDeclaration node, Object data) {
1130: List fields = node
1131: .findChildrenOfType(ASTVariableDeclaratorId.class);
1132: if (fields.size() > 0) {
1133: String fieldName = ((ASTVariableDeclaratorId) fields
1134: .get(0)).getName();
1135: PTVData ptv = (PTVData) data;
1136: ptv.push(new AField(fieldName, node));
1137: super .visit(node, data);
1138: ptv.pop();
1139: } else {
1140: super .visit(node, data);
1141: }
1142: return data;
1143: }
1144:
1145: }
1146:
1147: /**
1148: * Description of the Class
1149: *
1150: * @author Chris Seguin
1151: * @since 2.9.12
1152: */
1153: private static class PTVData {
1154: /**
1155: * Description of the Field
1156: *
1157: * @since 2.9.12
1158: */
1159: public DefaultTreeModel model;
1160: /**
1161: * Description of the Field
1162: *
1163: * @since 2.9.12
1164: */
1165: public DefaultMutableTreeNode currentNode;
1166:
1167: /**
1168: * Constructor for the PTVData object
1169: *
1170: * @param name Description of Parameter
1171: * @since 2.9.12
1172: */
1173: public PTVData(String name) {
1174: currentNode = new ASourceFile(name, null);
1175: model = new DefaultTreeModel(currentNode);
1176: }
1177:
1178: /**
1179: * Description of the Method
1180: *
1181: * @param child Description of Parameter
1182: * @since 2.9.12
1183: */
1184: public void push(DefaultMutableTreeNode child) {
1185: currentNode.add(child);
1186: currentNode = child;
1187: }
1188:
1189: /**
1190: * Description of the Method
1191: *
1192: * @since 2.9.12
1193: */
1194: public void pop() {
1195: currentNode = (DefaultMutableTreeNode) currentNode
1196: .getParent();
1197: }
1198: }
1199:
1200: /**
1201: * Description of the Class
1202: *
1203: * @author Mike Atkinson
1204: * @since 2.9.12
1205: */
1206: private static class NodeData extends ModifierAdapter {
1207: private int beginLine;
1208:
1209: /**
1210: * Constructor for the NodeData object
1211: *
1212: * @param node Description of Parameter
1213: * @since 2.9.12
1214: */
1215: public NodeData(SimpleNode node) {
1216: beginLine = (node == null) ? 0 : node.getBeginLine();
1217: if (node instanceof AccessNode) {
1218: setModifiers(((AccessNode) node).getModifiers());
1219: }
1220: }
1221:
1222: /**
1223: * Gets the beginLine attribute of the NodeData object
1224: *
1225: * @return The beginLine value
1226: * @since 2.9.12
1227: */
1228: public int getBeginLine() {
1229: return beginLine;
1230: }
1231: }
1232:
1233: /**
1234: * Description of the Class
1235: *
1236: * @author Chris Seguin
1237: * @since 2.9.12
1238: */
1239: private static class ANode extends DefaultMutableTreeNode {
1240: String name;
1241:
1242: /**
1243: * Constructor for the ANode object
1244: *
1245: * @param name Description of Parameter
1246: * @param node Description of Parameter
1247: * @since 2.9.12
1248: */
1249: public ANode(String name, SimpleNode node) {
1250: this .name = name;
1251: setUserObject(new NodeData(node));
1252: }
1253:
1254: /**
1255: * Sets the name attribute of the ANode object
1256: *
1257: * @param name The new name value
1258: * @since 2.9.12
1259: */
1260: public void setName(String name) {
1261: this .name = name;
1262: }
1263:
1264: /**
1265: * Gets the Line attribute of the ANode object
1266: *
1267: * @return The Line value
1268: * @since 2.9.12
1269: */
1270: public int getLine() {
1271: return ((NodeData) getUserObject()).getBeginLine();
1272: }
1273:
1274: /**
1275: * Gets the Name attribute of the ANode object
1276: *
1277: * @return The Name value
1278: * @since 2.9.12
1279: */
1280: public String getName() {
1281: return name;
1282: }
1283:
1284: /**
1285: * Description of the Method
1286: *
1287: * @return Description of the Returned Value
1288: * @since 2.9.12
1289: */
1290: public String toString() {
1291: return name;
1292: }
1293:
1294: /**
1295: * Description of the Method
1296: *
1297: * @param comparator Description of Parameter
1298: * @since 2.9.12
1299: */
1300: public void sort(java.util.Comparator comparator) {
1301: if (children != null) {
1302: List sortedChildren = new ArrayList(children);
1303: removeAllChildren();
1304: java.util.Collections.sort(sortedChildren, comparator);
1305: for (Iterator i = sortedChildren.iterator(); i
1306: .hasNext();) {
1307: add((ANode) i.next());
1308: }
1309: }
1310: for (Enumeration i = children(); i.hasMoreElements();) {
1311: ANode child = (ANode) i.nextElement();
1312: if (!child.isLeaf()) {
1313: child.sort(comparator);
1314: }
1315: }
1316: }
1317: }
1318:
1319: /**
1320: * Description of the Class
1321: *
1322: * @author Chris Seguin
1323: * @since 2.9.12
1324: */
1325: private static class ASourceFile extends ANode {
1326: private String filename = "";
1327:
1328: /**
1329: * Constructor for the ASourceFile object
1330: *
1331: * @param name Description of Parameter
1332: * @param node Description of Parameter
1333: * @since 2.9.12
1334: */
1335: public ASourceFile(String name, SimpleNode node) {
1336: super (name, node);
1337: int index = name.lastIndexOf("\\");
1338: if (index < 0) {
1339: index = name.lastIndexOf("/");
1340: }
1341: StringBuffer sb = new StringBuffer(name
1342: .substring(index + 1));
1343: for (int i = sb.length(); i < 30; i++) {
1344: sb.append(" ");
1345: }
1346: sb.append(" (" + name.substring(0, index + 1) + ")");
1347: setName(sb.toString());
1348: filename = name;
1349: }
1350:
1351: /**
1352: * Gets the fileName attribute of the ASourceFile object
1353: *
1354: * @return The fileName value
1355: * @since 2.9.12
1356: */
1357: public String getFileName() {
1358: return filename;
1359: }
1360: }
1361:
1362: /**
1363: * Description of the Class
1364: *
1365: * @author Chris Seguin
1366: * @since 2.9.12
1367: */
1368: private static class AnInterface extends ANode {
1369: /**
1370: * Constructor for the AClass object
1371: *
1372: * @param name Description of Parameter
1373: * @param node Description of Parameter
1374: * @since 2.9.12
1375: */
1376: public AnInterface(String name, SimpleNode node) {
1377: super (name, node);
1378: }
1379: }
1380:
1381: /**
1382: * Description of the Class
1383: *
1384: * @author Chris Seguin
1385: * @since 2.9.12
1386: */
1387: private static class AClass extends ANode {
1388: /**
1389: * Constructor for the AClass object
1390: *
1391: * @param name Description of Parameter
1392: * @param node Description of Parameter
1393: * @since 2.9.12
1394: */
1395: public AClass(String name, SimpleNode node) {
1396: super (name, node);
1397: }
1398:
1399: }
1400:
1401: /**
1402: * Description of the Class
1403: *
1404: * @author Chris Seguin
1405: * @since 2.9.12
1406: */
1407: private static class AMethod extends ANode {
1408: /**
1409: * Constructor for the AMethod object
1410: *
1411: * @param name Description of Parameter
1412: * @param node Description of Parameter
1413: * @since 2.9.12
1414: */
1415: public AMethod(String name, SimpleNode node) {
1416: super (name, node);
1417: }
1418: }
1419:
1420: /**
1421: * Description of the Class
1422: *
1423: * @author Chris Seguin
1424: * @since 2.9.12
1425: */
1426: private static class AField extends ANode {
1427: /**
1428: * Constructor for the AMethod object
1429: *
1430: * @param name Description of Parameter
1431: * @param node Description of Parameter
1432: * @since 2.9.12
1433: */
1434: public AField(String name, SimpleNode node) {
1435: super (name, node);
1436: }
1437: }
1438:
1439: /**
1440: * Description of the Class
1441: *
1442: * @author Chris Seguin
1443: * @since 2.9.12
1444: */
1445: private static class AConstructor extends ANode {
1446: /**
1447: * Constructor for the AConstructor object
1448: *
1449: * @param name Description of Parameter
1450: * @param node Description of Parameter
1451: * @since 2.9.12
1452: */
1453: public AConstructor(String name, SimpleNode node) {
1454: super (name, node);
1455: }
1456: }
1457:
1458: /**
1459: * Description of the Class
1460: *
1461: * @author Mike Atkinson
1462: * @since 2.9.12
1463: */
1464: private static class RunGotoNode implements Runnable {
1465: private ANode node;
1466: private Frame view;
1467:
1468: /**
1469: * Constructor for the RunGotoViolation object
1470: *
1471: * @param node Description of Parameter
1472: * @param view Description of Parameter
1473: * @since 2.9.12
1474: */
1475: public RunGotoNode(ANode node, Frame view) {
1476: this .node = node;
1477: this .view = view;
1478: }
1479:
1480: /**
1481: * Main processing method for the RunGotoViolation object
1482: *
1483: * @since 2.9.12
1484: */
1485: public void run() {
1486: try {
1487: String filename = getFilename(node);
1488: if (filename != null) {
1489: final Object buffer = IDEPlugin.openFile(view,
1490: filename);
1491: IDEPlugin.setBuffer(view, buffer);
1492: int start = IDEPlugin.getLineStartOffset(buffer,
1493: node.getLine() - 1);
1494: int end = IDEPlugin.getLineStartOffset(buffer, node
1495: .getLine());
1496: if (start < 0) {
1497: start = 0;
1498: }
1499: IDEPlugin.setSelection(view, buffer, start, end);
1500: IDEPlugin.moveCaretPosition(view, buffer, end);
1501: }
1502: } catch (Exception ex) {
1503: ex.printStackTrace();
1504: IDEPlugin
1505: .log(IDEInterface.ERROR, "Navigator",
1506: "can't open duplicate file! "
1507: + ex.getMessage());
1508: }
1509: }
1510:
1511: /**
1512: * Gets the Filename attribute of the RunGotoNode object
1513: *
1514: * @param node Description of Parameter
1515: * @return The Filename value
1516: * @since 2.9.12
1517: */
1518: private String getFilename(ANode node) {
1519: TreeNode this Node = node;
1520: while (this Node != null) {
1521: if (this Node instanceof ASourceFile) {
1522: return ((ASourceFile) this Node).getFileName();
1523: }
1524: this Node = this Node.getParent();
1525: }
1526: return null;
1527: }
1528: }
1529:
1530: /**
1531: * Custom cell renderer for the bug tree. We use this to select the tree icons, and to set the text color based on
1532: * the bug priority.
1533: *
1534: * @author Mike Atkinson
1535: * @since 2.9.12
1536: */
1537: private static class NavigatorRenderer extends
1538: DefaultTreeCellRenderer {
1539: //private ImageIcon packageIcon;
1540: private ImageIcon classPublicIcon;
1541: private ImageIcon classPrivateIcon;
1542: private ImageIcon classPackageIcon;
1543: private ImageIcon classProtectedIcon;
1544: private ImageIcon interfacePublicIcon;
1545: private ImageIcon interfacePrivateIcon;
1546: private ImageIcon interfacePackageIcon;
1547: private ImageIcon interfaceProtectedIcon;
1548: private ImageIcon constructorPublicIcon;
1549: private ImageIcon constructorPrivateIcon;
1550: private ImageIcon constructorPackageIcon;
1551: private ImageIcon constructorProtectedIcon;
1552: private ImageIcon methodPublicIcon;
1553: private ImageIcon methodPrivateIcon;
1554: private ImageIcon methodPackageIcon;
1555: private ImageIcon methodProtectedIcon;
1556: private ImageIcon methodStPublicIcon;
1557: private ImageIcon methodStPrivateIcon;
1558: private ImageIcon methodStPackageIcon;
1559: private ImageIcon methodStProtectedIcon;
1560: private ImageIcon fieldPublicIcon;
1561: private ImageIcon fieldPrivateIcon;
1562: private ImageIcon fieldPackageIcon;
1563: private ImageIcon fieldProtectedIcon;
1564: private ImageIcon fieldStPublicIcon;
1565: private ImageIcon fieldStPrivateIcon;
1566: private ImageIcon fieldStPackageIcon;
1567: private ImageIcon fieldStProtectedIcon;
1568: private ImageIcon sourceFileIcon;
1569: private Object value;
1570:
1571: /**
1572: * Constructor for the NavigatorRenderer object
1573: *
1574: * @since 2.9.12
1575: */
1576: public NavigatorRenderer() {
1577: ClassLoader classLoader = this .getClass().getClassLoader();
1578: classPublicIcon = new ImageIcon(
1579: classLoader
1580: .getResource("org/acm/seguin/ide/common/icons/classPublic.gif"));
1581: classPrivateIcon = new ImageIcon(
1582: classLoader
1583: .getResource("org/acm/seguin/ide/common/icons/classPrivate.gif"));
1584: classPackageIcon = new ImageIcon(
1585: classLoader
1586: .getResource("org/acm/seguin/ide/common/icons/classPackage.gif"));
1587: classProtectedIcon = new ImageIcon(
1588: classLoader
1589: .getResource("org/acm/seguin/ide/common/icons/classProtected.gif"));
1590: interfacePublicIcon = new ImageIcon(
1591: classLoader
1592: .getResource("org/acm/seguin/ide/common/icons/interfacePublic.gif"));
1593: interfacePrivateIcon = new ImageIcon(
1594: classLoader
1595: .getResource("org/acm/seguin/ide/common/icons/interfacePrivate.gif"));
1596: interfacePackageIcon = new ImageIcon(
1597: classLoader
1598: .getResource("org/acm/seguin/ide/common/icons/interfacePackage.gif"));
1599: interfaceProtectedIcon = new ImageIcon(
1600: classLoader
1601: .getResource("org/acm/seguin/ide/common/icons/interfaceProtected.gif"));
1602: constructorPublicIcon = new ImageIcon(
1603: classLoader
1604: .getResource("org/acm/seguin/ide/common/icons/constructorPublic.gif"));
1605: methodPublicIcon = new ImageIcon(
1606: classLoader
1607: .getResource("org/acm/seguin/ide/common/icons/methodPublic.gif"));
1608: methodPrivateIcon = new ImageIcon(
1609: classLoader
1610: .getResource("org/acm/seguin/ide/common/icons/methodPrivate.gif"));
1611: methodPackageIcon = new ImageIcon(
1612: classLoader
1613: .getResource("org/acm/seguin/ide/common/icons/methodPackage.gif"));
1614: methodProtectedIcon = new ImageIcon(
1615: classLoader
1616: .getResource("org/acm/seguin/ide/common/icons/methodProtected.gif"));
1617: methodStPublicIcon = new ImageIcon(
1618: classLoader
1619: .getResource("org/acm/seguin/ide/common/icons/methodStPublic.gif"));
1620: methodStPrivateIcon = new ImageIcon(
1621: classLoader
1622: .getResource("org/acm/seguin/ide/common/icons/methodStPrivate.gif"));
1623: methodStPackageIcon = new ImageIcon(
1624: classLoader
1625: .getResource("org/acm/seguin/ide/common/icons/methodStPackage.gif"));
1626: methodStProtectedIcon = new ImageIcon(
1627: classLoader
1628: .getResource("org/acm/seguin/ide/common/icons/methodStProtected.gif"));
1629: fieldPublicIcon = new ImageIcon(
1630: classLoader
1631: .getResource("org/acm/seguin/ide/common/icons/variablePublic.gif"));
1632: fieldPrivateIcon = new ImageIcon(
1633: classLoader
1634: .getResource("org/acm/seguin/ide/common/icons/variablePrivate.gif"));
1635: fieldPackageIcon = new ImageIcon(
1636: classLoader
1637: .getResource("org/acm/seguin/ide/common/icons/variablePackage.gif"));
1638: fieldProtectedIcon = new ImageIcon(
1639: classLoader
1640: .getResource("org/acm/seguin/ide/common/icons/variableProtected.gif"));
1641: fieldStPublicIcon = new ImageIcon(
1642: classLoader
1643: .getResource("org/acm/seguin/ide/common/icons/variableStPublic.gif"));
1644: fieldStPrivateIcon = new ImageIcon(
1645: classLoader
1646: .getResource("org/acm/seguin/ide/common/icons/variableStPrivate.gif"));
1647: fieldStPackageIcon = new ImageIcon(
1648: classLoader
1649: .getResource("org/acm/seguin/ide/common/icons/variableStPackage.gif"));
1650: fieldStProtectedIcon = new ImageIcon(
1651: classLoader
1652: .getResource("org/acm/seguin/ide/common/icons/variableStProtected.gif"));
1653: sourceFileIcon = new ImageIcon(
1654: classLoader
1655: .getResource("org/acm/seguin/ide/common/icons/sourcefile.gif"));
1656: }
1657:
1658: /**
1659: * Gets the treeCellRendererComponent attribute of the NavigatorRenderer object
1660: *
1661: * @param tree Description of Parameter
1662: * @param value Description of Parameter
1663: * @param sel Description of Parameter
1664: * @param expanded Description of Parameter
1665: * @param leaf Description of Parameter
1666: * @param row Description of Parameter
1667: * @param hasFocus Description of Parameter
1668: * @return The treeCellRendererComponent value
1669: * @since 2.9.12
1670: */
1671: public Component getTreeCellRendererComponent(JTree tree,
1672: Object value, boolean sel, boolean expanded,
1673: boolean leaf, int row, boolean hasFocus) {
1674: DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
1675: Object obj = node.getUserObject();
1676:
1677: this .value = obj;
1678:
1679: super .getTreeCellRendererComponent(tree, value, sel,
1680: expanded, leaf, row, hasFocus);
1681:
1682: // Set the icon, depending on what kind of node it is
1683: if (value instanceof AnInterface) {
1684: if (obj instanceof ModifierHolder) {
1685: ModifierHolder astnode = (ModifierHolder) obj;
1686: if (astnode.isPublic()) {
1687: setIcon(interfacePublicIcon);
1688: } else if (astnode.isPrivate()) {
1689: setIcon(interfacePrivateIcon);
1690: } else if (astnode.isProtected()) {
1691: setIcon(interfaceProtectedIcon);
1692: } else {
1693: setIcon(interfacePackageIcon);
1694: }
1695: } else {
1696: setIcon(interfacePublicIcon);
1697: }
1698: } else if (value instanceof AClass) {
1699: if (obj instanceof ModifierHolder) {
1700: ModifierHolder astnode = (ModifierHolder) obj;
1701: if (astnode.isPublic()) {
1702: setIcon(classPublicIcon);
1703: } else if (astnode.isPrivate()) {
1704: setIcon(classPrivateIcon);
1705: } else if (astnode.isProtected()) {
1706: setIcon(classProtectedIcon);
1707: } else {
1708: setIcon(classPackageIcon);
1709: }
1710: } else {
1711: setIcon(classPublicIcon);
1712: }
1713: } else if (value instanceof AConstructor) {
1714: ModifierHolder astnode = (ModifierHolder) obj;
1715: if (astnode.isPublic()) {
1716: setIcon(constructorPublicIcon);
1717: } else if (astnode.isPrivate()) {
1718: setIcon(constructorPrivateIcon);
1719: } else if (astnode.isProtected()) {
1720: setIcon(constructorProtectedIcon);
1721: } else {
1722: setIcon(constructorPackageIcon);
1723: }
1724: } else if (value instanceof AMethod) {
1725: ModifierHolder astnode = (ModifierHolder) obj;
1726: boolean isStatic = astnode.isStatic();
1727: if (astnode.isPublic()) {
1728: setIcon((isStatic) ? methodStPublicIcon
1729: : methodPublicIcon);
1730: } else if (astnode.isPrivate()) {
1731: setIcon((isStatic) ? methodStPrivateIcon
1732: : methodPrivateIcon);
1733: } else if (astnode.isProtected()) {
1734: setIcon((isStatic) ? methodStProtectedIcon
1735: : methodProtectedIcon);
1736: } else {
1737: setIcon((isStatic) ? methodStPackageIcon
1738: : methodPackageIcon);
1739: }
1740: } else if (value instanceof AField) {
1741: ModifierHolder astnode = (ModifierHolder) obj;
1742: boolean isStatic = astnode.isStatic();
1743: if (astnode.isPublic()) {
1744: setIcon((isStatic) ? fieldStPublicIcon
1745: : fieldPublicIcon);
1746: } else if (astnode.isPrivate()) {
1747: setIcon((isStatic) ? fieldStPrivateIcon
1748: : fieldPrivateIcon);
1749: } else if (astnode.isProtected()) {
1750: setIcon((isStatic) ? fieldStProtectedIcon
1751: : fieldProtectedIcon);
1752: } else {
1753: setIcon((isStatic) ? fieldStPackageIcon
1754: : fieldPackageIcon);
1755: }
1756: } else if (value instanceof ASourceFile) {
1757: setIcon(sourceFileIcon);
1758: } else {
1759: setIcon(null);
1760: }
1761:
1762: return this ;
1763: }
1764:
1765: /**
1766: * Gets the textNonSelectionColor attribute of the NavigatorRenderer object
1767: *
1768: * @return The textNonSelectionColor value
1769: * @since 2.9.12
1770: */
1771: public Color getTextNonSelectionColor() {
1772: return getCellTextColor();
1773: }
1774:
1775: /**
1776: * Gets the cellTextColor attribute of the NavigatorRenderer object
1777: *
1778: * @return The cellTextColor value
1779: * @since 2.9.12
1780: */
1781: private Color getCellTextColor() {
1782: // Based on the priority, color-code the bug instance.
1783: Color color = Color.BLACK;
1784: return color;
1785: }
1786: }
1787: }
|