| /* |
| * Copyright (c) 1998, 1999, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| /* |
| * This source code is provided to illustrate the usage of a given feature |
| * or technique and has been deliberately simplified. Additional steps |
| * required for a production-quality application, such as security checks, |
| * input validation and proper error handling, might not be present in |
| * this sample code. |
| */ |
| |
| |
| package com.sun.tools.example.debug.gui; |
| |
| import java.io.*; |
| import java.util.*; |
| |
| import javax.swing.*; |
| import javax.swing.tree.*; |
| import java.awt.*; |
| import java.awt.event.*; |
| |
| import com.sun.tools.example.debug.bdi.*; |
| |
| public class SourceTreeTool extends JPanel { |
| |
| private static final long serialVersionUID = 3336680912107956419L; |
| |
| private Environment env; |
| |
| private ExecutionManager runtime; |
| private SourceManager sourceManager; |
| private ClassManager classManager; |
| |
| private JTree tree; |
| private SourceTreeNode root; |
| private SearchPath sourcePath; |
| private CommandInterpreter interpreter; |
| |
| private static String HEADING = "SOURCES"; |
| |
| public SourceTreeTool(Environment env) { |
| |
| super(new BorderLayout()); |
| |
| this.env = env; |
| this.runtime = env.getExecutionManager(); |
| this.sourceManager = env.getSourceManager(); |
| |
| this.interpreter = new CommandInterpreter(env); |
| |
| sourcePath = sourceManager.getSourcePath(); |
| root = createDirectoryTree(HEADING); |
| |
| // Create a tree that allows one selection at a time. |
| tree = new JTree(new DefaultTreeModel(root)); |
| tree.setSelectionModel(new SingleLeafTreeSelectionModel()); |
| |
| /****** |
| // Listen for when the selection changes. |
| tree.addTreeSelectionListener(new TreeSelectionListener() { |
| public void valueChanged(TreeSelectionEvent e) { |
| SourceTreeNode node = (SourceTreeNode) |
| (e.getPath().getLastPathComponent()); |
| interpreter.executeCommand("view " + node.getRelativePath()); |
| } |
| }); |
| ******/ |
| |
| MouseListener ml = new MouseAdapter() { |
| @Override |
| public void mouseClicked(MouseEvent e) { |
| int selRow = tree.getRowForLocation(e.getX(), e.getY()); |
| TreePath selPath = tree.getPathForLocation(e.getX(), e.getY()); |
| if(selRow != -1) { |
| if(e.getClickCount() == 1) { |
| SourceTreeNode node = |
| (SourceTreeNode)selPath.getLastPathComponent(); |
| // If user clicks on leaf, select it, and issue 'view' command. |
| if (node.isLeaf()) { |
| tree.setSelectionPath(selPath); |
| interpreter.executeCommand("view " + node.getRelativePath()); |
| } |
| } |
| } |
| } |
| }; |
| tree.addMouseListener(ml); |
| |
| JScrollPane treeView = new JScrollPane(tree); |
| add(treeView); |
| |
| // Create listener for source path changes. |
| |
| SourceTreeToolListener listener = new SourceTreeToolListener(); |
| sourceManager.addSourceListener(listener); |
| |
| //### remove listeners on exit! |
| } |
| |
| private class SourceTreeToolListener implements SourceListener { |
| |
| @Override |
| public void sourcepathChanged(SourcepathChangedEvent e) { |
| sourcePath = sourceManager.getSourcePath(); |
| root = createDirectoryTree(HEADING); |
| tree.setModel(new DefaultTreeModel(root)); |
| } |
| |
| } |
| |
| private static class SourceOrDirectoryFilter implements FilenameFilter { |
| @Override |
| public boolean accept(File dir, String name) { |
| return (name.endsWith(".java") || |
| new File(dir, name).isDirectory()); |
| } |
| } |
| |
| private static FilenameFilter filter = new SourceOrDirectoryFilter(); |
| |
| SourceTreeNode createDirectoryTree(String label) { |
| try { |
| return new SourceTreeNode(label, null, "", true); |
| } catch (SecurityException e) { |
| env.failure("Cannot access source file or directory"); |
| return null; |
| } |
| } |
| |
| |
| class SourceTreeNode implements TreeNode { |
| |
| private String name; |
| private boolean isDirectory; |
| private SourceTreeNode parent; |
| private SourceTreeNode[] children; |
| private String relativePath; |
| private boolean isExpanded; |
| |
| private SourceTreeNode(String label, |
| SourceTreeNode parent, |
| String relativePath, |
| boolean isDirectory) { |
| this.name = label; |
| this.relativePath = relativePath; |
| this.parent = parent; |
| this.isDirectory = isDirectory; |
| } |
| |
| @Override |
| public String toString() { |
| return name; |
| } |
| |
| public String getRelativePath() { |
| return relativePath; |
| } |
| |
| private void expandIfNeeded() { |
| try { |
| if (!isExpanded && isDirectory) { |
| String[] files = sourcePath.children(relativePath, filter); |
| children = new SourceTreeNode[files.length]; |
| for (int i = 0; i < files.length; i++) { |
| String childName = |
| (relativePath.equals("")) |
| ? files[i] |
| : relativePath + File.separator + files[i]; |
| File file = sourcePath.resolve(childName); |
| boolean isDir = (file != null && file.isDirectory()); |
| children[i] = |
| new SourceTreeNode(files[i], this, childName, isDir); |
| } |
| } |
| isExpanded = true; |
| } catch (SecurityException e) { |
| children = null; |
| env.failure("Cannot access source file or directory"); |
| } |
| } |
| |
| // -- interface TreeNode -- |
| |
| /* |
| * Returns the child <code>TreeNode</code> at index |
| * <code>childIndex</code>. |
| */ |
| @Override |
| public TreeNode getChildAt(int childIndex) { |
| expandIfNeeded(); |
| return children[childIndex]; |
| } |
| |
| /** |
| * Returns the number of children <code>TreeNode</code>s the receiver |
| * contains. |
| */ |
| @Override |
| public int getChildCount() { |
| expandIfNeeded(); |
| return children.length; |
| } |
| |
| /** |
| * Returns the parent <code>TreeNode</code> of the receiver. |
| */ |
| @Override |
| public TreeNode getParent() { |
| return parent; |
| } |
| |
| /** |
| * Returns the index of <code>node</code> in the receivers children. |
| * If the receiver does not contain <code>node</code>, -1 will be |
| * returned. |
| */ |
| @Override |
| public int getIndex(TreeNode node) { |
| expandIfNeeded(); |
| for (int i = 0; i < children.length; i++) { |
| if (children[i] == node) { |
| return i; |
| } |
| } |
| return -1; |
| } |
| |
| /** |
| * Returns true if the receiver allows children. |
| */ |
| @Override |
| public boolean getAllowsChildren() { |
| return isDirectory; |
| } |
| |
| /** |
| * Returns true if the receiver is a leaf. |
| */ |
| @Override |
| public boolean isLeaf() { |
| expandIfNeeded(); |
| return !isDirectory; |
| } |
| |
| /** |
| * Returns the children of the receiver as an Enumeration. |
| */ |
| @Override |
| public Enumeration children() { |
| expandIfNeeded(); |
| return new Enumeration() { |
| int i = 0; |
| @Override |
| public boolean hasMoreElements() { |
| return (i < children.length); |
| } |
| @Override |
| public Object nextElement() throws NoSuchElementException { |
| if (i >= children.length) { |
| throw new NoSuchElementException(); |
| } |
| return children[i++]; |
| } |
| }; |
| } |
| |
| } |
| |
| } |