psmith 2003/09/15 15:13:27 Modified: src/java/org/apache/log4j/chainsaw LoggerNameTreePanel.java LogUI.java LogPanel.java Log: Added the concept of "hidding" a logger by being able to add it to an Ignore list. Only Loggers that are not on the Ignored list are shown. Revision Changes Path 1.10 +216 -64 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.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- LoggerNameTreePanel.java 11 Sep 2003 10:34:22 -0000 1.9 +++ LoggerNameTreePanel.java 15 Sep 2003 22:13:26 -0000 1.10 @@ -64,7 +64,9 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; +import java.util.HashSet; import java.util.List; +import java.util.Set; import javax.swing.AbstractAction; import javax.swing.Action; @@ -83,6 +85,9 @@ import javax.swing.JTree; import javax.swing.SwingUtilities; import javax.swing.ToolTipManager; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.EventListenerList; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.event.TreeSelectionEvent; @@ -114,12 +119,15 @@ private final JButton closeButton = new SmallButton(); private final SmallToggleButton focusOnLoggerButton = new SmallToggleButton(); + private final SmallToggleButton ignoreLoggerButton = new SmallToggleButton(); private final JButton editLoggerButton = new SmallButton(); private final Action expandAction; private final Action collapseAction; private final Action closeAction; private final Action editLoggerAction; private final Action focusOnAction; + private final Action hideAction; + private final Action clearIgnoreListAction; // private final EventListenerList focusOnActionListeners = // new EventListenerList(); @@ -128,6 +136,8 @@ new LoggerNameTreeCellRenderer(); private final LoggerTreePopupMenu popupMenu; private final PopupListener popupListener; + private final Set hiddenSet = new HashSet(); + private final EventListenerList listenerList = new EventListenerList(); /** * @param logTreeModel @@ -148,7 +158,13 @@ TreePath path = logTree.getPathForLocation(ev.getX(), ev.getY()); - return getLoggerName(path); + String loggerName = getLoggerName(path); + + if (hiddenSet.contains(loggerName)) { + loggerName += " (you are ignoring this logger)"; + } + + return loggerName; } }; @@ -158,16 +174,16 @@ // ============================================ logTreeModel.addTreeModelListener( new TreeModelListener() { - private boolean latched = false; + private boolean latched = false; + public void treeNodesChanged(TreeModelEvent e) { - } public void treeNodesInserted(TreeModelEvent e) { if (!latched) { - ensureRootExpanded(); - latched = true; - } + ensureRootExpanded(); + latched = true; + } } public void treeNodesRemoved(TreeModelEvent e) { @@ -194,6 +210,8 @@ closeAction = createCloseAction(); collapseAction = createCollapseAction(); focusOnAction = createFocusOnAction(); + hideAction = createIgnoreAction(); + clearIgnoreListAction = createClearIgnoreListAction(); popupMenu = new LoggerTreePopupMenu(); popupListener = new PopupListener(popupMenu); @@ -206,6 +224,90 @@ } /** + * Adds a change Listener to this LoggerNameTreePanel to be notfied + * when the State of the Focus or Hidden details have changed. + * + * @param l + */ + public void addChangeListener(ChangeListener l) { + listenerList.add(ChangeListener.class, l); + } + + public void removeChangeListener(ChangeListener l) { + listenerList.remove(ChangeListener.class, l); + } + + /** + * @return + */ + private Action createClearIgnoreListAction() { + Action action = + new AbstractAction("Clear Ignore list", null) { + public void actionPerformed(ActionEvent e) { + ignoreLoggerButton.setSelected(false); + logTreeModel.reload(); + hiddenSet.clear(); + } + }; + + action.putValue( + Action.SHORT_DESCRIPTION, + "Removes all entries from the Ignore list so you can see their events in the view"); + + return action; + } + + /** + * @return + */ + private Action createIgnoreAction() { + Action action = + new AbstractAction( + "Ignore this Logger", new ImageIcon(ChainsawIcons.ICON_COLLAPSE)) { + public void actionPerformed(ActionEvent e) { + String logger = getCurrentlySelectedLoggerName(); + + if (logger != null) { + toggleHiddenLogger(logger); + logTreeModel.nodeChanged( + (TreeNode) logTree.getSelectionPath().getLastPathComponent()); + ignoreLoggerButton.setSelected(hiddenSet.contains(logger)); + focusOnAction.setEnabled(!hiddenSet.contains(logger)); + popupMenu.hideCheck.setSelected(hiddenSet.contains(logger)); + } + fireChangeEvent(); + } + }; + + action.putValue( + Action.SHORT_DESCRIPTION, + "Adds the selected Logger to your Ignore list, filtering those events from view"); + + return action; + } + + /** + * @param logger + */ + protected void toggleHiddenLogger(String logger) { + if (!hiddenSet.contains(logger)) { + hiddenSet.add(logger); + } else { + hiddenSet.remove(logger); + } + + firePropertyChange("hiddenSet", (Object) null, (Object) null); + } + + /** + * Returns an unmodifiable set of those Loggers marked as hidden. + * @return + */ + Set getHiddenSet() { + return Collections.unmodifiableSet(hiddenSet); + } + + /** * @return */ private Action createFocusOnAction() { @@ -229,7 +331,7 @@ } private void toggleFocusOnState() { - setFocusOnSelected(!isFocusOnSelected()); + setFocusOnSelected(!isFocusOnSelected()); } /** @@ -277,14 +379,16 @@ } private void ensureRootExpanded() { - LogLog.debug("Ensuring Root node is expanded."); - final DefaultMutableTreeNode root = (DefaultMutableTreeNode) logTreeModel.getRoot(); - SwingUtilities.invokeLater(new Runnable(){ - - public void run() { - logTree.expandPath(new TreePath(root)); - - }}); + LogLog.debug("Ensuring Root node is expanded."); + + final DefaultMutableTreeNode root = + (DefaultMutableTreeNode) logTreeModel.getRoot(); + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + logTree.expandPath(new TreePath(root)); + } + }); } /** @@ -339,19 +443,34 @@ new TreeSelectionListener() { public void valueChanged(TreeSelectionEvent e) { TreePath path = e.getNewLeadSelectionPath(); - TreeNode node=null; - if(path!=null){ - node = (TreeNode) path.getLastPathComponent(); + TreeNode node = null; + + if (path != null) { + node = (TreeNode) path.getLastPathComponent(); } + // editLoggerAction.setEnabled(path != null); - focusOnAction.setEnabled(path != null && node!=null && node.getParent()!=null); - - if(!focusOnAction.isEnabled()){ - setFocusOnSelected(false); + String logger = getCurrentlySelectedLoggerName(); + focusOnAction.setEnabled( + (path != null) && (node != null) && (node.getParent() != null) && !hiddenSet.contains(logger)); + hideAction.setEnabled( + (path != null) && (node != null) && (node.getParent() != null)); + + if (!focusOnAction.isEnabled()) { + setFocusOnSelected(false); } + + expandAction.setEnabled(path != null); + + if (logger != null) { + boolean isHidden = hiddenSet.contains(logger); + popupMenu.hideCheck.setSelected(isHidden); + ignoreLoggerButton.setSelected(isHidden); + } + collapseAction.setEnabled(path != null); - + reconfigureFocusOnText(); } }); @@ -360,15 +479,20 @@ /** * This listener ensures the Tool bar toggle button and popup menu check box - * stay in sync + * stay in sync, plus notifies all the ChangeListeners that + * an effective filter criteria has been modified */ focusOnAction.addPropertyChangeListener( new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { popupMenu.focusOnCheck.setSelected(isFocusOnSelected()); focusOnLoggerButton.setSelected(isFocusOnSelected()); - logTreeModel.nodeChanged( - (TreeNode) logTree.getSelectionPath().getLastPathComponent()); + + if (logTree.getSelectionPath() != null) { + logTreeModel.nodeChanged( + (TreeNode) logTree.getSelectionPath().getLastPathComponent()); + } + fireChangeEvent(); } }); @@ -379,7 +503,6 @@ logTree.addMouseListener( new MouseAdapter() { public void mouseClicked(MouseEvent e) { - if ( (e.getClickCount() > 1) && ((e.getModifiers() & InputEvent.CTRL_MASK) > 0) @@ -387,50 +510,56 @@ expandCurrentlySelectedNode(); e.consume(); } else if (e.getClickCount() > 1) { - super.mouseClicked(e); + super.mouseClicked(e); LogLog.debug("Ignoring dbl click event " + e); } } }); } - - private void reconfigureFocusOnText() { - String logger = getCurrentlySelectedLoggerName(); - if(logger == null || logger.length()==0) { - focusOnAction.putValue(Action.NAME, "Focus On..."); - } else { - focusOnAction.putValue(Action.NAME, "Focus On '" + logger + "'"); - } - - // need to ensure the button doens't update itself with the text, looks stupid otherwise - focusOnLoggerButton.setText(null); + private void reconfigureFocusOnText() { + String logger = getCurrentlySelectedLoggerName(); + + if ((logger == null) || (logger.length() == 0)) { + focusOnAction.putValue(Action.NAME, "Focus On..."); + } else { + focusOnAction.putValue(Action.NAME, "Focus On '" + logger + "'"); } - - /** - * Returns true if the FocusOn element has been selected - * @return true if the FocusOn action/lement has been selected - */ + + // need to ensure the button doens't update itself with the text, looks stupid otherwise + focusOnLoggerButton.setText(null); + } + + /** + * Returns true if the FocusOn element has been selected + * @return true if the FocusOn action/lement has been selected + */ boolean isFocusOnSelected() { return focusOnAction.getValue("checked") != null; } - void setFocusOnSelected(boolean selected){ - - if (selected) { - focusOnAction.putValue("checked", Boolean.TRUE); - } else { - focusOnAction.putValue("checked", null); - } + void setFocusOnSelected(boolean selected) { + if (selected) { + focusOnAction.putValue("checked", Boolean.TRUE); + } else { + focusOnAction.putValue("checked", null); + } } - void addFocusOnPropertyChangeListener(PropertyChangeListener l) { - focusOnAction.addPropertyChangeListener(l); - } - void removeFocusOnPropertyChangeListener(PropertyChangeListener l) { - focusOnAction.removePropertyChangeListener(l); + private void fireChangeEvent() { + ChangeListener[] listeners = + (ChangeListener[]) listenerList.getListeners(ChangeListener.class); + ChangeEvent e = null; + + for (int i = 0; i < listeners.length; i++) { + if (e == null) { + e = new ChangeEvent(this); + } + + listeners[i].stateChanged(e); + } } - + private Action createEditLoggerAction() { Action action = new AbstractAction() { @@ -535,15 +664,17 @@ for (int i = 0; i < paths.length; i++) { TreePath path = paths[i]; + /** - * Handle an expansion of the Root node by only doing the first level. + * Handle an expansion of the Root node by only doing the first level. * Safe... */ - if(path.getPathCount()==1){ - logTree.expandPath(path); - return; + if (path.getPathCount() == 1) { + logTree.expandPath(path); + + return; } - + DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) path.getLastPathComponent(); @@ -602,6 +733,8 @@ collapseButton.setText(null); focusOnLoggerButton.setAction(focusOnAction); focusOnLoggerButton.setText(null); + ignoreLoggerButton.setAction(hideAction); + ignoreLoggerButton.setText(null); expandButton.setFont(expandButton.getFont().deriveFont(Font.BOLD)); collapseButton.setFont(collapseButton.getFont().deriveFont(Font.BOLD)); @@ -615,7 +748,9 @@ toolbar.add(collapseButton); toolbar.addSeparator(); toolbar.add(focusOnLoggerButton); - toolbar.add(editLoggerButton); + toolbar.add(ignoreLoggerButton); + + // toolbar.add(editLoggerButton); toolbar.addSeparator(); toolbar.add(Box.createHorizontalGlue()); @@ -661,12 +796,24 @@ component.setFont(originalFont.deriveFont(Font.PLAIN)); } + originalFont = component.getFont(); + + String logger = + ((DefaultMutableTreeNode) value).getUserObject().toString(); + + if (hiddenSet.contains(logger)) { + component.setEnabled(false); + } else { + component.setEnabled(true); + } + return component; } } private class LoggerTreePopupMenu extends JPopupMenu { JCheckBoxMenuItem focusOnCheck = new JCheckBoxMenuItem(); + JCheckBoxMenuItem hideCheck = new JCheckBoxMenuItem(); private LoggerTreePopupMenu() { initMenu(); @@ -680,8 +827,13 @@ add(collapseAction); addSeparator(); focusOnCheck.setAction(focusOnAction); + hideCheck.setAction(hideAction); add(focusOnCheck); - add(editLoggerAction); + add(hideCheck); + + // add(editLoggerAction); + addSeparator(); + add(clearIgnoreListAction); } /* (non-Javadoc) 1.29 +0 -1 jakarta-log4j/src/java/org/apache/log4j/chainsaw/LogUI.java Index: LogUI.java =================================================================== RCS file: /home/cvs/jakarta-log4j/src/java/org/apache/log4j/chainsaw/LogUI.java,v retrieving revision 1.28 retrieving revision 1.29 diff -u -r1.28 -r1.29 --- LogUI.java 15 Sep 2003 06:38:35 -0000 1.28 +++ LogUI.java 15 Sep 2003 22:13:26 -0000 1.29 @@ -558,7 +558,6 @@ public void propertyChange(PropertyChangeEvent evt) { double dataRate = ((Double)evt.getNewValue()).doubleValue(); - LogLog.debug("dataRate=" + dataRate); statusBar.setDataRate(dataRate); }}); 1.10 +97 -65 jakarta-log4j/src/java/org/apache/log4j/chainsaw/LogPanel.java Index: LogPanel.java =================================================================== RCS file: /home/cvs/jakarta-log4j/src/java/org/apache/log4j/chainsaw/LogPanel.java,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- LogPanel.java 14 Sep 2003 04:08:16 -0000 1.9 +++ LogPanel.java 15 Sep 2003 22:13:27 -0000 1.10 @@ -55,6 +55,22 @@ */ package org.apache.log4j.chainsaw; +import org.apache.log4j.Layout; +import org.apache.log4j.PatternLayout; +import org.apache.log4j.chainsaw.filter.FilterModel; +import org.apache.log4j.chainsaw.icons.ChainsawIcons; +import org.apache.log4j.chainsaw.icons.LineIconFactory; +import org.apache.log4j.chainsaw.layout.DefaultLayoutFactory; +import org.apache.log4j.chainsaw.layout.EventDetailLayout; +import org.apache.log4j.chainsaw.layout.LayoutEditorPane; +import org.apache.log4j.chainsaw.prefs.LoadSettingsEvent; +import org.apache.log4j.chainsaw.prefs.SaveSettingsEvent; +import org.apache.log4j.chainsaw.prefs.SettingsListener; +import org.apache.log4j.chainsaw.prefs.SettingsManager; +import org.apache.log4j.chainsaw.rule.AbstractRule; +import org.apache.log4j.helpers.LogLog; +import org.apache.log4j.spi.LoggingEvent; + import java.awt.BorderLayout; import java.awt.Container; import java.awt.Dimension; @@ -73,8 +89,10 @@ import java.awt.event.MouseMotionAdapter; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; + import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; + import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.EOFException; @@ -86,7 +104,9 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; + import java.text.NumberFormat; + import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; @@ -129,32 +149,16 @@ import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.event.TableColumnModelEvent; import javax.swing.event.TableColumnModelListener; -import javax.swing.table.AbstractTableModel; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; -import org.apache.log4j.Layout; -import org.apache.log4j.PatternLayout; -import org.apache.log4j.chainsaw.filter.FilterModel; -import org.apache.log4j.chainsaw.icons.ChainsawIcons; -import org.apache.log4j.chainsaw.icons.LineIconFactory; -import org.apache.log4j.chainsaw.layout.DefaultLayoutFactory; -import org.apache.log4j.chainsaw.layout.EventDetailLayout; -import org.apache.log4j.chainsaw.layout.LayoutEditorPane; -import org.apache.log4j.chainsaw.prefs.LoadSettingsEvent; -import org.apache.log4j.chainsaw.prefs.SaveSettingsEvent; -import org.apache.log4j.chainsaw.prefs.SettingsListener; -import org.apache.log4j.chainsaw.prefs.SettingsManager; -import org.apache.log4j.chainsaw.rule.AbstractRule; -import org.apache.log4j.helpers.LogLog; -import org.apache.log4j.spi.LoggingEvent; - /** * LogPanel encapsulates all the necessary bits and pieces of a @@ -233,15 +237,20 @@ table.addColumn(new TableColumn(e.getNewModelIndex())); } }); - tableModel.addPropertyChangeListener("cyclic", new PropertyChangeListener(){ - - public void propertyChange(PropertyChangeEvent arg0) { - if(tableModel.isCyclic()){ - statusBar.setMessage("Changed to Cyclic Mode. Maximum # events kept: " + tableModel.getMaxSize()); - } else{ - statusBar.setMessage("Changed to Unlimited Mode. Warning, you may run out of memory."); - } - }}); + tableModel.addPropertyChangeListener( + "cyclic", + new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent arg0) { + if (tableModel.isCyclic()) { + statusBar.setMessage( + "Changed to Cyclic Mode. Maximum # events kept: " + + tableModel.getMaxSize()); + } else { + statusBar.setMessage( + "Changed to Unlimited Mode. Warning, you may run out of memory."); + } + } + }); table.setRowHeight(20); table.setShowGrid(false); @@ -262,21 +271,39 @@ * We listen for when the FocusOn action changes, and then ensure the Refinement filter is set * accordingly. */ - logTreePanel.addFocusOnPropertyChangeListener( - new PropertyChangeListener() { - public void propertyChange(PropertyChangeEvent evt) { - if (logTreePanel.isFocusOnSelected()) { - final String loggerName = - logTreePanel.getCurrentlySelectedLoggerName(); - ruleMediator.setRefinementRule( - new AbstractRule() { - public boolean evaluate(LoggingEvent e) { - return e.getLoggerName().startsWith(loggerName); - } - }); - } else { - ruleMediator.setRefinementRule(null); - } + logTreePanel.addChangeListener( + new ChangeListener() { + public void stateChanged(ChangeEvent evt) { + final String currentlySelectedLoggerName = + logTreePanel.getCurrentlySelectedLoggerName(); + + /** + * We run this later so that the GUI gets a chance to repaint + * etc, this might take a little time. + */ + SwingUtilities.invokeLater( + new Runnable() { + public void run() { + ruleMediator.setRefinementRule( + new AbstractRule() { + public boolean evaluate(LoggingEvent e) { + boolean isHidden = + logTreePanel.getHiddenSet().contains( + e.getLoggerName()); + boolean result = !isHidden; + + if (result && logTreePanel.isFocusOnSelected()) { + result = + result + && e.getLoggerName().startsWith( + currentlySelectedLoggerName); + } + + return result; + } + }); + } + }); } }); @@ -624,17 +651,22 @@ detailToolbar.add(editDetailButton); detailToolbar.addSeparator(); detailToolbar.add(Box.createHorizontalStrut(5)); - - Action closeDetailAction = new AbstractAction(null, LineIconFactory.createCloseIcon()){ - public void actionPerformed(ActionEvent arg0) { - toggleDetailPanel(); - }}; - closeDetailAction.putValue(Action.SHORT_DESCRIPTION, "Hides the Detail Panel"); + Action closeDetailAction = + new AbstractAction(null, LineIconFactory.createCloseIcon()) { + public void actionPerformed(ActionEvent arg0) { + toggleDetailPanel(); + } + }; + + closeDetailAction.putValue( + Action.SHORT_DESCRIPTION, "Hides the Detail Panel"); + SmallButton closeDetailButton = new SmallButton(closeDetailAction); detailToolbar.add(closeDetailButton); detailPanel.add(detailToolbar, BorderLayout.NORTH); + JPopupMenu editDetailPopupMenu = new JPopupMenu(); editDetailPopupMenu.add(editDetailAction); editDetailPopupMenu.addSeparator(); @@ -852,16 +884,15 @@ menuItemScrollBottom.setIcon( new ImageIcon(ChainsawIcons.SCROLL_TO_BOTTOM)); -// JMenuItem menuItemRemoveColorFilter = -// new JMenuItem("Remove all color filters"); -// menuItemRemoveColorFilter.addActionListener( -// new ActionListener() { -// public void actionPerformed(ActionEvent evt) { -// // colorDisplaySelector.clearColors(); -// colorFilter.clear(); -// } -// }); - + // JMenuItem menuItemRemoveColorFilter = + // new JMenuItem("Remove all color filters"); + // menuItemRemoveColorFilter.addActionListener( + // new ActionListener() { + // public void actionPerformed(ActionEvent evt) { + // // colorDisplaySelector.clearColors(); + // colorFilter.clear(); + // } + // }); JMenuItem menuItemColumnSelector = new JMenuItem("Select display columns..."); menuItemColumnSelector.addActionListener( @@ -920,21 +951,22 @@ p.add(new JSeparator()); p.add(menuItemDisplayFilter); - p.add(menuColumnDisplayFilter); - p.add(menuColumnColorFilter); + + // p.add(menuColumnDisplayFilter); + // p.add(menuColumnColorFilter); p.add(new JSeparator()); - JMenu removeSubMenu = new JMenu("Remove"); + // JMenu removeSubMenu = new JMenu("Remove"); JMenu selectSubMenu = new JMenu("Select"); selectSubMenu.add(menuItemColumnSelector); -// removeSubMenu.add(menuItemRemoveColorFilter); - removeSubMenu.add(menuItemRemoveDisplayFilter); - - p.add(selectSubMenu); - p.add(removeSubMenu); + // removeSubMenu.add(menuItemRemoveColorFilter); + // removeSubMenu.add(menuItemRemoveDisplayFilter); + p.add(menuItemColumnSelector); + // p.add(selectSubMenu); + // p.add(removeSubMenu); final PopupListener popupListener = new PopupListener(p); eventsPane.addMouseListener(popupListener);
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]