alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*****************************************************************************
 *                                                                           *
 *  This file is part of the BeanShell Java Scripting distribution.          *
 *  Documentation and updates may be found at http://www.beanshell.org/      *
 *                                                                           *
 *  BeanShell is distributed under the terms of the LGPL:                    *
 *  GNU Library Public License http://www.gnu.org/copyleft/lgpl.html         *
 *                                                                           *
 *  Patrick Niemeyer (pat@pat.net)                                           *
 *  Author of Exploring Java, O'Reilly & Associates                          *
 *  http://www.pat.net/~pat/                                                 *
 *                                                                           *
 *****************************************************************************/

import java.util.*;
import java.util.zip.*;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.lang.reflect.*;
import org.jext.*;
import org.jext.gui.*;

/**
  A simple class browser for the BeanShell desktop.
*/
public class ClassBrowser extends JSplitPane implements ListSelectionListener,
TreeSelectionListener, ActionListener {

	JFrame frame;
	JextHighlightButton apiButton;
	JInternalFrame iframe;
	Hashtable packages = new Hashtable();
	JList plist, classlist, mlist, conslist;
	String selectedPackage;
	Class selectedClass;
	JTextArea methodLine;
	String [] packagesList, classesList;
	Method [] methodList;
	Constructor [] consList;
	JTree tree;

	public ClassBrowser() {
		super(VERTICAL_SPLIT, true);
	}

	String [] split(String s, String delim) {
		Vector v = new Vector();
		StringTokenizer st = new StringTokenizer(s, delim);
		while (st.hasMoreTokens())
			v.addElement(st.nextToken());
		String [] sa = new String [v.size()];
		v.copyInto(sa);
		return sa;
	}

	String [] splitClassname (String classname) {
		classname = classname.replace('/', '.');
		if (classname.startsWith("class "))
			classname = classname.substring(6);
		if (classname.endsWith(".class"))
			classname = classname.substring(0, classname.length() - 6);

		int i = classname.lastIndexOf(".");
		String classn, packn;
		if (i == -1) {
			// top level class
			classn = classname;
			packn = "";
		} else {
			packn = classname.substring(0, i);
			classn = classname.substring(i + 1);
		}
		return new String []{ packn, classn };
	}

	void addClass(String classname) {
		String [] sa = splitClassname(classname);
		String packn = sa[0];
		String classn = sa[1];

		Vector pack = (Vector) packages.get(packn);
		if (pack == null) {
			pack = new Vector();
			packages.put(packn, pack);
		}
		pack.addElement(classn);
	}

	void addJar(String jarname) throws IOException {
		ZipFile f = new ZipFile(jarname);
		Enumeration e = f.entries();
		//Vector v=new Vector();
		while (e.hasMoreElements()) {
			String name = ((ZipEntry) e.nextElement()).getName();
			if (name.endsWith(".class") && (name.indexOf('$') == -1)) {
				//v.addElement(name);
				addClass(name);
			}
		}
	}

	/** Convenient wrapper for QuickSort of an array of Method objects
	   * @param  methods the Method array to be sorted
	   */
	void sortMethods(Method[] methods) {
		sortMethods(methods, 0, methods.length - 1);
	}

	/**
	   * QuickSort an array of Strings.
	   * @param a Methods to be sorted
	   * @param lo0 Lower bound
	   * @param hi0 Higher bound
	   */

	void sortMethods(Method a[], int lo0, int hi0) {
		int lo = lo0;
		int hi = hi0;
		Method mid;

		if (hi0 > lo0) {
			mid = a[(lo0 + hi0) / 2];

			while (lo <= hi) {
				while (lo < hi0 && a[lo].getName().compareTo(mid.getName()) < 0)
					++lo;

				while (hi > lo0 && a[hi].getName().compareTo(mid.getName()) > 0)
					--hi;

				if (lo <= hi) {
					swap(a, lo, hi);
					++lo;
					--hi;
				}
			}

			if (lo0 < hi)
				sortMethods(a, lo0, hi);

			if (lo < hi0)
				sortMethods(a, lo, hi0);
		}
	}

	/**
	   * Swaps two Method objects.
	   * @param a The array to be swapped
	   * @param i First Method index
	   * @param j Second Method index
	   */

	public static void swap(Method a[], int i, int j) {
		Method temp;
		temp = a[i];
		a[i] = a[j];
		a[j] = temp;
	}

	String [] toSortedList (Vector v) {
		String [] sa = new String [v.size()];
		v.copyInto(sa);
		Arrays.sort(sa);
		return sa;
	}

	void setClist(String packagename) {
		this.selectedPackage = packagename;
		Vector v = (Vector) packages.get(packagename);
		if (v == null)
			return;

		classesList = toSortedList(v);
		classlist.setListData(classesList);
		//setMlist( (String)classlist.getModel().getElementAt(0) );
	}

	String [] parseMethods(Method [] methods) {
		String [] sa = new String [methods.length];
		for (int i = 0; i < sa.length; i++)
			sa[i] = methods[i].getName();
		return sa;
	}

	Method [] getPublicMethods(Method [] methods) {
		Vector v = new Vector();
		sortMethods(methods);
		for (int i = 0; i < methods.length; i++)
			if (Modifier.isPublic(methods[i].getModifiers()))
				v.addElement(methods[i]);

		Method [] ma = new Method [v.size()];
		v.copyInto(ma);
		return ma;
	}

	void setMlist(String classname) {
		if (classname == null) {
			mlist.setListData(new Object []{ });
			setConslist(null);
			setTree(null);
			return;
		}

		Class clas;
		try {
			selectedClass = Class.forName(selectedPackage + "."+classname);
		} catch (Exception e) {
			System.out.println(e);
			return;
		}
		methodList = getPublicMethods(selectedClass.getDeclaredMethods());
		mlist.setListData(parseMethods(methodList));
		setTree(selectedClass);
		setConslist(selectedClass);
	}

	void setConslist(Class clas) {
		if (clas == null) {
			conslist.setListData(new Object []{ });
			return;
		}

		consList = clas.getConstructors();
		conslist.setListData(consList);
	}

	void setMethodLine(Object method) {
		methodLine.setText(method == null ? "" : method.toString());
	}

	void setTree(Class clas) {
		if (clas == null) {
			tree.setModel(null);
			return;
		}

		MutableTreeNode bottom = null, top = null;
		DefaultMutableTreeNode up;
		do {
			up = new DefaultMutableTreeNode(clas.toString());
			if (top != null)
				up.add(top);
			else
				bottom = up;
			top = up;
		} while ((clas = clas.getSuperclass()) != null)
			;
		tree.setModel(new DefaultTreeModel(top));

		TreeNode tn = bottom.getParent();
		if (tn != null) {
			TreePath tp = new TreePath (
			        ((DefaultTreeModel) tree.getModel()).getPathToRoot(tn));
			tree.expandPath(tp);
		}
	}

	JPanel labeledPane(JComponent comp, String label) {
		JPanel jp = new JPanel(new BorderLayout());
		jp.add("Center", comp);
		jp.add("North", new JLabel(label, SwingConstants.CENTER));
		return jp;
	}

	public void init() {
		String cp = System.getProperty("java.class.path");
		String [] paths = split(cp, File.pathSeparator);
		for (int i = 0; i < paths.length; i++)
			if (paths[i].endsWith(".jar") || paths[i].endsWith(".zip"))
				try {
					System.out.println("Adding classes: "+paths[i]);
					addJar(paths[i]);
				} catch (IOException e) {
				}

		// do we have the core classes?
		// try some standard locations
		if (packages.get("java.lang") == null)
			try {
				addJar(System.getProperty("java.home") + "/lib/rt.jar");
			} catch (IOException e) {
				System.out.println("Can't find core classes....");
			}

		Vector v = new Vector();
		Enumeration e = packages.keys();
		while (e.hasMoreElements())
			v.addElement(e.nextElement());

		packagesList = toSortedList(v);
		plist = new JList(packagesList);
    plist.setCellRenderer(new ModifiedCellRenderer());
		plist.addListSelectionListener(this);

		classlist = new JList();
    classlist.setCellRenderer(new ModifiedCellRenderer());
		classlist.addListSelectionListener(this);

		mlist = new JList();
    mlist.setCellRenderer(new ModifiedCellRenderer());
		mlist.addListSelectionListener(this);

		conslist = new JList();
    conslist.setCellRenderer(new ModifiedCellRenderer());
		conslist.addListSelectionListener(this);

		JSplitPane methodspane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true,
		        labeledPane(new JScrollPane(mlist), "Methods"),
		        labeledPane(new JScrollPane(conslist), "Constructors"));

		JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true,
		        labeledPane(new JScrollPane(classlist), "Classes"), methodspane);
		sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true,
		        labeledPane(new JScrollPane(plist), "Packages"), sp);

		JPanel bottompanel = new JPanel(new BorderLayout());
		apiButton = new JextHighlightButton("Open API doc");
		apiButton.addActionListener(this);
		bottompanel.add("North", apiButton);
		methodLine = new JTextArea(1, 60);
		methodLine.setEditable(false);
		methodLine.setLineWrap(true);
		methodLine.setWrapStyleWord(true);
		methodLine.setFont(new Font("Monospaced", Font.BOLD, 14));
		methodLine.setMargin(new Insets(5, 5, 5, 5));
		methodLine.setBorder(BorderFactory.createRaisedBevelBorder());
		bottompanel.add("Center", methodLine);
		JPanel p = new JPanel(new BorderLayout());
		tree = new JTree();
		tree.addTreeSelectionListener(this);
		tree.setBorder(BorderFactory.createRaisedBevelBorder());
		setTree(null);
		p.add("Center", tree);
		bottompanel.add("South", p);

		// give it a preferred height
		// bottompanel.setPreferredSize(new java.awt.Dimension(150, 150));

		setTopComponent(sp);
		setBottomComponent(bottompanel);
	}

	public void actionPerformed(ActionEvent evt) {
		if (evt.getSource() == apiButton) {
			String classname = (String) classlist.getSelectedValue();
			String packagename = (String) plist.getSelectedValue();

			if (classname == null || packagename == null)
				return;

			if (!packagename.startsWith("java.") &&
			        !packagename.startsWith("javax.") &&
			        !packagename.startsWith("org.omg."))
				return;

			StringBuffer buf = new StringBuffer(Jext.getProperty("class_browser.base_api_doc_url"));
			buf.append('/');

			for (int i = 0; i < packagename.length(); i++) {
				char c = packagename.charAt(i);
				if (c == '.')
					buf.append('/');
				else
					buf.append(c);
			}
			buf.append('/');
			buf.append(classname).append(".html");

			try {
				BrowserLauncher.openURL(buf.toString());
			} catch (IOException ioe) {
				System.out.println("IOException caught in ClassBrowser.java");
				ioe.printStackTrace();
			}
		}
	}

	public static void main(String [] args) {
		//warning...Jext.getProperties doesn't work when running w/ this driver
		ClassBrowser cb = new ClassBrowser();
		cb.init();

		JFrame f = new JFrame("Class Browser");
		f.getContentPane().add("Center", cb);
		cb.setFrame(f);
		//f.pack();
		f.setSize(new Dimension(700, 450));
		f.show();
	}

	public void setFrame(JFrame frame) {
		this.frame = frame;
	}
	public void setFrame(JInternalFrame frame) {
		this.iframe = frame;
	}

	public void valueChanged(TreeSelectionEvent e) {
		driveToClass(e.getPath().getLastPathComponent().toString());
	}

	public void valueChanged(ListSelectionEvent e) {
		if (e.getSource() == plist) {
			String selectedPackage = (String) plist.getSelectedValue();
			setClist(selectedPackage);
		} else if (e.getSource() == classlist) {
			String classname = (String) classlist.getSelectedValue();
			setMlist(classname);
		} else if (e.getSource() == mlist) {
			int i = mlist.getSelectedIndex();
			if (i == -1)
				setMethodLine(null);
			else
				setMethodLine(methodList[i]);
		} else if (e.getSource() == conslist) {
			int i = conslist.getSelectedIndex();
			if (i == -1)
				setMethodLine(null);
			else
				setMethodLine(consList[i]);
		}
	}

	// fully qualified classname
	public void driveToClass(String classname) {
		String [] sa = splitClassname(classname);
		String packn = sa[0];
		String classn = sa[1];

		Vector v = (Vector) packages.get(packn);
		if (v == null)
			return;

		boolean found = false;
		for (int i = 0; i < packagesList.length; i++) {
			if (packagesList[i].equals(packn)) {
				plist.setSelectedIndex(i);
				plist.ensureIndexIsVisible(i);
				found = true;
				break;
			}
		}
		if (!found)
			return;

		for (int i = 0; i < classesList.length; i++) {
			if (classesList[i].equals(classn)) {
				classlist.setSelectedIndex(i);
				classlist.ensureIndexIsVisible(i);
				break;
			}
		}
	}

	public void toFront() {
		if (frame != null)
			frame.toFront();
		else if (iframe != null)
			iframe.toFront();
	}
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.