psmith 2003/09/01 15:33:32 Modified: src/java/org/apache/log4j/chainsaw LoggerNameTreePanel.java Log: added mini-toolbar to the LoggerName tree panel, with expansion button. added support for CTRL+Dbl Click to auto-expand all child nodes. Tooltip for each node in the tree is the complete dotted package name Revision Changes Path 1.2 +205 -6 jakarta-log4j/src/java/org/apache/log4j/chainsaw/LoggerNameTreePanel.java Index: LoggerNameTreePanel.java =================================================================== RCS file: /home/cvs/jakarta-log4j/src/java/org/apache/log4j/chainsaw/LoggerNameTreePanel.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- LoggerNameTreePanel.java 1 Sep 2003 03:56:51 -0000 1.1 +++ LoggerNameTreePanel.java 1 Sep 2003 22:33:32 -0000 1.2 @@ -51,30 +51,229 @@ */ package org.apache.log4j.chainsaw; +import org.apache.log4j.chainsaw.icons.ChainsawIcons; +import org.apache.log4j.helpers.LogLog; + import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.ImageIcon; +import javax.swing.JButton; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTree; +import javax.swing.ToolTipManager; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeSelectionModel; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; /** + * A panel that encapsulates the Logger Name tree, with associated actions * * @author Paul Smith <[EMAIL PROTECTED]> */ final class LoggerNameTreePanel extends JPanel { + private static final int WARN_DEPTH = 4; + private final JTree logTree; + private final JScrollPane scrollTree; + private final JPanel toolbarPanel = new JPanel(); + private final JButton expandButton = new SmallButton(); + private final Action expandAction; - final JTree logTree ; - final JScrollPane scrollTree; /** * @param logTreeModel */ - LoggerNameTreePanel(LogPanelLoggerTreeModel logTreeModel) - { + LoggerNameTreePanel(LogPanelLoggerTreeModel logTreeModel) { super(new BorderLayout()); - logTree = new LoggerNameTree(logTreeModel); - + setBorder(BorderFactory.createEtchedBorder()); + + logTree = + new LoggerNameTree(logTreeModel) { + public String getToolTipText(MouseEvent ev) { + if (ev == null) { + return null; + } + + TreePath path = logTree.getPathForLocation(ev.getX(), ev.getY()); + + if (path != null) { + Object[] objects = path.getPath(); + StringBuffer buf = new StringBuffer(); + + for (int i = 1; i < objects.length; i++) { + buf.append(objects[i].toString()); + + if (i < (objects.length - 1)) { + buf.append("."); + } + } + + // TODO output the Level filter details + return buf.toString(); + } + + return null; + } + }; + + ToolTipManager.sharedInstance().registerComponent(logTree); + + // TODO decide if Multi-selection is useful, and how it would work + TreeSelectionModel selectionModel = new DefaultTreeSelectionModel(); + selectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); + logTree.setSelectionModel(selectionModel); + + logTree.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3)); scrollTree = new JScrollPane(logTree); + + toolbarPanel.setLayout(new BoxLayout(toolbarPanel, BoxLayout.X_AXIS)); + + expandAction = createExpandAction(); + + setupListeners(); + configureToolbarPanel(); + + add(toolbarPanel, BorderLayout.NORTH); add(scrollTree, BorderLayout.CENTER); + } + + /** + * Configures varoius listeners etc for the components within + * this Class. + */ + private void setupListeners() { + /** + * Enable the actions depending on state of the tree selection + */ + logTree.addTreeSelectionListener( + new TreeSelectionListener() { + public void valueChanged(TreeSelectionEvent e) { + TreePath path = e.getNewLeadSelectionPath(); + expandAction.setEnabled(path != null); + } + }); + + /** + * Now add a MouseListener that fires the expansion + * action if CTRL + DBL CLICK is done. + */ + logTree.addMouseListener( + new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + + if ( + (e.getClickCount() > 1) + && ((e.getModifiers() & InputEvent.CTRL_MASK) > 0) + && ((e.getModifiers() & InputEvent.BUTTON1_MASK) > 0)) { + expandCurrentlySelectedNode(); + } + } + }); + } + + /** + * Creates an action that is used to expand the selected node + * and all children + * @return an Action + */ + private Action createExpandAction() { + Action action = + new AbstractAction() { + public void actionPerformed(ActionEvent e) { + expandCurrentlySelectedNode(); + } + }; + + action.putValue(Action.NAME, "Expand branch"); + action.putValue( + Action.SHORT_DESCRIPTION, "Expands all the child nodes recursively"); + action.putValue( + Action.SMALL_ICON, new ImageIcon(ChainsawIcons.UNDOCKED_ICON)); + action.setEnabled(false); + + return action; + } + + /** + * Expands the currently selected node (if any) + * including all the children. + * + */ + private void expandCurrentlySelectedNode() { + TreePath[] paths = logTree.getSelectionPaths(); + + for (int i = 0; i < paths.length; i++) { + TreePath path = paths[i]; + DefaultMutableTreeNode treeNode = + (DefaultMutableTreeNode) path.getLastPathComponent(); + + Enumeration depthEnum = treeNode.depthFirstEnumeration(); + + if (!depthEnum.hasMoreElements()) { + break; + } + + List depths = new ArrayList(); + + while (depthEnum.hasMoreElements()) { + depths.add( + new Integer( + ((DefaultMutableTreeNode) depthEnum.nextElement()).getDepth())); + } + + Collections.sort(depths); + Collections.reverse(depths); + + int maxDepth = ((Integer) depths.get(0)).intValue(); + + if (maxDepth > WARN_DEPTH) { + LogLog.warn("Should warn user, depth=" + maxDepth); + } + + depthEnum = treeNode.depthFirstEnumeration(); + + while (depthEnum.hasMoreElements()) { + DefaultMutableTreeNode node = + (DefaultMutableTreeNode) depthEnum.nextElement(); + + if (node.isLeaf()) { + TreeNode[] nodes = + ((DefaultMutableTreeNode) node.getParent()).getPath(); + TreePath treePath = new TreePath(nodes); + + LogLog.debug("Expanding path:" + treePath); + + logTree.expandPath(treePath); + } + } + } + } + + /** + * configures all the components that are used in the mini-toolbar of this + * component + */ + private void configureToolbarPanel() { + expandButton.setAction(expandAction); + expandButton.setText(""); + toolbarPanel.add(expandButton); } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]