blob: 9d73a5cc9a7d9cfb2550cbbf5ddef9ed38a9d4c2 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
*/
package org.apache.log4j.chainsaw;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JColorChooser;
import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.UIManager;
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;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeSelectionModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.chainsaw.color.RuleColorizer;
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.rule.AbstractRule;
import org.apache.log4j.rule.ColorRule;
import org.apache.log4j.rule.ExpressionRule;
import org.apache.log4j.rule.Rule;
import org.apache.log4j.spi.LoggingEvent;
/**
* A panel that encapsulates the Logger Name tree, with associated actions
* and implements the Rule interface so that it can filter in/out events
* that do not match the users request for refining the view based on Loggers.
*
* @author Paul Smith <psmith@apache.org>
*/
final class LoggerNameTreePanel extends JPanel implements LoggerNameListener
{
//~ Static fields/initializers ==============================================
private static final int WARN_DEPTH = 4;
//~ Instance fields =========================================================
private LoggerNameTreeCellRenderer cellRenderer =
new LoggerNameTreeCellRenderer();
private final Action clearIgnoreListAction;
private final Action closeAction;
private final JButton closeButton = new SmallButton();
private final Action collapseAction;
private final JButton collapseButton = new SmallButton();
private final Action editLoggerAction;
private final JButton editLoggerButton = new SmallButton();
private final Action expandAction;
private final Action findAction;
private final Action clearFindNextAction;
private final Action defineColorRuleForLoggerAction;
private final Action setRefineFocusAction;
private final Action updateRefineFocusAction;
private final Action updateFindAction;
private final JButton expandButton = new SmallButton();
private final Action focusOnAction;
private final Action clearRefineFocusAction;
private final SmallToggleButton focusOnLoggerButton =
new SmallToggleButton();
private final Set hiddenSet = new HashSet();
private final Action hideAction;
private final Action hideSubLoggersAction;
private final LogPanelPreferenceModel preferenceModel;
private final JList ignoreList = new JList();
private final JEditorPane ignoreExpressionEntryField = new JEditorPane();
private final JEditorPane alwaysDisplayExpressionEntryField = new JEditorPane();
private final JScrollPane ignoreListScroll = new JScrollPane(ignoreList);
private final JDialog ignoreDialog = new JDialog();
private final JDialog ignoreExpressionDialog = new JDialog();
private final JDialog alwaysDisplayExpressionDialog = new JDialog();
private final JLabel ignoreSummary = new JLabel("0 hidden loggers");
private final JLabel ignoreExpressionSummary = new JLabel("Ignore expression");
private final JLabel alwaysDisplayExpressionSummary = new JLabel("Always displayed expression");
private final SmallToggleButton ignoreLoggerButton = new SmallToggleButton();
private final EventListenerList listenerList = new EventListenerList();
private final JTree logTree;
private final Logger logger = LogManager.getLogger(LoggerNameTreePanel.class);
// private final EventListenerList focusOnActionListeners =
// new EventListenerList();
private final LogPanelLoggerTreeModel logTreeModel;
private final PopupListener popupListener;
private final LoggerTreePopupMenu popupMenu;
private final VisibilityRuleDelegate visibilityRuleDelegate;
private Rule colorRuleDelegate;
private final JScrollPane scrollTree;
private final JToolBar toolbar = new JToolBar();
private final LogPanel logPanel;
private final RuleColorizer colorizer;
private Rule ignoreExpressionRule;
private Rule alwaysDisplayExpressionRule;
private boolean expandRootLatch = false;
private String currentlySelectedLoggerName;
//~ Constructors ============================================================
/**
* Creates a new LoggerNameTreePanel object.
*
* @param logTreeModel
*/
LoggerNameTreePanel(LogPanelLoggerTreeModel logTreeModel, LogPanelPreferenceModel preferenceModel, LogPanel logPanel, RuleColorizer colorizer, FilterModel filterModel)
{
super();
this.logTreeModel = logTreeModel;
this.preferenceModel = preferenceModel;
this.logPanel = logPanel;
this.colorizer = colorizer;
setLayout(new BorderLayout());
ignoreExpressionEntryField.setPreferredSize(new Dimension(300, 150));
alwaysDisplayExpressionEntryField.setPreferredSize(new Dimension(300, 150));
alwaysDisplayExpressionSummary.setMinimumSize(new Dimension(10, alwaysDisplayExpressionSummary.getHeight()));
ignoreExpressionSummary.setMinimumSize(new Dimension(10, ignoreExpressionSummary.getHeight()));
ignoreSummary.setMinimumSize(new Dimension(10, ignoreSummary.getHeight()));
JTextComponentFormatter.applySystemFontAndSize(ignoreExpressionEntryField);
JTextComponentFormatter.applySystemFontAndSize(alwaysDisplayExpressionEntryField);
visibilityRuleDelegate = new VisibilityRuleDelegate();
colorRuleDelegate =
new AbstractRule()
{
public boolean evaluate(LoggingEvent e, Map matches)
{
boolean hiddenLogger = e.getLoggerName() != null && isHiddenLogger(e.getLoggerName());
boolean hiddenExpression = (ignoreExpressionRule != null && ignoreExpressionRule.evaluate(e, null));
boolean alwaysDisplayExpression = (alwaysDisplayExpressionRule != null && alwaysDisplayExpressionRule.evaluate(e, null));
boolean hidden = (!alwaysDisplayExpression) && (hiddenLogger || hiddenExpression);
String currentlySelectedLoggerName = getCurrentlySelectedLoggerName();
if (!isFocusOnSelected() && !hidden && currentlySelectedLoggerName != null && !"".equals(currentlySelectedLoggerName))
{
return (e.getLoggerName().startsWith(currentlySelectedLoggerName+".") || e.getLoggerName().endsWith(currentlySelectedLoggerName)) ;
}
return false;
}
};
logTree =
new JTree(logTreeModel)
{
public String getToolTipText(MouseEvent ev)
{
if (ev == null)
{
return null;
}
TreePath path = logTree.getPathForLocation(ev.getX(), ev.getY());
String loggerName = getLoggerName(path);
if (hiddenSet.contains(loggerName))
{
loggerName += " (you are ignoring this logger)";
}
return loggerName;
}
};
ToolTipManager.sharedInstance().registerComponent(logTree);
logTree.setCellRenderer(cellRenderer);
// ============================================
logTreeModel.addTreeModelListener(new TreeModelListener()
{
public void treeNodesChanged(TreeModelEvent e)
{
}
public void treeNodesInserted(TreeModelEvent e)
{
if (!expandRootLatch)
{
ensureRootExpanded();
expandRootLatch = true;
}
}
public void treeNodesRemoved(TreeModelEvent e)
{
}
public void treeStructureChanged(TreeModelEvent e)
{
}
});
logTree.setEditable(false);
// 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);
toolbar.setLayout(new BoxLayout(toolbar, BoxLayout.X_AXIS));
expandAction = createExpandAction();
findAction = createFindNextAction();
clearFindNextAction = createClearFindNextAction();
defineColorRuleForLoggerAction = createDefineColorRuleForLoggerAction();
clearRefineFocusAction = createClearRefineFocusAction();
setRefineFocusAction = createSetRefineFocusAction();
updateRefineFocusAction = createUpdateRefineFocusAction();
updateFindAction = createUpdateFindAction();
editLoggerAction = createEditLoggerAction();
closeAction = createCloseAction();
collapseAction = createCollapseAction();
focusOnAction = createFocusOnAction();
hideAction = createIgnoreAction();
hideSubLoggersAction = createIgnoreAllAction();
clearIgnoreListAction = createClearIgnoreListAction();
popupMenu = new LoggerTreePopupMenu();
popupListener = new PopupListener(popupMenu);
setupListeners();
configureToolbarPanel();
add(toolbar, BorderLayout.NORTH);
add(scrollTree, BorderLayout.CENTER);
ignoreDialog.setTitle("Hidden/Ignored Loggers");
ignoreDialog.setModal(true);
ignoreExpressionDialog.setTitle("Hidden/Ignored Expression");
ignoreExpressionDialog.setModal(true);
alwaysDisplayExpressionDialog.setTitle("Always displayed Expression");
alwaysDisplayExpressionDialog.setModal(true);
JPanel ignorePanel = new JPanel();
ignorePanel.setLayout(new BoxLayout(ignorePanel, BoxLayout.Y_AXIS));
JPanel ignoreSummaryPanel = new JPanel();
ignoreSummaryPanel.setLayout(new BoxLayout(ignoreSummaryPanel, BoxLayout.X_AXIS));
ignoreSummaryPanel.add(ignoreSummary);
Action showIgnoreDialogAction = new AbstractAction("...") {
public void actionPerformed(ActionEvent e) {
LogPanel.centerAndSetVisible(ignoreDialog);
}
};
Action showIgnoreExpressionDialogAction = new AbstractAction("...") {
public void actionPerformed(ActionEvent e) {
LogPanel.centerAndSetVisible(ignoreExpressionDialog);
}
};
Action showAlwaysDisplayExpressionDialogAction = new AbstractAction("...") {
public void actionPerformed(ActionEvent e) {
LogPanel.centerAndSetVisible(alwaysDisplayExpressionDialog);
}
};
showIgnoreDialogAction.putValue(Action.SHORT_DESCRIPTION, "Click to view and manage your hidden/ignored loggers");
JButton btnShowIgnoreDialog = new SmallButton(showIgnoreDialogAction);
ignoreSummaryPanel.add(btnShowIgnoreDialog);
ignorePanel.add(ignoreSummaryPanel);
JPanel ignoreExpressionPanel = new JPanel();
ignoreExpressionPanel.setLayout(new BoxLayout(ignoreExpressionPanel, BoxLayout.X_AXIS));
ignoreExpressionPanel.add(ignoreExpressionSummary);
showIgnoreExpressionDialogAction.putValue(Action.SHORT_DESCRIPTION, "Click to view and manage your hidden/ignored expression");
JButton btnShowIgnoreExpressionDialog = new SmallButton(showIgnoreExpressionDialogAction);
ignoreExpressionPanel.add(btnShowIgnoreExpressionDialog);
ignorePanel.add(ignoreExpressionPanel);
JPanel alwaysDisplayExpressionPanel = new JPanel();
alwaysDisplayExpressionPanel.setLayout(new BoxLayout(alwaysDisplayExpressionPanel, BoxLayout.X_AXIS));
alwaysDisplayExpressionPanel.add(alwaysDisplayExpressionSummary);
showAlwaysDisplayExpressionDialogAction.putValue(Action.SHORT_DESCRIPTION, "Click to view and manage your always-displayed expression");
JButton btnShowAlwaysDisplayExpressionDialog = new SmallButton(showAlwaysDisplayExpressionDialogAction);
alwaysDisplayExpressionPanel.add(btnShowAlwaysDisplayExpressionDialog);
ignorePanel.add(alwaysDisplayExpressionPanel);
add(ignorePanel, BorderLayout.SOUTH);
ignoreList.setModel(new DefaultListModel());
ignoreList.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
if (
(e.getClickCount() > 1)
&& ((e.getModifiers() & InputEvent.BUTTON1_MASK) > 0))
{
int index = ignoreList.locationToIndex(e.getPoint());
if (index >= 0)
{
String string =
ignoreList.getModel().getElementAt(index).toString();
toggleHiddenLogger(string);
fireChangeEvent();
/**
* TODO this needs to get the node that has this logger and fire a visual update
*/
LoggerNameTreePanel.this.logTreeModel.nodeStructureChanged(
(TreeNode) LoggerNameTreePanel.this.logTreeModel.getRoot());
}
}
}
});
JPanel ignoreListPanel = new JPanel(new BorderLayout());
ignoreListScroll.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),"Double click an entry to unhide it"));
ignoreListPanel.add(ignoreListScroll, BorderLayout.CENTER);
JPanel ignoreExpressionDialogPanel = new JPanel(new BorderLayout());
ignoreExpressionEntryField.addKeyListener(new ExpressionRuleContext(filterModel, ignoreExpressionEntryField));
ignoreExpressionDialogPanel.add(new JScrollPane(ignoreExpressionEntryField), BorderLayout.CENTER);
JButton ignoreExpressionCloseButton = new JButton(new AbstractAction(" Close ") {
public void actionPerformed(ActionEvent e)
{
String ignoreText = ignoreExpressionEntryField.getText();
if (updateIgnoreExpression(ignoreText)) {
ignoreExpressionDialog.setVisible(false);
}
}});
JPanel alwaysDisplayExpressionDialogPanel = new JPanel(new BorderLayout());
alwaysDisplayExpressionEntryField.addKeyListener(new ExpressionRuleContext(filterModel, alwaysDisplayExpressionEntryField));
alwaysDisplayExpressionDialogPanel.add(new JScrollPane(alwaysDisplayExpressionEntryField), BorderLayout.CENTER);
JButton alwaysDisplayExpressionCloseButton = new JButton(new AbstractAction(" Close ") {
public void actionPerformed(ActionEvent e)
{
String alwaysDisplayText = alwaysDisplayExpressionEntryField.getText();
if (updateAlwaysDisplayExpression(alwaysDisplayText)) {
alwaysDisplayExpressionDialog.setVisible(false);
}
}});
JPanel closeAlwaysDisplayExpressionPanel = new JPanel();
closeAlwaysDisplayExpressionPanel.add(alwaysDisplayExpressionCloseButton);
alwaysDisplayExpressionDialogPanel.add(closeAlwaysDisplayExpressionPanel, BorderLayout.SOUTH);
JPanel closeIgnoreExpressionPanel = new JPanel();
closeIgnoreExpressionPanel.add(ignoreExpressionCloseButton);
ignoreExpressionDialogPanel.add(closeIgnoreExpressionPanel, BorderLayout.SOUTH);
Box ignoreListButtonPanel = Box.createHorizontalBox();
JButton unhideAll = new JButton(new AbstractAction(" Unhide All ") {
public void actionPerformed(final ActionEvent e)
{
SwingUtilities.invokeLater(new Runnable() {
public void run()
{
clearIgnoreListAction.actionPerformed(e);
}});
}});
ignoreListButtonPanel.add(unhideAll);
ignoreListButtonPanel.add(Box.createHorizontalGlue());
JButton ignoreCloseButton = new JButton(new AbstractAction(" Close ") {
public void actionPerformed(ActionEvent e)
{
ignoreDialog.setVisible(false);
}});
ignoreListButtonPanel.add(ignoreCloseButton);
ignoreListPanel.add(ignoreListButtonPanel, BorderLayout.SOUTH);
ignoreDialog.getContentPane().add(ignoreListPanel);
ignoreDialog.pack();
ignoreExpressionDialog.getContentPane().add(ignoreExpressionDialogPanel);
ignoreExpressionDialog.pack();
alwaysDisplayExpressionDialog.getContentPane().add(alwaysDisplayExpressionDialogPanel);
alwaysDisplayExpressionDialog.pack();
}
private boolean updateIgnoreExpression(String ignoreText)
{
try {
if (ignoreText != null && !ignoreText.trim().equals("")) {
ignoreExpressionRule = ExpressionRule.getRule(ignoreText);
} else {
ignoreExpressionRule = null;
}
visibilityRuleDelegate.firePropertyChange("hiddenSet", null, null);
updateDisplay();
ignoreExpressionEntryField.setBackground(UIManager.getColor("TextField.background"));
return true;
} catch (IllegalArgumentException iae) {
ignoreExpressionEntryField.setToolTipText(iae.getMessage());
ignoreExpressionEntryField.setBackground(ChainsawConstants.INVALID_EXPRESSION_BACKGROUND);
return false;
}
}
private boolean updateAlwaysDisplayExpression(String alwaysDisplayText)
{
try {
if (alwaysDisplayText != null && !alwaysDisplayText.trim().equals("")) {
alwaysDisplayExpressionRule = ExpressionRule.getRule(alwaysDisplayText);
} else {
alwaysDisplayExpressionRule = null;
}
visibilityRuleDelegate.firePropertyChange("alwaysDisplayedSet", null, null);
updateDisplay();
alwaysDisplayExpressionEntryField.setBackground(UIManager.getColor("TextField.background"));
return true;
} catch (IllegalArgumentException iae) {
alwaysDisplayExpressionEntryField.setToolTipText(iae.getMessage());
alwaysDisplayExpressionEntryField.setBackground(ChainsawConstants.INVALID_EXPRESSION_BACKGROUND);
return false;
}
}
//~ Methods =================================================================
/**
* 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 Rule getLoggerColorRule() {
return colorRuleDelegate;
}
public Rule getLoggerVisibilityRule() {
return visibilityRuleDelegate;
}
/**
* DOCUMENT ME!
*
* @param l DOCUMENT ME!
*/
public void removeChangeListener(ChangeListener l)
{
listenerList.remove(ChangeListener.class, l);
}
/**
* Ensures the Focus is set to a specific logger name
* @param
*/
public void setFocusOn(String newLogger)
{
DefaultMutableTreeNode node = logTreeModel.lookupLogger(newLogger);
if (node != null)
{
TreeNode[] nodes = node.getPath();
TreePath treePath = new TreePath(nodes);
logTree.setSelectionPath(treePath);
if (!focusOnLoggerButton.isSelected())
{
focusOnLoggerButton.doClick();
}
}
else
{
logger.error("failed to lookup logger " + newLogger);
}
}
private boolean isHiddenLogger(String loggerName) {
for (Iterator iter = hiddenSet.iterator();iter.hasNext();) {
String hiddenLoggerEntry = iter.next().toString();
if (loggerName.startsWith(hiddenLoggerEntry + ".") || loggerName.endsWith(hiddenLoggerEntry)) {
return true;
}
}
return false;
}
/**
* DOCUMENT ME!
*
* @param logger
*/
protected void toggleHiddenLogger(String logger)
{
if (!hiddenSet.contains(logger))
{
hiddenSet.add(logger);
}
else
{
hiddenSet.remove(logger);
}
visibilityRuleDelegate.firePropertyChange("hiddenSet", null, null);
}
/**
* Returns the full name of the Logger that is represented by
* the currently selected Logger node in the tree.
*
* This is the dotted name, of the current node including all it's parents.
*
* If multiple Nodes are selected, the first path is used
* @return Logger Name or null if nothing selected
*/
String getCurrentlySelectedLoggerName()
{
TreePath[] paths = logTree.getSelectionPaths();
if ((paths == null) || (paths.length == 0))
{
return null;
}
TreePath firstPath = paths[0];
return getLoggerName(firstPath);
}
/**
* Returns the full
* @param path DOCUMENT ME!
* @return
*/
String getLoggerName(TreePath path)
{
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(".");
}
}
return buf.toString();
}
return null;
}
/**
* adds a Collection of Strings to the ignore List and notifise all listeners of
* both the "hiddenSet" property and those expecting the Rule to change
* via the ChangeListener interface
* @param fqnLoggersToIgnore
*/
void ignore(Collection fqnLoggersToIgnore)
{
hiddenSet.addAll(fqnLoggersToIgnore);
visibilityRuleDelegate.firePropertyChange("hiddenSet", null, null);
fireChangeEvent();
}
/**
* 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);
}
}
/**
* Given the currently selected nodes
* collapses all the children of those nodes.
*
*/
private void collapseCurrentlySelectedNode()
{
TreePath[] paths = logTree.getSelectionPaths();
if (paths == null)
{
return;
}
logger.debug("Collapsing all children of selected node");
for (int i = 0; i < paths.length; i++)
{
TreePath path = paths[i];
DefaultMutableTreeNode node =
(DefaultMutableTreeNode) path.getLastPathComponent();
Enumeration enumeration = node.depthFirstEnumeration();
while (enumeration.hasMoreElements())
{
DefaultMutableTreeNode child =
(DefaultMutableTreeNode) enumeration.nextElement();
if ((child.getParent() != null) && (child != node))
{
TreeNode[] nodes =
((DefaultMutableTreeNode) child.getParent()).getPath();
TreePath treePath = new TreePath(nodes);
logTree.collapsePath(treePath);
}
}
}
ensureRootExpanded();
}
/**
* configures all the components that are used in the mini-toolbar of this
* component
*/
private void configureToolbarPanel()
{
toolbar.setFloatable(false);
expandButton.setAction(expandAction);
expandButton.setText(null);
collapseButton.setAction(collapseAction);
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));
editLoggerButton.setAction(editLoggerAction);
editLoggerButton.setText(null);
closeButton.setAction(closeAction);
closeButton.setText(null);
toolbar.add(expandButton);
toolbar.add(collapseButton);
toolbar.addSeparator();
toolbar.add(focusOnLoggerButton);
toolbar.add(ignoreLoggerButton);
// toolbar.add(editLoggerButton);
toolbar.addSeparator();
toolbar.add(Box.createHorizontalGlue());
toolbar.add(closeButton);
toolbar.add(Box.createHorizontalStrut(5));
}
/**
* DOCUMENT ME!
*
* @return
*/
private Action createClearIgnoreListAction()
{
Action action = new AbstractAction("Clear Ignore list", null)
{
public void actionPerformed(ActionEvent e)
{
ignoreLoggerButton.setSelected(false);
logTreeModel.reload();
hiddenSet.clear();
fireChangeEvent();
}
};
action.putValue(
Action.SHORT_DESCRIPTION,
"Removes all entries from the Ignore list so you can see their events in the view");
return action;
}
/**
* An action that closes (hides) this panel
* @return
*/
private Action createCloseAction()
{
Action action = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
preferenceModel.setLogTreePanelVisible(false);
}
};
action.putValue(Action.NAME, "Close");
action.putValue(Action.SHORT_DESCRIPTION, "Closes the Logger panel");
action.putValue(Action.SMALL_ICON, LineIconFactory.createCloseIcon());
return action;
}
/**
* DOCUMENT ME!
*
* @return
*/
private Action createCollapseAction()
{
Action action = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
collapseCurrentlySelectedNode();
}
};
action.putValue(Action.SMALL_ICON, LineIconFactory.createCollapseIcon());
action.putValue(Action.NAME, "Collapse Branch");
action.putValue(
Action.SHORT_DESCRIPTION,
"Collapses all the children of the currently selected node");
action.setEnabled(false);
return action;
}
private Action createEditLoggerAction()
{
Action action = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
// TODO Auto-generated method stub
}
};
// TODO enable this when it's ready.
action.putValue("enabled", Boolean.FALSE);
action.putValue(Action.NAME, "Edit filters/colors");
action.putValue(
Action.SHORT_DESCRIPTION,
"Allows you to specify filters and coloring for this Logger");
action.putValue(
Action.SMALL_ICON, new ImageIcon(ChainsawIcons.ICON_EDIT_RECEIVER));
action.setEnabled(false);
return action;
}
/**
* 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.SMALL_ICON, LineIconFactory.createExpandIcon());
action.putValue(Action.NAME, "Expand branch");
action.putValue(
Action.SHORT_DESCRIPTION,
"Expands all the child nodes of the currently selected node, recursively");
action.setEnabled(false);
return action;
}
/**
* Creates an action that is used to find the next match of the selected node (similar to default selection behavior
* except the search field is populated and the next match is selected.
* @return an Action
*/
private Action createFindNextAction()
{
Action action = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
findNextUsingCurrentlySelectedNode();
}
};
action.putValue(Action.NAME, "Find next");
action.putValue(
Action.SHORT_DESCRIPTION,
"Find using the selected node");
action.setEnabled(false);
return action;
}
private Action createSetRefineFocusAction()
{
Action action = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
setRefineFocusUsingCurrentlySelectedNode();
}
};
action.putValue(Action.NAME, "Set 'refine focus' to selected logger");
action.putValue(
Action.SHORT_DESCRIPTION,
"Refine focus on the selected node");
action.setEnabled(false);
return action;
}
private Action createUpdateRefineFocusAction()
{
Action action = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
updateRefineFocusUsingCurrentlySelectedNode();
}
};
action.putValue(Action.NAME, "Update 'refine focus' to include selected logger");
action.putValue(
Action.SHORT_DESCRIPTION,
"Add selected node to 'refine focus' field");
action.setEnabled(false);
return action;
}
private Action createUpdateFindAction()
{
Action action = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
updateFindUsingCurrentlySelectedNode();
}
};
action.putValue(Action.NAME, "Update 'find' to include selected logger");
action.putValue(
Action.SHORT_DESCRIPTION,
"Add selected node to 'find' field");
action.setEnabled(false);
return action;
}
private void updateFindUsingCurrentlySelectedNode()
{
String selectedLogger = getCurrentlySelectedLoggerName();
TreePath[] paths = logTree.getSelectionPaths();
if (paths == null)
{
return;
}
String currentFindText = logPanel.getFindText();
logPanel.setFindText(currentFindText + " || logger ~= " + selectedLogger);
}
private void updateRefineFocusUsingCurrentlySelectedNode()
{
String selectedLogger = getCurrentlySelectedLoggerName();
TreePath[] paths = logTree.getSelectionPaths();
if (paths == null)
{
return;
}
String currentFilterText = logPanel.getRefineFocusText();
logPanel.setRefineFocusText(currentFilterText + " || logger ~= " + selectedLogger);
}
private void setRefineFocusUsingCurrentlySelectedNode()
{
String selectedLogger = getCurrentlySelectedLoggerName();
TreePath[] paths = logTree.getSelectionPaths();
if (paths == null)
{
return;
}
logPanel.setRefineFocusText("logger ~= " + selectedLogger);
}
private Action createDefineColorRuleForLoggerAction() {
Action action = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
String selectedLogger = getCurrentlySelectedLoggerName();
TreePath[] paths = logTree.getSelectionPaths();
if (paths == null)
{
return;
}
Color c = JColorChooser.showDialog(getRootPane(), "Choose a color", Color.red);
if (c != null) {
String expression = "logger like '^" + selectedLogger + ".*'";
colorizer.addRule(ChainsawConstants.DEFAULT_COLOR_RULE_NAME, new ColorRule(expression,
ExpressionRule.getRule(expression), c, ChainsawConstants.COLOR_DEFAULT_FOREGROUND));
}
}};
action.putValue(Action.NAME, "Define color rule for selected logger");
action.putValue(
Action.SHORT_DESCRIPTION,
"Define color rule for logger");
action.setEnabled(false);
return action;
}
/**
* Creates an action that is used to find the next match of the selected node (similar to default selection behavior
* except the search field is populated and the next match is selected.
* @return an Action
*/
private Action createClearFindNextAction()
{
Action action = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
clearFindNext();
}
};
action.putValue(Action.NAME, "Clear find field");
action.putValue(
Action.SHORT_DESCRIPTION,
"Clear the find field");
action.setEnabled(false);
return action;
}
private Action createClearRefineFocusAction()
{
Action action = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
clearRefineFocus();
}
};
action.putValue(Action.NAME, "Clear 'refine focus' field");
action.putValue(
Action.SHORT_DESCRIPTION,
"Clear the refine focus field");
action.setEnabled(false);
return action;
}
/**
* DOCUMENT ME!
*
* @return
*/
private Action createFocusOnAction()
{
final Action action = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
toggleFocusOnState();
}
};
action.putValue(Action.NAME, "Focus");
action.putValue(
Action.SHORT_DESCRIPTION,
"Allows you to Focus on the selected logger by setting a filter that discards all but this Logger");
action.putValue(
Action.SMALL_ICON, new ImageIcon(ChainsawIcons.WINDOW_ICON));
action.setEnabled(false);
return action;
}
/**
* DOCUMENT ME!
*
* @return
*/
private Action createIgnoreAllAction()
{
Action action =
new AbstractAction(
"Ignore loggers below selection")
{
public void actionPerformed(ActionEvent e)
{
//add all top level loggers as hidden loggers
TreePath[] paths = logTree.getSelectionPaths();
String parentPathString = "";
DefaultMutableTreeNode root;
if ((paths == null) || (paths.length == 0))
{
root = (DefaultMutableTreeNode) logTreeModel.getRoot();
} else {
root = (DefaultMutableTreeNode) logTree.getSelectionPath().getLastPathComponent();
TreeNode[] path = root.getPath();
//don't add 'root logger' to path string
for (int i=1;i<path.length;i++) {
if (i > 1) {
parentPathString = parentPathString + ".";
}
parentPathString = parentPathString + path[i].toString();
}
if (!(parentPathString.equals(""))) {
parentPathString = parentPathString + ".";
}
}
Enumeration topLevelLoggersEnumeration = root.children();
Set topLevelLoggersSet = new HashSet();
while (topLevelLoggersEnumeration.hasMoreElements()) {
String thisLogger = topLevelLoggersEnumeration.nextElement().toString();
topLevelLoggersSet.add(parentPathString + thisLogger);
}
if (topLevelLoggersSet.size() > 0) {
ignore(topLevelLoggersSet);
}
logTreeModel.nodeChanged(root);
ignoreLoggerButton.setSelected(false);
focusOnAction.setEnabled(false);
popupMenu.hideCheck.setSelected(false);
fireChangeEvent();
}
};
action.putValue(
Action.SHORT_DESCRIPTION,
"Adds all loggers to your Ignore list (unhide loggers you want to see in the view)");
return action;
}
/**
* DOCUMENT ME!
*
* @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;
}
private void ensureRootExpanded()
{
logger.debug("Ensuring Root node is expanded.");
final DefaultMutableTreeNode root =
(DefaultMutableTreeNode) logTreeModel.getRoot();
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
logTree.expandPath(new TreePath(root));
}
});
}
private void findNextUsingCurrentlySelectedNode()
{
String selectedLogger = getCurrentlySelectedLoggerName();
TreePath[] paths = logTree.getSelectionPaths();
if (paths == null)
{
return;
}
logPanel.setFindText("logger like '^" + selectedLogger + ".*'");
}
private void clearFindNext()
{
logPanel.setFindText("");
}
private void clearRefineFocus()
{
logPanel.setRefineFocusText("");
}
/**
* Expands the currently selected node (if any)
* including all the children.
*
*/
private void expandCurrentlySelectedNode()
{
TreePath[] paths = logTree.getSelectionPaths();
if (paths == null)
{
return;
}
logger.debug("Expanding all children of selected node");
for (int i = 0; i < paths.length; i++)
{
TreePath path = paths[i];
/**
* TODO this is commented out, right now it expands all nodes including the root, so if there is a large tree..... look out.
*/
// /**
// * Handle an expansion of the Root node by only doing the first level.
// * Safe...
// */
// if (path.getPathCount() == 1) {
// logTree.expandPath(path);
//
// return;
// }
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)
{
logger.warn("Should warn user, depth=" + maxDepth);
}
depthEnum = treeNode.depthFirstEnumeration();
while (depthEnum.hasMoreElements())
{
DefaultMutableTreeNode node =
(DefaultMutableTreeNode) depthEnum.nextElement();
if (node.isLeaf() && node.getParent() != null)
{
TreeNode[] nodes =
((DefaultMutableTreeNode) node.getParent()).getPath();
TreePath treePath = new TreePath(nodes);
logger.debug("Expanding path:" + treePath);
logTree.expandPath(treePath);
}
}
}
}
private void fireChangeEvent()
{
ChangeListener[] listeners =
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 void reconfigureMenuText()
{
String logger = getCurrentlySelectedLoggerName();
if ((logger == null) || (logger.length() == 0))
{
focusOnAction.putValue(Action.NAME, "Focus On...");
hideAction.putValue(Action.NAME, "Ignore...");
findAction.putValue(Action.NAME, "Find...");
setRefineFocusAction.putValue(Action.NAME, "Set refine focus field");
updateRefineFocusAction.putValue(Action.NAME, "Add to refine focus field");
updateFindAction.putValue(Action.NAME, "Add to find field");
defineColorRuleForLoggerAction.putValue(Action.NAME, "Define color rule");
}
else
{
focusOnAction.putValue(Action.NAME, "Focus On '" + logger + "'");
hideAction.putValue(Action.NAME, "Ignore '" + logger + "'");
findAction.putValue(Action.NAME, "Find '" + logger + "'");
setRefineFocusAction.putValue(Action.NAME, "Set refine focus field to '" + logger + "'");
updateRefineFocusAction.putValue(Action.NAME, "Add '" + logger + "' to 'refine focus' field");
updateFindAction.putValue(Action.NAME, "Add '" + logger + "' to 'find' field");
defineColorRuleForLoggerAction.putValue(Action.NAME, "Define color rule for '" + logger + "'");
}
// need to ensure the button doens't update itself with the text, looks stupid otherwise
hideSubLoggersAction.putValue(Action.NAME, "Ignore loggers below selection");
focusOnLoggerButton.setText(null);
ignoreLoggerButton.setText(null);
}
/**
* Configures varoius listeners etc for the components within
* this Class.
*/
private void setupListeners()
{
logTree.addMouseMotionListener(new MouseKeyIconListener());
/**
* Enable the actions depending on state of the tree selection
*/
logTree.addTreeSelectionListener(new TreeSelectionListener()
{
public void valueChanged(TreeSelectionEvent e)
{
TreePath path = e.getNewLeadSelectionPath();
TreeNode node = null;
if (path != null)
{
node = (TreeNode) path.getLastPathComponent();
}
boolean focusOnSelected = isFocusOnSelected();
// editLoggerAction.setEnabled(path != null);
currentlySelectedLoggerName = getCurrentlySelectedLoggerName();
focusOnAction.setEnabled(
(path != null) && (node != null) && (node.getParent() != null)
&& !hiddenSet.contains(currentlySelectedLoggerName));
hideAction.setEnabled(
(path != null) && (node != null) && (node.getParent() != null));
if (!focusOnAction.isEnabled())
{
setFocusOnSelected(false);
}
else
{
}
expandAction.setEnabled(path != null);
findAction.setEnabled(path != null);
clearFindNextAction.setEnabled(true);
defineColorRuleForLoggerAction.setEnabled(path != null);
setRefineFocusAction.setEnabled(path != null);
updateRefineFocusAction.setEnabled(path != null);
updateFindAction.setEnabled(path != null);
clearRefineFocusAction.setEnabled(true);
if (currentlySelectedLoggerName != null)
{
boolean isHidden = hiddenSet.contains(currentlySelectedLoggerName);
popupMenu.hideCheck.setSelected(isHidden);
ignoreLoggerButton.setSelected(isHidden);
}
collapseAction.setEnabled(path != null);
reconfigureMenuText();
if (isFocusOnSelected()) {
fireChangeEvent();
}
//fire change event if we toggled focus off
if (focusOnSelected && !isFocusOnSelected()) {
fireChangeEvent();
}
//trigger a table repaint
logPanel.repaint();
}
});
logTree.addMouseListener(popupListener);
/**
* This listener ensures the Tool bar toggle button and popup menu check box
* 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());
if (logTree.getSelectionPath() != null)
{
logTreeModel.nodeChanged(
(TreeNode) logTree.getSelectionPath().getLastPathComponent());
}
}
});
hideAction.addPropertyChangeListener(new PropertyChangeListener()
{
public void propertyChange(PropertyChangeEvent evt)
{
if (logTree.getSelectionPath() != null)
{
logTreeModel.nodeChanged(
(TreeNode) logTree.getSelectionPath().getLastPathComponent());
}
}
});
// /**
// * Now add a MouseListener that fires the expansion
// * action if CTRL + DBL CLICK is done.
// */
// logTree.addMouseListener(
// new MouseAdapter() {
// public void mouseClicked(MouseEvent e) {
// if (
// (e.getClickCount() > 1)
// && ((e.getModifiers() & InputEvent.CTRL_MASK) > 0)
// && ((e.getModifiers() & InputEvent.BUTTON1_MASK) > 0)) {
// expandCurrentlySelectedNode();
// e.consume();
// } else if (e.getClickCount() > 1) {
// super.mouseClicked(e);
// logger.debug("Ignoring dbl click event " + e);
// }
// }
// });
logTree.addMouseListener(new MouseFocusOnListener());
/**
* We listen for when the FocusOn action changes, and then translate
* that to a RuleChange
*/
addChangeListener(new ChangeListener()
{
public void stateChanged(ChangeEvent evt)
{
visibilityRuleDelegate.firePropertyChange("rule", null, null);
updateDisplay();
}
});
visibilityRuleDelegate.addPropertyChangeListener(new PropertyChangeListener()
{
public void propertyChange(PropertyChangeEvent event)
{
if (event.getPropertyName().equals("hiddenSet")) {
updateDisplay();
}
}
});
}
private void updateDisplay() {
updateHiddenSetModels();
updateIgnoreSummary();
updateIgnoreExpressionSummary();
updateAlwaysDisplayExpressionSummary();
}
private void updateHiddenSetModels() {
DefaultListModel model = (DefaultListModel) ignoreList.getModel();
model.clear();
List sortedIgnoreList = new ArrayList(hiddenSet);
Collections.sort(sortedIgnoreList);
for (Iterator iter = sortedIgnoreList.iterator(); iter.hasNext();)
{
String string = (String) iter.next();
model.addElement(string);
}
// ignoreList.setModel(model);
}
private void updateIgnoreSummary() {
ignoreSummary.setText(ignoreList.getModel().getSize() + " hidden loggers");
}
private void updateIgnoreExpressionSummary() {
ignoreExpressionSummary.setText(ignoreExpressionRule != null?"Ignore (set)":"Ignore (unset)");
}
private void updateAlwaysDisplayExpressionSummary() {
alwaysDisplayExpressionSummary.setText(alwaysDisplayExpressionRule != null?"Always displayed (set)":"Always displayed (unset)");
}
private void toggleFocusOnState()
{
setFocusOnSelected(!isFocusOnSelected());
fireChangeEvent();
}
public Collection getHiddenSet() {
return Collections.unmodifiableSet(hiddenSet);
}
public String getHiddenExpression() {
String text = ignoreExpressionEntryField.getText();
if (text == null || text.trim().equals("")) {
return null;
}
return text.trim();
}
public void setHiddenExpression(String hiddenExpression) {
ignoreExpressionEntryField.setText(hiddenExpression);
updateIgnoreExpression(hiddenExpression);
}
public String getAlwaysDisplayExpression() {
String text = alwaysDisplayExpressionEntryField.getText();
if (text == null || text.trim().equals("")) {
return null;
}
return text.trim();
}
public void setAlwaysDisplayExpression(String alwaysDisplayExpression) {
alwaysDisplayExpressionEntryField.setText(alwaysDisplayExpression);
updateAlwaysDisplayExpression(alwaysDisplayExpression);
}
public void loggerNameAdded(String loggerName)
{
//no-op
}
public void reset()
{
expandRootLatch = false;
//keep track if focuson was active when we were reset
final String logger = currentlySelectedLoggerName;
final boolean focusOnSelected = isFocusOnSelected();
if (logger == null || !focusOnSelected) {
return;
}
//loggernameAdded runs on EDT
logTreeModel.loggerNameAdded(logger);
EventQueue.invokeLater(new Runnable() {
public void run() {
setFocusOn(logger);
}
});
}
//~ Inner Classes ===========================================================
/**
* DOCUMENT ME!
*
* @author $author$
* @version $Revision$, $Date$
*
* @author Paul Smith &lt;psmith@apache.org&gt;
*
*/
private class LoggerNameTreeCellRenderer extends DefaultTreeCellRenderer
{
//~ Constructors ==========================================================
// private JPanel panel = new JPanel();
private LoggerNameTreeCellRenderer()
{
super();
// panel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
// panel.add(this);
setLeafIcon(null);
setOpaque(false);
}
//~ Methods ===============================================================
/* (non-Javadoc)
* @see javax.swing.tree.TreeCellRenderer#getTreeCellRendererComponent(javax.swing.JTree, java.lang.Object, boolean, boolean, boolean, int, boolean)
*/
/**
* DOCUMENT ME!
*
* @param tree DOCUMENT ME!
* @param value DOCUMENT ME!
* @param sel DOCUMENT ME!
* @param expanded DOCUMENT ME!
* @param leaf DOCUMENT ME!
* @param row DOCUMENT ME!
* @param focus DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public Component getTreeCellRendererComponent(
JTree tree, Object value, boolean sel, boolean expanded, boolean leaf,
int row, boolean focus)
{
JLabel component =
(JLabel) super.getTreeCellRendererComponent(
tree, value, sel, expanded, leaf, row, focus);
Font originalFont = new Font(component.getFont().getName(), component.getFont().getStyle(), component.getFont().getSize());
int style = Font.PLAIN;
if (sel && focusOnLoggerButton.isSelected())
{
style = style | Font.BOLD;
}
String logger =
getLoggerName(
new TreePath(((DefaultMutableTreeNode) value).getPath()));
if (hiddenSet.contains(logger))
{
// component.setEnabled(false);
// component.setIcon(leaf?null:getDefaultOpenIcon());
style = style | Font.ITALIC;
// logger.debug("TreeRenderer: '" + logger + "' is in hiddenSet, italicizing");
}
else
{
// logger.debug("TreeRenderer: '" + logger + "' is NOT in hiddenSet, leaving plain");
// component.setEnabled(true);
}
if (originalFont != null)
{
Font font2 = originalFont.deriveFont(style);
if (font2 != null)
{
component.setFont(font2);
}
}
return component;
}
}
private class LoggerTreePopupMenu extends JPopupMenu
{
//~ Instance fields =======================================================
JCheckBoxMenuItem focusOnCheck = new JCheckBoxMenuItem();
JCheckBoxMenuItem hideCheck = new JCheckBoxMenuItem();
//~ Constructors ==========================================================
private LoggerTreePopupMenu()
{
initMenu();
}
//~ Methods ===============================================================
/* (non-Javadoc)
* @see javax.swing.JPopupMenu#show(java.awt.Component, int, int)
*/
/**
* DOCUMENT ME!
*
* @param invoker DOCUMENT ME!
* @param x DOCUMENT ME!
* @param y DOCUMENT ME!
*/
public void show(Component invoker, int x, int y)
{
DefaultMutableTreeNode node =
(DefaultMutableTreeNode) logTree.getLastSelectedPathComponent();
if (node == null)
{
return;
}
super.show(invoker, x, y);
}
/**
* DOCUMENT ME!
*/
private void initMenu()
{
focusOnCheck.setAction(focusOnAction);
hideCheck.setAction(hideAction);
add(expandAction);
add(collapseAction);
addSeparator();
add(focusOnCheck);
add(hideCheck);
addSeparator();
add(setRefineFocusAction);
add(updateRefineFocusAction);
add(clearRefineFocusAction);
addSeparator();
add(findAction);
add(updateFindAction);
add(clearFindNextAction);
addSeparator();
add(defineColorRuleForLoggerAction);
addSeparator();
add(hideSubLoggersAction);
add(clearIgnoreListAction);
}
}
private final class MouseFocusOnListener extends MouseAdapter
{
//~ Methods ===============================================================
/* (non-Javadoc)
* @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
*/
/**
* DOCUMENT ME!
*
* @param e DOCUMENT ME!
*/
public void mouseClicked(MouseEvent e)
{
if (
(e.getClickCount() > 1)
&& ((e.getModifiers() & InputEvent.CTRL_MASK) > 0)
&& ((e.getModifiers() & InputEvent.SHIFT_MASK) > 0))
{
ignoreLoggerAtPoint(e.getPoint());
e.consume();
fireChangeEvent();
}
else if (
(e.getClickCount() > 1)
&& ((e.getModifiers() & InputEvent.CTRL_MASK) > 0))
{
focusAnLoggerAtPoint(e.getPoint());
e.consume();
fireChangeEvent();
}
}
/**
* DOCUMENT ME!
*
* @param point
*/
private void focusAnLoggerAtPoint(Point point)
{
String logger = getLoggerAtPoint(point);
if (logger != null)
{
toggleFocusOnState();
}
}
/**
* DOCUMENT ME!
*
* @param point
* @return
*/
private String getLoggerAtPoint(Point point)
{
TreePath path = logTree.getPathForLocation(point.x, point.y);
if (path != null)
{
return getLoggerName(path);
}
return null;
}
/**
* DOCUMENT ME!
*
* @param point
*/
private void ignoreLoggerAtPoint(Point point)
{
String logger = getLoggerAtPoint(point);
if (logger != null)
{
toggleHiddenLogger(logger);
fireChangeEvent();
}
}
}
private final class MouseKeyIconListener extends MouseMotionAdapter
implements MouseMotionListener
{
//~ Instance fields =======================================================
Cursor focusOnCursor =
Toolkit.getDefaultToolkit().createCustomCursor(
ChainsawIcons.FOCUS_ON_ICON.getImage(), new Point(10, 10), "");
Cursor ignoreCursor =
Toolkit.getDefaultToolkit().createCustomCursor(
ChainsawIcons.IGNORE_ICON.getImage(), new Point(10, 10), "");
//~ Methods ===============================================================
/* (non-Javadoc)
* @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
*/
/**
* DOCUMENT ME!
*
* @param e DOCUMENT ME!
*/
public void mouseMoved(MouseEvent e)
{
// logger.debug(e.toString());
if (
((e.getModifiers() & InputEvent.CTRL_MASK) > 0)
&& ((e.getModifiers() & InputEvent.SHIFT_MASK) > 0))
{
logTree.setCursor(ignoreCursor);
}
else if ((e.getModifiers() & InputEvent.CTRL_MASK) > 0)
{
logTree.setCursor(focusOnCursor);
}
else
{
logTree.setCursor(Cursor.getDefaultCursor());
}
}
}
class VisibilityRuleDelegate extends AbstractRule {
public boolean evaluate(LoggingEvent e, Map matches)
{
String currentlySelectedLoggerName = getCurrentlySelectedLoggerName();
boolean hiddenLogger = e.getLoggerName() != null && isHiddenLogger(e.getLoggerName());
boolean hiddenExpression = (ignoreExpressionRule != null && ignoreExpressionRule.evaluate(e, null));
boolean alwaysDisplayExpression = (alwaysDisplayExpressionRule != null && alwaysDisplayExpressionRule.evaluate(e, null));
boolean hidden = (!alwaysDisplayExpression) && (hiddenLogger || hiddenExpression);
if (currentlySelectedLoggerName == null) {
//if there is no selected logger, pass if not hidden
return !hidden;
}
boolean result = (e.getLoggerName() != null) && !hidden;
if (result && isFocusOnSelected())
{
result = (e.getLoggerName() != null && (e.getLoggerName().startsWith(currentlySelectedLoggerName+".") || e.getLoggerName().endsWith(currentlySelectedLoggerName)));
}
return result;
}
public void firePropertyChange(String propertyName, Object oldVal, Object newVal)
{
super.firePropertyChange(propertyName, oldVal, newVal);
}
}
}