/* Show_Threads.bsh
 *
 * A BeanShell macro script for jEdit - displays all threads in a tree.
 *
 * Copyright (c) 2001 Dirk Moebius (dmoebius@gmx.net)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or any later version.
 *
 * This program 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 for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 *
 * Version 1.0
 * requires JDK 1.1, jEdit3.1
 *
 * $Id: Show_Threads.bsh 4001 2002-01-31 05:35:49Z spestov $
 */


import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;


JFrame createThreadsFrame() {

	void windowClosing(WindowEvent e) {
		GUIUtilities.saveGeometry(frame, "macros-show-threads");
	}


	void keyPressed(KeyEvent e) {
		if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
			GUIUtilities.saveGeometry(frame, "macros-show-threads");
			frame.setVisible(false);
			frame.dispose();
		}
		else if (e.getKeyCode() == KeyEvent.VK_U) {
			tree.setModel(new DefaultTreeModel(createModel()));
			tree.revalidate();
		}
	}


	// Having these members of KeyListener and WindowListener implemented as
	// no-ops will speedup execution.  Otherwise BeanShell throws an
	// exception each time one of these events occur.
	void keyReleased(KeyEvent e) { }
	void keyTyped(KeyEvent e) { }
	void windowActivated(WindowEvent e) { }
	void windowClosed(WindowEvent e) { }
	void windowDeactivated(WindowEvent e) { }
	void windowDeiconified(WindowEvent e) { }
	void windowIconified(WindowEvent e) { }
	void windowOpened(WindowEvent e) { }


	ThreadGroup getMainThreadGroup() {
		t = Thread.currentThread();
		g = t.getThreadGroup();
		while (g.getParent() != null)
			g = g.getParent();
		return g;
	}


	DefaultMutableTreeNode createModel() {
		g = getMainThreadGroup();
		return createGroupNode(g);
	}


	DefaultMutableTreeNode createGroupNode(ThreadGroup g) {
		node = new DefaultMutableTreeNode(g.getName() + (g.isDaemon() ? " (daemon)" : ""), true);

		groups = new ThreadGroup[g.activeGroupCount()];
		count = g.enumerate(groups, false);
		for (int i = 0; i < count; ++i)
			node.add(createGroupNode(groups[i]));

		threads = new Thread[g.activeCount()];
		count = g.enumerate(threads, false);
		for (int i = 0; i < count; ++i)
			node.add(new DefaultMutableTreeNode(getDescription(threads[i]), false));

		return node;
	}


	String getDescription(Thread t) {
		StringBuffer buf = new StringBuffer(t.getName());
		buf.append(" (prio ");
		buf.append(t.getPriority());
		if (!t.isAlive())
			buf.append(", not started");
		if (t.isDaemon())
			buf.append(", daemon");
		if (t.isInterrupted())
			buf.append(", interrupted");
		buf.append(")");
		return buf.toString();
	}


	tree = new JTree(createModel());
	tree.putClientProperty("JTree.lineStyle", "Angled");
	tree.addKeyListener(this);

	stage = new JScrollPane(tree);
	stage.setColumnHeaderView(new JLabel("[Esc] Close      [U] Update"));

	frame = new JFrame("Current Threads");
	frame.setContentPane(stage);
	frame.addWindowListener(this);
	// set default size and position:
	frame.setSize(new Dimension(400, 400)); // faster than pack()
	// overwrite default size and position loading user properties:
	GUIUtilities.loadGeometry(frame, "macros-show-threads");
	frame.setVisible(true);

	return frame;
}


createThreadsFrame();

/*

Macro index data (in DocBook format)

  <listitem>
    <para><filename>Show_Threads.bsh</filename></para>
    <abstract><para>
      Displays all running Java threads in a tree.
    </para></abstract>
  </listitem>

*/

// end Show_Threads.bsh

