blob: 8d8f7f97697ad9bd543c080daea9f42d678ebfd9 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1998-1999 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package com.sun.tools.example.debug.gui;
27
28import java.io.*;
29import java.util.*;
30
31import javax.swing.*;
32import javax.swing.tree.*;
33import javax.swing.event.*;
34import java.awt.*;
35import java.awt.event.*;
36
37import com.sun.jdi.*;
38import com.sun.tools.example.debug.bdi.*;
39
40public class SourceTreeTool extends JPanel {
41
42 private Environment env;
43
44 private ExecutionManager runtime;
45 private SourceManager sourceManager;
46 private ClassManager classManager;
47
48 private JTree tree;
49 private SourceTreeNode root;
50 private SearchPath sourcePath;
51 private CommandInterpreter interpreter;
52
53 private static String HEADING = "SOURCES";
54
55 public SourceTreeTool(Environment env) {
56
57 super(new BorderLayout());
58
59 this.env = env;
60 this.runtime = env.getExecutionManager();
61 this.sourceManager = env.getSourceManager();
62
63 this.interpreter = new CommandInterpreter(env);
64
65 sourcePath = sourceManager.getSourcePath();
66 root = createDirectoryTree(HEADING);
67
68 // Create a tree that allows one selection at a time.
69 tree = new JTree(new DefaultTreeModel(root));
70 tree.setSelectionModel(new SingleLeafTreeSelectionModel());
71
72 /******
73 // Listen for when the selection changes.
74 tree.addTreeSelectionListener(new TreeSelectionListener() {
75 public void valueChanged(TreeSelectionEvent e) {
76 SourceTreeNode node = (SourceTreeNode)
77 (e.getPath().getLastPathComponent());
78 interpreter.executeCommand("view " + node.getRelativePath());
79 }
80 });
81 ******/
82
83 MouseListener ml = new MouseAdapter() {
84 public void mouseClicked(MouseEvent e) {
85 int selRow = tree.getRowForLocation(e.getX(), e.getY());
86 TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());
87 if(selRow != -1) {
88 if(e.getClickCount() == 1) {
89 SourceTreeNode node =
90 (SourceTreeNode)selPath.getLastPathComponent();
91 // If user clicks on leaf, select it, and issue 'view' command.
92 if (node.isLeaf()) {
93 tree.setSelectionPath(selPath);
94 interpreter.executeCommand("view " + node.getRelativePath());
95 }
96 }
97 }
98 }
99 };
100 tree.addMouseListener(ml);
101
102 JScrollPane treeView = new JScrollPane(tree);
103 add(treeView);
104
105 // Create listener for source path changes.
106
107 SourceTreeToolListener listener = new SourceTreeToolListener();
108 sourceManager.addSourceListener(listener);
109
110 //### remove listeners on exit!
111 }
112
113 private class SourceTreeToolListener implements SourceListener {
114
115 public void sourcepathChanged(SourcepathChangedEvent e) {
116 sourcePath = sourceManager.getSourcePath();
117 root = createDirectoryTree(HEADING);
118 tree.setModel(new DefaultTreeModel(root));
119 }
120
121 }
122
123 private static class SourceOrDirectoryFilter implements FilenameFilter {
124 public boolean accept(File dir, String name) {
125 return (name.endsWith(".java") ||
126 new File(dir, name).isDirectory());
127 }
128 }
129
130 private static FilenameFilter filter = new SourceOrDirectoryFilter();
131
132 SourceTreeNode createDirectoryTree(String label) {
133 try {
134 return new SourceTreeNode(label, null, "", true);
135 } catch (SecurityException e) {
136 env.failure("Cannot access source file or directory");
137 return null;
138 }
139 }
140
141
142 class SourceTreeNode implements TreeNode {
143
144 private String name;
145 private boolean isDirectory;
146 private SourceTreeNode parent;
147 private SourceTreeNode[] children;
148 private String relativePath;
149 private boolean isExpanded;
150
151 private SourceTreeNode(String label,
152 SourceTreeNode parent,
153 String relativePath,
154 boolean isDirectory) {
155 this.name = label;
156 this.relativePath = relativePath;
157 this.parent = parent;
158 this.isDirectory = isDirectory;
159 }
160
161 public String toString() {
162 return name;
163 }
164
165 public String getRelativePath() {
166 return relativePath;
167 }
168
169 private void expandIfNeeded() {
170 try {
171 if (!isExpanded && isDirectory) {
172 String[] files = sourcePath.children(relativePath, filter);
173 children = new SourceTreeNode[files.length];
174 for (int i = 0; i < files.length; i++) {
175 String childName =
176 (relativePath.equals(""))
177 ? files[i]
178 : relativePath + File.separator + files[i];
179 File file = sourcePath.resolve(childName);
180 boolean isDir = (file != null && file.isDirectory());
181 children[i] =
182 new SourceTreeNode(files[i], this, childName, isDir);
183 }
184 }
185 isExpanded = true;
186 } catch (SecurityException e) {
187 children = null;
188 env.failure("Cannot access source file or directory");
189 }
190 }
191
192 // -- interface TreeNode --
193
194 /*
195 * Returns the child <code>TreeNode</code> at index
196 * <code>childIndex</code>.
197 */
198 public TreeNode getChildAt(int childIndex) {
199 expandIfNeeded();
200 return children[childIndex];
201 }
202
203 /**
204 * Returns the number of children <code>TreeNode</code>s the receiver
205 * contains.
206 */
207 public int getChildCount() {
208 expandIfNeeded();
209 return children.length;
210 }
211
212 /**
213 * Returns the parent <code>TreeNode</code> of the receiver.
214 */
215 public TreeNode getParent() {
216 return parent;
217 }
218
219 /**
220 * Returns the index of <code>node</code> in the receivers children.
221 * If the receiver does not contain <code>node</code>, -1 will be
222 * returned.
223 */
224 public int getIndex(TreeNode node) {
225 expandIfNeeded();
226 for (int i = 0; i < children.length; i++) {
227 if (children[i] == node)
228 return i;
229 }
230 return -1;
231 }
232
233 /**
234 * Returns true if the receiver allows children.
235 */
236 public boolean getAllowsChildren() {
237 return isDirectory;
238 }
239
240 /**
241 * Returns true if the receiver is a leaf.
242 */
243 public boolean isLeaf() {
244 expandIfNeeded();
245 return !isDirectory;
246 }
247
248 /**
249 * Returns the children of the receiver as an Enumeration.
250 */
251 public Enumeration children() {
252 expandIfNeeded();
253 return new Enumeration() {
254 int i = 0;
255 public boolean hasMoreElements() {
256 return (i < children.length);
257 }
258 public Object nextElement() throws NoSuchElementException {
259 if (i >= children.length) {
260 throw new NoSuchElementException();
261 }
262 return children[i++];
263 }
264 };
265 }
266
267 }
268
269}