1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.log4j.chainsaw;
20
21 import java.awt.BorderLayout;
22 import java.awt.Color;
23 import java.awt.Component;
24 import java.awt.Cursor;
25 import java.awt.Dimension;
26 import java.awt.EventQueue;
27 import java.awt.Font;
28 import java.awt.Point;
29 import java.awt.Toolkit;
30 import java.awt.event.ActionEvent;
31 import java.awt.event.InputEvent;
32 import java.awt.event.MouseAdapter;
33 import java.awt.event.MouseEvent;
34 import java.awt.event.MouseMotionAdapter;
35 import java.awt.event.MouseMotionListener;
36 import java.beans.PropertyChangeEvent;
37 import java.beans.PropertyChangeListener;
38 import java.util.ArrayList;
39 import java.util.Collection;
40 import java.util.Collections;
41 import java.util.Enumeration;
42 import java.util.HashSet;
43 import java.util.Iterator;
44 import java.util.List;
45 import java.util.Map;
46 import java.util.Set;
47
48 import javax.swing.AbstractAction;
49 import javax.swing.Action;
50 import javax.swing.BorderFactory;
51 import javax.swing.Box;
52 import javax.swing.BoxLayout;
53 import javax.swing.DefaultListModel;
54 import javax.swing.ImageIcon;
55 import javax.swing.JButton;
56 import javax.swing.JCheckBoxMenuItem;
57 import javax.swing.JColorChooser;
58 import javax.swing.JDialog;
59 import javax.swing.JEditorPane;
60 import javax.swing.JLabel;
61 import javax.swing.JList;
62 import javax.swing.JPanel;
63 import javax.swing.JPopupMenu;
64 import javax.swing.JScrollPane;
65 import javax.swing.JToolBar;
66 import javax.swing.JTree;
67 import javax.swing.SwingUtilities;
68 import javax.swing.ToolTipManager;
69 import javax.swing.UIManager;
70 import javax.swing.event.ChangeEvent;
71 import javax.swing.event.ChangeListener;
72 import javax.swing.event.EventListenerList;
73 import javax.swing.event.TreeModelEvent;
74 import javax.swing.event.TreeModelListener;
75 import javax.swing.event.TreeSelectionEvent;
76 import javax.swing.event.TreeSelectionListener;
77 import javax.swing.tree.DefaultMutableTreeNode;
78 import javax.swing.tree.DefaultTreeCellRenderer;
79 import javax.swing.tree.DefaultTreeSelectionModel;
80 import javax.swing.tree.TreeNode;
81 import javax.swing.tree.TreePath;
82 import javax.swing.tree.TreeSelectionModel;
83
84 import org.apache.log4j.LogManager;
85 import org.apache.log4j.Logger;
86 import org.apache.log4j.chainsaw.color.RuleColorizer;
87 import org.apache.log4j.chainsaw.filter.FilterModel;
88 import org.apache.log4j.chainsaw.icons.ChainsawIcons;
89 import org.apache.log4j.chainsaw.icons.LineIconFactory;
90 import org.apache.log4j.rule.AbstractRule;
91 import org.apache.log4j.rule.ColorRule;
92 import org.apache.log4j.rule.ExpressionRule;
93 import org.apache.log4j.rule.Rule;
94 import org.apache.log4j.spi.LoggingEvent;
95
96
97
98
99
100
101
102
103
104 final class LoggerNameTreePanel extends JPanel implements LoggerNameListener
105 {
106
107
108 private static final int WARN_DEPTH = 4;
109
110
111
112 private LoggerNameTreeCellRenderer cellRenderer =
113 new LoggerNameTreeCellRenderer();
114 private final Action clearIgnoreListAction;
115 private final Action closeAction;
116 private final JButton closeButton = new SmallButton();
117 private final Action collapseAction;
118 private final JButton collapseButton = new SmallButton();
119 private final Action editLoggerAction;
120 private final JButton editLoggerButton = new SmallButton();
121 private final Action expandAction;
122 private final Action findAction;
123 private final Action clearFindNextAction;
124 private final Action defineColorRuleForLoggerAction;
125 private final Action setRefineFocusAction;
126 private final Action updateRefineFocusAction;
127 private final Action updateFindAction;
128 private final JButton expandButton = new SmallButton();
129 private final Action focusOnAction;
130 private final Action clearRefineFocusAction;
131 private final SmallToggleButton focusOnLoggerButton =
132 new SmallToggleButton();
133 private final Set hiddenSet = new HashSet();
134 private final Action hideAction;
135 private final Action hideSubLoggersAction;
136 private final LogPanelPreferenceModel preferenceModel;
137
138 private final JList ignoreList = new JList();
139 private final JEditorPane ignoreExpressionEntryField = new JEditorPane();
140 private final JEditorPane alwaysDisplayExpressionEntryField = new JEditorPane();
141 private final JScrollPane ignoreListScroll = new JScrollPane(ignoreList);
142 private final JDialog ignoreDialog = new JDialog();
143 private final JDialog ignoreExpressionDialog = new JDialog();
144 private final JDialog alwaysDisplayExpressionDialog = new JDialog();
145 private final JLabel ignoreSummary = new JLabel("0 hidden loggers");
146 private final JLabel ignoreExpressionSummary = new JLabel("Ignore expression");
147 private final JLabel alwaysDisplayExpressionSummary = new JLabel("Always displayed expression");
148 private final SmallToggleButton ignoreLoggerButton = new SmallToggleButton();
149 private final EventListenerList listenerList = new EventListenerList();
150 private final JTree logTree;
151 private final Logger logger = LogManager.getLogger(LoggerNameTreePanel.class);
152
153
154
155 private final LogPanelLoggerTreeModel logTreeModel;
156 private final PopupListener popupListener;
157 private final LoggerTreePopupMenu popupMenu;
158 private final VisibilityRuleDelegate visibilityRuleDelegate;
159 private Rule colorRuleDelegate;
160 private final JScrollPane scrollTree;
161 private final JToolBar toolbar = new JToolBar();
162 private final LogPanel logPanel;
163 private final RuleColorizer colorizer;
164 private Rule ignoreExpressionRule;
165 private Rule alwaysDisplayExpressionRule;
166 private boolean expandRootLatch = false;
167 private String currentlySelectedLoggerName;
168
169
170
171
172
173
174
175
176 LoggerNameTreePanel(LogPanelLoggerTreeModel logTreeModel, LogPanelPreferenceModel preferenceModel, LogPanel logPanel, RuleColorizer colorizer, FilterModel filterModel)
177 {
178 super();
179 this.logTreeModel = logTreeModel;
180 this.preferenceModel = preferenceModel;
181 this.logPanel = logPanel;
182 this.colorizer = colorizer;
183
184 setLayout(new BorderLayout());
185 ignoreExpressionEntryField.setPreferredSize(new Dimension(300, 150));
186 alwaysDisplayExpressionEntryField.setPreferredSize(new Dimension(300, 150));
187 alwaysDisplayExpressionSummary.setMinimumSize(new Dimension(10, alwaysDisplayExpressionSummary.getHeight()));
188 ignoreExpressionSummary.setMinimumSize(new Dimension(10, ignoreExpressionSummary.getHeight()));
189 ignoreSummary.setMinimumSize(new Dimension(10, ignoreSummary.getHeight()));
190
191 JTextComponentFormatter.applySystemFontAndSize(ignoreExpressionEntryField);
192 JTextComponentFormatter.applySystemFontAndSize(alwaysDisplayExpressionEntryField);
193
194 visibilityRuleDelegate = new VisibilityRuleDelegate();
195 colorRuleDelegate =
196 new AbstractRule()
197 {
198 public boolean evaluate(LoggingEvent e, Map matches)
199 {
200 boolean hiddenLogger = e.getLoggerName() != null && isHiddenLogger(e.getLoggerName());
201 boolean hiddenExpression = (ignoreExpressionRule != null && ignoreExpressionRule.evaluate(e, null));
202 boolean alwaysDisplayExpression = (alwaysDisplayExpressionRule != null && alwaysDisplayExpressionRule.evaluate(e, null));
203 boolean hidden = (!alwaysDisplayExpression) && (hiddenLogger || hiddenExpression);
204 String currentlySelectedLoggerName = getCurrentlySelectedLoggerName();
205
206 if (!isFocusOnSelected() && !hidden && currentlySelectedLoggerName != null && !"".equals(currentlySelectedLoggerName))
207 {
208 return (e.getLoggerName().startsWith(currentlySelectedLoggerName+".") || e.getLoggerName().endsWith(currentlySelectedLoggerName)) ;
209 }
210 return false;
211 }
212 };
213
214 logTree =
215 new JTree(logTreeModel)
216 {
217 public String getToolTipText(MouseEvent ev)
218 {
219 if (ev == null)
220 {
221 return null;
222 }
223
224 TreePath path = logTree.getPathForLocation(ev.getX(), ev.getY());
225
226 String loggerName = getLoggerName(path);
227
228 if (hiddenSet.contains(loggerName))
229 {
230 loggerName += " (you are ignoring this logger)";
231 }
232
233 return loggerName;
234 }
235 };
236
237 ToolTipManager.sharedInstance().registerComponent(logTree);
238 logTree.setCellRenderer(cellRenderer);
239
240
241 logTreeModel.addTreeModelListener(new TreeModelListener()
242 {
243 public void treeNodesChanged(TreeModelEvent e)
244 {
245 }
246
247 public void treeNodesInserted(TreeModelEvent e)
248 {
249 if (!expandRootLatch)
250 {
251 ensureRootExpanded();
252 expandRootLatch = true;
253 }
254 }
255
256 public void treeNodesRemoved(TreeModelEvent e)
257 {
258 }
259
260 public void treeStructureChanged(TreeModelEvent e)
261 {
262 }
263 });
264
265 logTree.setEditable(false);
266
267
268 TreeSelectionModel selectionModel = new DefaultTreeSelectionModel();
269 selectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
270 logTree.setSelectionModel(selectionModel);
271
272 logTree.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
273 scrollTree = new JScrollPane(logTree);
274 toolbar.setLayout(new BoxLayout(toolbar, BoxLayout.X_AXIS));
275
276 expandAction = createExpandAction();
277 findAction = createFindNextAction();
278 clearFindNextAction = createClearFindNextAction();
279 defineColorRuleForLoggerAction = createDefineColorRuleForLoggerAction();
280 clearRefineFocusAction = createClearRefineFocusAction();
281 setRefineFocusAction = createSetRefineFocusAction();
282 updateRefineFocusAction = createUpdateRefineFocusAction();
283 updateFindAction = createUpdateFindAction();
284 editLoggerAction = createEditLoggerAction();
285 closeAction = createCloseAction();
286 collapseAction = createCollapseAction();
287 focusOnAction = createFocusOnAction();
288 hideAction = createIgnoreAction();
289 hideSubLoggersAction = createIgnoreAllAction();
290 clearIgnoreListAction = createClearIgnoreListAction();
291
292 popupMenu = new LoggerTreePopupMenu();
293 popupListener = new PopupListener(popupMenu);
294
295 setupListeners();
296 configureToolbarPanel();
297
298 add(toolbar, BorderLayout.NORTH);
299 add(scrollTree, BorderLayout.CENTER);
300
301 ignoreDialog.setTitle("Hidden/Ignored Loggers");
302 ignoreDialog.setModal(true);
303
304 ignoreExpressionDialog.setTitle("Hidden/Ignored Expression");
305 ignoreExpressionDialog.setModal(true);
306
307 alwaysDisplayExpressionDialog.setTitle("Always displayed Expression");
308 alwaysDisplayExpressionDialog.setModal(true);
309
310 JPanel ignorePanel = new JPanel();
311 ignorePanel.setLayout(new BoxLayout(ignorePanel, BoxLayout.Y_AXIS));
312 JPanel ignoreSummaryPanel = new JPanel();
313 ignoreSummaryPanel.setLayout(new BoxLayout(ignoreSummaryPanel, BoxLayout.X_AXIS));
314 ignoreSummaryPanel.add(ignoreSummary);
315
316 Action showIgnoreDialogAction = new AbstractAction("...") {
317 public void actionPerformed(ActionEvent e) {
318 LogPanel.centerAndSetVisible(ignoreDialog);
319 }
320 };
321
322 Action showIgnoreExpressionDialogAction = new AbstractAction("...") {
323 public void actionPerformed(ActionEvent e) {
324 LogPanel.centerAndSetVisible(ignoreExpressionDialog);
325 }
326 };
327
328
329 Action showAlwaysDisplayExpressionDialogAction = new AbstractAction("...") {
330 public void actionPerformed(ActionEvent e) {
331 LogPanel.centerAndSetVisible(alwaysDisplayExpressionDialog);
332 }
333 };
334
335 showIgnoreDialogAction.putValue(Action.SHORT_DESCRIPTION, "Click to view and manage your hidden/ignored loggers");
336 JButton btnShowIgnoreDialog = new SmallButton(showIgnoreDialogAction);
337
338 ignoreSummaryPanel.add(btnShowIgnoreDialog);
339 ignorePanel.add(ignoreSummaryPanel);
340
341 JPanel ignoreExpressionPanel = new JPanel();
342 ignoreExpressionPanel.setLayout(new BoxLayout(ignoreExpressionPanel, BoxLayout.X_AXIS));
343 ignoreExpressionPanel.add(ignoreExpressionSummary);
344 showIgnoreExpressionDialogAction.putValue(Action.SHORT_DESCRIPTION, "Click to view and manage your hidden/ignored expression");
345 JButton btnShowIgnoreExpressionDialog = new SmallButton(showIgnoreExpressionDialogAction);
346 ignoreExpressionPanel.add(btnShowIgnoreExpressionDialog);
347
348 ignorePanel.add(ignoreExpressionPanel);
349
350 JPanel alwaysDisplayExpressionPanel = new JPanel();
351 alwaysDisplayExpressionPanel.setLayout(new BoxLayout(alwaysDisplayExpressionPanel, BoxLayout.X_AXIS));
352 alwaysDisplayExpressionPanel.add(alwaysDisplayExpressionSummary);
353 showAlwaysDisplayExpressionDialogAction.putValue(Action.SHORT_DESCRIPTION, "Click to view and manage your always-displayed expression");
354 JButton btnShowAlwaysDisplayExpressionDialog = new SmallButton(showAlwaysDisplayExpressionDialogAction);
355 alwaysDisplayExpressionPanel.add(btnShowAlwaysDisplayExpressionDialog);
356
357 ignorePanel.add(alwaysDisplayExpressionPanel);
358
359 add(ignorePanel, BorderLayout.SOUTH);
360
361 ignoreList.setModel(new DefaultListModel());
362 ignoreList.addMouseListener(new MouseAdapter()
363 {
364 public void mouseClicked(MouseEvent e)
365 {
366 if (
367 (e.getClickCount() > 1)
368 && ((e.getModifiers() & InputEvent.BUTTON1_MASK) > 0))
369 {
370 int index = ignoreList.locationToIndex(e.getPoint());
371
372 if (index >= 0)
373 {
374 String string =
375 ignoreList.getModel().getElementAt(index).toString();
376 toggleHiddenLogger(string);
377 fireChangeEvent();
378
379
380
381
382 LoggerNameTreePanel.this.logTreeModel.nodeStructureChanged(
383 (TreeNode) LoggerNameTreePanel.this.logTreeModel.getRoot());
384 }
385 }
386 }
387 });
388
389 JPanel ignoreListPanel = new JPanel(new BorderLayout());
390 ignoreListScroll.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),"Double click an entry to unhide it"));
391 ignoreListPanel.add(ignoreListScroll, BorderLayout.CENTER);
392
393 JPanel ignoreExpressionDialogPanel = new JPanel(new BorderLayout());
394 ignoreExpressionEntryField.addKeyListener(new ExpressionRuleContext(filterModel, ignoreExpressionEntryField));
395
396 ignoreExpressionDialogPanel.add(new JScrollPane(ignoreExpressionEntryField), BorderLayout.CENTER);
397 JButton ignoreExpressionCloseButton = new JButton(new AbstractAction(" Close ") {
398 public void actionPerformed(ActionEvent e)
399 {
400 String ignoreText = ignoreExpressionEntryField.getText();
401
402 if (updateIgnoreExpression(ignoreText)) {
403 ignoreExpressionDialog.setVisible(false);
404 }
405 }});
406
407
408 JPanel alwaysDisplayExpressionDialogPanel = new JPanel(new BorderLayout());
409 alwaysDisplayExpressionEntryField.addKeyListener(new ExpressionRuleContext(filterModel, alwaysDisplayExpressionEntryField));
410
411 alwaysDisplayExpressionDialogPanel.add(new JScrollPane(alwaysDisplayExpressionEntryField), BorderLayout.CENTER);
412 JButton alwaysDisplayExpressionCloseButton = new JButton(new AbstractAction(" Close ") {
413 public void actionPerformed(ActionEvent e)
414 {
415 String alwaysDisplayText = alwaysDisplayExpressionEntryField.getText();
416
417 if (updateAlwaysDisplayExpression(alwaysDisplayText)) {
418 alwaysDisplayExpressionDialog.setVisible(false);
419 }
420 }});
421
422 JPanel closeAlwaysDisplayExpressionPanel = new JPanel();
423 closeAlwaysDisplayExpressionPanel.add(alwaysDisplayExpressionCloseButton);
424 alwaysDisplayExpressionDialogPanel.add(closeAlwaysDisplayExpressionPanel, BorderLayout.SOUTH);
425
426 JPanel closeIgnoreExpressionPanel = new JPanel();
427 closeIgnoreExpressionPanel.add(ignoreExpressionCloseButton);
428 ignoreExpressionDialogPanel.add(closeIgnoreExpressionPanel, BorderLayout.SOUTH);
429
430 Box ignoreListButtonPanel = Box.createHorizontalBox();
431
432 JButton unhideAll = new JButton(new AbstractAction(" Unhide All ") {
433
434 public void actionPerformed(final ActionEvent e)
435 {
436 SwingUtilities.invokeLater(new Runnable() {
437
438 public void run()
439 {
440 clearIgnoreListAction.actionPerformed(e);
441 }});
442
443 }});
444 ignoreListButtonPanel.add(unhideAll);
445
446 ignoreListButtonPanel.add(Box.createHorizontalGlue());
447 JButton ignoreCloseButton = new JButton(new AbstractAction(" Close ") {
448
449 public void actionPerformed(ActionEvent e)
450 {
451 ignoreDialog.setVisible(false);
452
453 }});
454 ignoreListButtonPanel.add(ignoreCloseButton);
455
456
457 ignoreListPanel.add(ignoreListButtonPanel, BorderLayout.SOUTH);
458
459
460 ignoreDialog.getContentPane().add(ignoreListPanel);
461 ignoreDialog.pack();
462
463 ignoreExpressionDialog.getContentPane().add(ignoreExpressionDialogPanel);
464 ignoreExpressionDialog.pack();
465
466 alwaysDisplayExpressionDialog.getContentPane().add(alwaysDisplayExpressionDialogPanel);
467 alwaysDisplayExpressionDialog.pack();
468 }
469
470 private boolean updateIgnoreExpression(String ignoreText)
471 {
472 try {
473 if (ignoreText != null && !ignoreText.trim().equals("")) {
474 ignoreExpressionRule = ExpressionRule.getRule(ignoreText);
475 } else {
476 ignoreExpressionRule = null;
477 }
478 visibilityRuleDelegate.firePropertyChange("hiddenSet", null, null);
479
480 updateDisplay();
481 ignoreExpressionEntryField.setBackground(UIManager.getColor("TextField.background"));
482 return true;
483 } catch (IllegalArgumentException iae) {
484 ignoreExpressionEntryField.setToolTipText(iae.getMessage());
485 ignoreExpressionEntryField.setBackground(ChainsawConstants.INVALID_EXPRESSION_BACKGROUND);
486 return false;
487 }
488 }
489
490 private boolean updateAlwaysDisplayExpression(String alwaysDisplayText)
491 {
492 try {
493 if (alwaysDisplayText != null && !alwaysDisplayText.trim().equals("")) {
494 alwaysDisplayExpressionRule = ExpressionRule.getRule(alwaysDisplayText);
495 } else {
496 alwaysDisplayExpressionRule = null;
497 }
498 visibilityRuleDelegate.firePropertyChange("alwaysDisplayedSet", null, null);
499
500 updateDisplay();
501 alwaysDisplayExpressionEntryField.setBackground(UIManager.getColor("TextField.background"));
502 return true;
503 } catch (IllegalArgumentException iae) {
504 alwaysDisplayExpressionEntryField.setToolTipText(iae.getMessage());
505 alwaysDisplayExpressionEntryField.setBackground(ChainsawConstants.INVALID_EXPRESSION_BACKGROUND);
506 return false;
507 }
508 }
509
510
511
512
513
514
515
516
517
518 public void addChangeListener(ChangeListener l)
519 {
520 listenerList.add(ChangeListener.class, l);
521 }
522
523 public Rule getLoggerColorRule() {
524 return colorRuleDelegate;
525 }
526
527 public Rule getLoggerVisibilityRule() {
528 return visibilityRuleDelegate;
529 }
530
531
532
533
534
535
536 public void removeChangeListener(ChangeListener l)
537 {
538 listenerList.remove(ChangeListener.class, l);
539 }
540
541
542
543
544
545 public void setFocusOn(String newLogger)
546 {
547 DefaultMutableTreeNode node = logTreeModel.lookupLogger(newLogger);
548
549 if (node != null)
550 {
551 TreeNode[] nodes = node.getPath();
552 TreePath treePath = new TreePath(nodes);
553 logTree.setSelectionPath(treePath);
554
555 if (!focusOnLoggerButton.isSelected())
556 {
557 focusOnLoggerButton.doClick();
558 }
559 }
560 else
561 {
562 logger.error("failed to lookup logger " + newLogger);
563 }
564 }
565
566 private boolean isHiddenLogger(String loggerName) {
567 for (Iterator iter = hiddenSet.iterator();iter.hasNext();) {
568 String hiddenLoggerEntry = iter.next().toString();
569 if (loggerName.startsWith(hiddenLoggerEntry + ".") || loggerName.endsWith(hiddenLoggerEntry)) {
570 return true;
571 }
572 }
573 return false;
574 }
575
576
577
578
579
580
581
582
583 protected void toggleHiddenLogger(String logger)
584 {
585 if (!hiddenSet.contains(logger))
586 {
587 hiddenSet.add(logger);
588 }
589 else
590 {
591 hiddenSet.remove(logger);
592 }
593
594 visibilityRuleDelegate.firePropertyChange("hiddenSet", (Object) null, (Object) null);
595 }
596
597
598
599
600
601
602
603
604
605
606 String getCurrentlySelectedLoggerName()
607 {
608 TreePath[] paths = logTree.getSelectionPaths();
609
610 if ((paths == null) || (paths.length == 0))
611 {
612 return null;
613 }
614
615 TreePath firstPath = paths[0];
616
617 return getLoggerName(firstPath);
618 }
619
620
621
622
623
624
625 String getLoggerName(TreePath path)
626 {
627 if (path != null)
628 {
629 Object[] objects = path.getPath();
630 StringBuffer buf = new StringBuffer();
631
632 for (int i = 1; i < objects.length; i++)
633 {
634 buf.append(objects[i].toString());
635
636 if (i < (objects.length - 1))
637 {
638 buf.append(".");
639 }
640 }
641
642 return buf.toString();
643 }
644
645 return null;
646 }
647
648
649
650
651
652
653
654 void ignore(Collection fqnLoggersToIgnore)
655 {
656 hiddenSet.addAll(fqnLoggersToIgnore);
657 visibilityRuleDelegate.firePropertyChange("hiddenSet", null, null);
658 fireChangeEvent();
659 }
660
661
662
663
664
665 boolean isFocusOnSelected()
666 {
667 return focusOnAction.getValue("checked") != null;
668 }
669
670 void setFocusOnSelected(boolean selected)
671 {
672 if (selected)
673 {
674 focusOnAction.putValue("checked", Boolean.TRUE);
675 }
676 else
677 {
678 focusOnAction.putValue("checked", null);
679 }
680 }
681
682
683
684
685
686
687 private void collapseCurrentlySelectedNode()
688 {
689 TreePath[] paths = logTree.getSelectionPaths();
690
691 if (paths == null)
692 {
693 return;
694 }
695
696 logger.debug("Collapsing all children of selected node");
697
698 for (int i = 0; i < paths.length; i++)
699 {
700 TreePath path = paths[i];
701 DefaultMutableTreeNode node =
702 (DefaultMutableTreeNode) path.getLastPathComponent();
703 Enumeration enumeration = node.depthFirstEnumeration();
704
705 while (enumeration.hasMoreElements())
706 {
707 DefaultMutableTreeNode child =
708 (DefaultMutableTreeNode) enumeration.nextElement();
709
710 if ((child.getParent() != null) && (child != node))
711 {
712 TreeNode[] nodes =
713 ((DefaultMutableTreeNode) child.getParent()).getPath();
714
715 TreePath treePath = new TreePath(nodes);
716 logTree.collapsePath(treePath);
717 }
718 }
719 }
720
721 ensureRootExpanded();
722 }
723
724
725
726
727
728 private void configureToolbarPanel()
729 {
730 toolbar.setFloatable(false);
731
732 expandButton.setAction(expandAction);
733 expandButton.setText(null);
734 collapseButton.setAction(collapseAction);
735 collapseButton.setText(null);
736 focusOnLoggerButton.setAction(focusOnAction);
737 focusOnLoggerButton.setText(null);
738 ignoreLoggerButton.setAction(hideAction);
739 ignoreLoggerButton.setText(null);
740
741 expandButton.setFont(expandButton.getFont().deriveFont(Font.BOLD));
742 collapseButton.setFont(collapseButton.getFont().deriveFont(Font.BOLD));
743
744 editLoggerButton.setAction(editLoggerAction);
745 editLoggerButton.setText(null);
746 closeButton.setAction(closeAction);
747 closeButton.setText(null);
748
749 toolbar.add(expandButton);
750 toolbar.add(collapseButton);
751 toolbar.addSeparator();
752 toolbar.add(focusOnLoggerButton);
753 toolbar.add(ignoreLoggerButton);
754
755
756 toolbar.addSeparator();
757
758 toolbar.add(Box.createHorizontalGlue());
759 toolbar.add(closeButton);
760 toolbar.add(Box.createHorizontalStrut(5));
761 }
762
763
764
765
766
767
768 private Action createClearIgnoreListAction()
769 {
770 Action action = new AbstractAction("Clear Ignore list", null)
771 {
772 public void actionPerformed(ActionEvent e)
773 {
774 ignoreLoggerButton.setSelected(false);
775 logTreeModel.reload();
776 hiddenSet.clear();
777 fireChangeEvent();
778 }
779 };
780
781 action.putValue(
782 Action.SHORT_DESCRIPTION,
783 "Removes all entries from the Ignore list so you can see their events in the view");
784
785 return action;
786 }
787
788
789
790
791
792 private Action createCloseAction()
793 {
794 Action action = new AbstractAction()
795 {
796 public void actionPerformed(ActionEvent e)
797 {
798 preferenceModel.setLogTreePanelVisible(false);
799 }
800 };
801
802 action.putValue(Action.NAME, "Close");
803 action.putValue(Action.SHORT_DESCRIPTION, "Closes the Logger panel");
804 action.putValue(Action.SMALL_ICON, LineIconFactory.createCloseIcon());
805
806 return action;
807 }
808
809
810
811
812
813
814 private Action createCollapseAction()
815 {
816 Action action = new AbstractAction()
817 {
818 public void actionPerformed(ActionEvent e)
819 {
820 collapseCurrentlySelectedNode();
821 }
822 };
823
824 action.putValue(Action.SMALL_ICON, LineIconFactory.createCollapseIcon());
825 action.putValue(Action.NAME, "Collapse Branch");
826 action.putValue(
827 Action.SHORT_DESCRIPTION,
828 "Collapses all the children of the currently selected node");
829 action.setEnabled(false);
830
831 return action;
832 }
833
834 private Action createEditLoggerAction()
835 {
836 Action action = new AbstractAction()
837 {
838 public void actionPerformed(ActionEvent e)
839 {
840
841 }
842 };
843
844
845 action.putValue("enabled", Boolean.FALSE);
846
847 action.putValue(Action.NAME, "Edit filters/colors");
848 action.putValue(
849 Action.SHORT_DESCRIPTION,
850 "Allows you to specify filters and coloring for this Logger");
851 action.putValue(
852 Action.SMALL_ICON, new ImageIcon(ChainsawIcons.ICON_EDIT_RECEIVER));
853 action.setEnabled(false);
854
855 return action;
856 }
857
858
859
860
861
862
863 private Action createExpandAction()
864 {
865 Action action = new AbstractAction()
866 {
867 public void actionPerformed(ActionEvent e)
868 {
869 expandCurrentlySelectedNode();
870 }
871 };
872
873 action.putValue(Action.SMALL_ICON, LineIconFactory.createExpandIcon());
874 action.putValue(Action.NAME, "Expand branch");
875 action.putValue(
876 Action.SHORT_DESCRIPTION,
877 "Expands all the child nodes of the currently selected node, recursively");
878 action.setEnabled(false);
879
880 return action;
881 }
882
883
884
885
886
887
888 private Action createFindNextAction()
889 {
890 Action action = new AbstractAction()
891 {
892 public void actionPerformed(ActionEvent e)
893 {
894 findNextUsingCurrentlySelectedNode();
895 }
896 };
897
898 action.putValue(Action.NAME, "Find next");
899 action.putValue(
900 Action.SHORT_DESCRIPTION,
901 "Find using the selected node");
902 action.setEnabled(false);
903
904 return action;
905 }
906
907 private Action createSetRefineFocusAction()
908 {
909 Action action = new AbstractAction()
910 {
911 public void actionPerformed(ActionEvent e)
912 {
913 setRefineFocusUsingCurrentlySelectedNode();
914 }
915 };
916
917 action.putValue(Action.NAME, "Set 'refine focus' to selected logger");
918 action.putValue(
919 Action.SHORT_DESCRIPTION,
920 "Refine focus on the selected node");
921 action.setEnabled(false);
922
923 return action;
924 }
925
926 private Action createUpdateRefineFocusAction()
927 {
928 Action action = new AbstractAction()
929 {
930 public void actionPerformed(ActionEvent e)
931 {
932 updateRefineFocusUsingCurrentlySelectedNode();
933 }
934 };
935
936 action.putValue(Action.NAME, "Update 'refine focus' to include selected logger");
937 action.putValue(
938 Action.SHORT_DESCRIPTION,
939 "Add selected node to 'refine focus' field");
940 action.setEnabled(false);
941
942 return action;
943 }
944
945 private Action createUpdateFindAction()
946 {
947 Action action = new AbstractAction()
948 {
949 public void actionPerformed(ActionEvent e)
950 {
951 updateFindUsingCurrentlySelectedNode();
952 }
953 };
954
955 action.putValue(Action.NAME, "Update 'find' to include selected logger");
956 action.putValue(
957 Action.SHORT_DESCRIPTION,
958 "Add selected node to 'find' field");
959 action.setEnabled(false);
960
961 return action;
962 }
963
964 private void updateFindUsingCurrentlySelectedNode()
965 {
966 String selectedLogger = getCurrentlySelectedLoggerName();
967 TreePath[] paths = logTree.getSelectionPaths();
968
969 if (paths == null)
970 {
971 return;
972 }
973 String currentFindText = logPanel.getFindText();
974 logPanel.setFindText(currentFindText + " || logger ~= " + selectedLogger);
975 }
976
977 private void updateRefineFocusUsingCurrentlySelectedNode()
978 {
979 String selectedLogger = getCurrentlySelectedLoggerName();
980 TreePath[] paths = logTree.getSelectionPaths();
981
982 if (paths == null)
983 {
984 return;
985 }
986 String currentFilterText = logPanel.getRefineFocusText();
987 logPanel.setRefineFocusText(currentFilterText + " || logger ~= " + selectedLogger);
988 }
989
990 private void setRefineFocusUsingCurrentlySelectedNode()
991 {
992 String selectedLogger = getCurrentlySelectedLoggerName();
993 TreePath[] paths = logTree.getSelectionPaths();
994
995 if (paths == null)
996 {
997 return;
998 }
999 logPanel.setRefineFocusText("logger ~= " + selectedLogger);
1000 }
1001
1002 private Action createDefineColorRuleForLoggerAction() {
1003 Action action = new AbstractAction()
1004 {
1005 public void actionPerformed(ActionEvent e)
1006 {
1007 String selectedLogger = getCurrentlySelectedLoggerName();
1008 TreePath[] paths = logTree.getSelectionPaths();
1009
1010 if (paths == null)
1011 {
1012 return;
1013 }
1014 Color c = JColorChooser.showDialog(getRootPane(), "Choose a color", Color.red);
1015 if (c != null) {
1016 String expression = "logger like '^" + selectedLogger + ".*'";
1017 colorizer.addRule(ChainsawConstants.DEFAULT_COLOR_RULE_NAME, new ColorRule(expression,
1018 ExpressionRule.getRule(expression), c, ChainsawConstants.COLOR_DEFAULT_FOREGROUND));
1019 }
1020 }};
1021
1022 action.putValue(Action.NAME, "Define color rule for selected logger");
1023 action.putValue(
1024 Action.SHORT_DESCRIPTION,
1025 "Define color rule for logger");
1026 action.setEnabled(false);
1027 return action;
1028 }
1029
1030
1031
1032
1033
1034
1035 private Action createClearFindNextAction()
1036 {
1037 Action action = new AbstractAction()
1038 {
1039 public void actionPerformed(ActionEvent e)
1040 {
1041 clearFindNext();
1042 }
1043 };
1044
1045 action.putValue(Action.NAME, "Clear find field");
1046 action.putValue(
1047 Action.SHORT_DESCRIPTION,
1048 "Clear the find field");
1049 action.setEnabled(false);
1050
1051 return action;
1052 }
1053
1054 private Action createClearRefineFocusAction()
1055 {
1056 Action action = new AbstractAction()
1057 {
1058 public void actionPerformed(ActionEvent e)
1059 {
1060 clearRefineFocus();
1061 }
1062 };
1063
1064 action.putValue(Action.NAME, "Clear 'refine focus' field");
1065 action.putValue(
1066 Action.SHORT_DESCRIPTION,
1067 "Clear the refine focus field");
1068 action.setEnabled(false);
1069
1070 return action;
1071 }
1072
1073
1074
1075
1076
1077
1078 private Action createFocusOnAction()
1079 {
1080 final Action action = new AbstractAction()
1081 {
1082 public void actionPerformed(ActionEvent e)
1083 {
1084 toggleFocusOnState();
1085 }
1086 };
1087
1088 action.putValue(Action.NAME, "Focus");
1089 action.putValue(
1090 Action.SHORT_DESCRIPTION,
1091 "Allows you to Focus on the selected logger by setting a filter that discards all but this Logger");
1092 action.putValue(
1093 Action.SMALL_ICON, new ImageIcon(ChainsawIcons.WINDOW_ICON));
1094
1095 action.setEnabled(false);
1096
1097 return action;
1098 }
1099
1100
1101
1102
1103
1104
1105 private Action createIgnoreAllAction()
1106 {
1107 Action action =
1108 new AbstractAction(
1109 "Ignore loggers below selection")
1110 {
1111 public void actionPerformed(ActionEvent e)
1112 {
1113
1114 TreePath[] paths = logTree.getSelectionPaths();
1115
1116 String parentPathString = "";
1117 DefaultMutableTreeNode root;
1118 if ((paths == null) || (paths.length == 0))
1119 {
1120 root = (DefaultMutableTreeNode) logTreeModel.getRoot();
1121 } else {
1122 root = (DefaultMutableTreeNode) logTree.getSelectionPath().getLastPathComponent();
1123 TreeNode[] path = root.getPath();
1124
1125 for (int i=1;i<path.length;i++) {
1126 if (i > 1) {
1127 parentPathString = parentPathString + ".";
1128 }
1129 parentPathString = parentPathString + path[i].toString();
1130 }
1131 if (!(parentPathString.equals(""))) {
1132 parentPathString = parentPathString + ".";
1133 }
1134 }
1135 Enumeration topLevelLoggersEnumeration = root.children();
1136 Set topLevelLoggersSet = new HashSet();
1137 while (topLevelLoggersEnumeration.hasMoreElements()) {
1138 String thisLogger = topLevelLoggersEnumeration.nextElement().toString();
1139 topLevelLoggersSet.add(parentPathString + thisLogger);
1140 }
1141 if (topLevelLoggersSet.size() > 0) {
1142 ignore(topLevelLoggersSet);
1143 }
1144
1145 logTreeModel.nodeChanged(root);
1146 ignoreLoggerButton.setSelected(false);
1147 focusOnAction.setEnabled(false);
1148 popupMenu.hideCheck.setSelected(false);
1149 fireChangeEvent();
1150 }
1151 };
1152
1153 action.putValue(
1154 Action.SHORT_DESCRIPTION,
1155 "Adds all loggers to your Ignore list (unhide loggers you want to see in the view)");
1156
1157 return action;
1158 }
1159
1160
1161
1162
1163
1164
1165 private Action createIgnoreAction()
1166 {
1167 Action action =
1168 new AbstractAction(
1169 "Ignore this Logger", new ImageIcon(ChainsawIcons.ICON_COLLAPSE))
1170 {
1171 public void actionPerformed(ActionEvent e)
1172 {
1173 String logger = getCurrentlySelectedLoggerName();
1174
1175 if (logger != null)
1176 {
1177 toggleHiddenLogger(logger);
1178 logTreeModel.nodeChanged(
1179 (TreeNode) logTree.getSelectionPath().getLastPathComponent());
1180 ignoreLoggerButton.setSelected(hiddenSet.contains(logger));
1181 focusOnAction.setEnabled(!hiddenSet.contains(logger));
1182 popupMenu.hideCheck.setSelected(hiddenSet.contains(logger));
1183 }
1184
1185 fireChangeEvent();
1186 }
1187 };
1188
1189 action.putValue(
1190 Action.SHORT_DESCRIPTION,
1191 "Adds the selected Logger to your Ignore list, filtering those events from view");
1192
1193 return action;
1194 }
1195
1196 private void ensureRootExpanded()
1197 {
1198 logger.debug("Ensuring Root node is expanded.");
1199
1200 final DefaultMutableTreeNode root =
1201 (DefaultMutableTreeNode) logTreeModel.getRoot();
1202 SwingUtilities.invokeLater(new Runnable()
1203 {
1204 public void run()
1205 {
1206 logTree.expandPath(new TreePath(root));
1207 }
1208 });
1209 }
1210
1211 private void findNextUsingCurrentlySelectedNode()
1212 {
1213 String selectedLogger = getCurrentlySelectedLoggerName();
1214 TreePath[] paths = logTree.getSelectionPaths();
1215
1216 if (paths == null)
1217 {
1218 return;
1219 }
1220 logPanel.setFindText("logger like '^" + selectedLogger + ".*'");
1221 }
1222
1223 private void clearFindNext()
1224 {
1225 logPanel.setFindText("");
1226 }
1227
1228 private void clearRefineFocus()
1229 {
1230 logPanel.setRefineFocusText("");
1231 }
1232
1233
1234
1235
1236
1237
1238 private void expandCurrentlySelectedNode()
1239 {
1240 TreePath[] paths = logTree.getSelectionPaths();
1241
1242 if (paths == null)
1243 {
1244 return;
1245 }
1246
1247 logger.debug("Expanding all children of selected node");
1248
1249 for (int i = 0; i < paths.length; i++)
1250 {
1251 TreePath path = paths[i];
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267 DefaultMutableTreeNode treeNode =
1268 (DefaultMutableTreeNode) path.getLastPathComponent();
1269
1270 Enumeration depthEnum = treeNode.depthFirstEnumeration();
1271
1272 if (!depthEnum.hasMoreElements())
1273 {
1274 break;
1275 }
1276
1277 List depths = new ArrayList();
1278
1279 while (depthEnum.hasMoreElements())
1280 {
1281 depths.add(
1282 new Integer(
1283 ((DefaultMutableTreeNode) depthEnum.nextElement()).getDepth()));
1284 }
1285
1286 Collections.sort(depths);
1287 Collections.reverse(depths);
1288
1289 int maxDepth = ((Integer) depths.get(0)).intValue();
1290
1291 if (maxDepth > WARN_DEPTH)
1292 {
1293 logger.warn("Should warn user, depth=" + maxDepth);
1294 }
1295
1296 depthEnum = treeNode.depthFirstEnumeration();
1297
1298 while (depthEnum.hasMoreElements())
1299 {
1300 DefaultMutableTreeNode node =
1301 (DefaultMutableTreeNode) depthEnum.nextElement();
1302
1303 if (node.isLeaf() && node.getParent() != null)
1304 {
1305 TreeNode[] nodes =
1306 ((DefaultMutableTreeNode) node.getParent()).getPath();
1307 TreePath treePath = new TreePath(nodes);
1308
1309 logger.debug("Expanding path:" + treePath);
1310
1311 logTree.expandPath(treePath);
1312 }
1313 }
1314 }
1315 }
1316
1317 private void fireChangeEvent()
1318 {
1319 ChangeListener[] listeners =
1320 (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
1321 ChangeEvent e = null;
1322
1323 for (int i = 0; i < listeners.length; i++)
1324 {
1325 if (e == null)
1326 {
1327 e = new ChangeEvent(this);
1328 }
1329
1330 listeners[i].stateChanged(e);
1331 }
1332 }
1333
1334 private void reconfigureMenuText()
1335 {
1336 String logger = getCurrentlySelectedLoggerName();
1337
1338 if ((logger == null) || (logger.length() == 0))
1339 {
1340 focusOnAction.putValue(Action.NAME, "Focus On...");
1341 hideAction.putValue(Action.NAME, "Ignore...");
1342 findAction.putValue(Action.NAME, "Find...");
1343 setRefineFocusAction.putValue(Action.NAME, "Set refine focus field");
1344 updateRefineFocusAction.putValue(Action.NAME, "Add to refine focus field");
1345 updateFindAction.putValue(Action.NAME, "Add to find field");
1346 defineColorRuleForLoggerAction.putValue(Action.NAME, "Define color rule");
1347 }
1348 else
1349 {
1350 focusOnAction.putValue(Action.NAME, "Focus On '" + logger + "'");
1351 hideAction.putValue(Action.NAME, "Ignore '" + logger + "'");
1352 findAction.putValue(Action.NAME, "Find '" + logger + "'");
1353 setRefineFocusAction.putValue(Action.NAME, "Set refine focus field to '" + logger + "'");
1354 updateRefineFocusAction.putValue(Action.NAME, "Add '" + logger + "' to 'refine focus' field");
1355 updateFindAction.putValue(Action.NAME, "Add '" + logger + "' to 'find' field");
1356 defineColorRuleForLoggerAction.putValue(Action.NAME, "Define color rule for '" + logger + "'");
1357 }
1358
1359
1360 hideSubLoggersAction.putValue(Action.NAME, "Ignore loggers below selection");
1361 focusOnLoggerButton.setText(null);
1362 ignoreLoggerButton.setText(null);
1363 }
1364
1365
1366
1367
1368
1369 private void setupListeners()
1370 {
1371 logTree.addMouseMotionListener(new MouseKeyIconListener());
1372
1373
1374
1375
1376 logTree.addTreeSelectionListener(new TreeSelectionListener()
1377 {
1378 public void valueChanged(TreeSelectionEvent e)
1379 {
1380 TreePath path = e.getNewLeadSelectionPath();
1381 TreeNode node = null;
1382
1383 if (path != null)
1384 {
1385 node = (TreeNode) path.getLastPathComponent();
1386 }
1387 boolean focusOnSelected = isFocusOnSelected();
1388
1389 currentlySelectedLoggerName = getCurrentlySelectedLoggerName();
1390 focusOnAction.setEnabled(
1391 (path != null) && (node != null) && (node.getParent() != null)
1392 && !hiddenSet.contains(currentlySelectedLoggerName));
1393 hideAction.setEnabled(
1394 (path != null) && (node != null) && (node.getParent() != null));
1395 if (!focusOnAction.isEnabled())
1396 {
1397 setFocusOnSelected(false);
1398 }
1399 else
1400 {
1401 }
1402
1403 expandAction.setEnabled(path != null);
1404 findAction.setEnabled(path != null);
1405 clearFindNextAction.setEnabled(true);
1406 defineColorRuleForLoggerAction.setEnabled(path != null);
1407 setRefineFocusAction.setEnabled(path != null);
1408 updateRefineFocusAction.setEnabled(path != null);
1409 updateFindAction.setEnabled(path != null);
1410 clearRefineFocusAction.setEnabled(true);
1411
1412 if (currentlySelectedLoggerName != null)
1413 {
1414 boolean isHidden = hiddenSet.contains(currentlySelectedLoggerName);
1415 popupMenu.hideCheck.setSelected(isHidden);
1416 ignoreLoggerButton.setSelected(isHidden);
1417 }
1418
1419 collapseAction.setEnabled(path != null);
1420
1421 reconfigureMenuText();
1422 if (isFocusOnSelected()) {
1423 fireChangeEvent();
1424 }
1425
1426 if (focusOnSelected && !isFocusOnSelected()) {
1427 fireChangeEvent();
1428 }
1429
1430 logPanel.repaint();
1431 }
1432 });
1433
1434 logTree.addMouseListener(popupListener);
1435
1436
1437
1438
1439
1440
1441 focusOnAction.addPropertyChangeListener(new PropertyChangeListener()
1442 {
1443 public void propertyChange(PropertyChangeEvent evt)
1444 {
1445 popupMenu.focusOnCheck.setSelected(isFocusOnSelected());
1446 focusOnLoggerButton.setSelected(isFocusOnSelected());
1447
1448 if (logTree.getSelectionPath() != null)
1449 {
1450 logTreeModel.nodeChanged(
1451 (TreeNode) logTree.getSelectionPath().getLastPathComponent());
1452 }
1453 }
1454 });
1455
1456 hideAction.addPropertyChangeListener(new PropertyChangeListener()
1457 {
1458 public void propertyChange(PropertyChangeEvent evt)
1459 {
1460 if (logTree.getSelectionPath() != null)
1461 {
1462 logTreeModel.nodeChanged(
1463 (TreeNode) logTree.getSelectionPath().getLastPathComponent());
1464 }
1465 }
1466 });
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488 logTree.addMouseListener(new MouseFocusOnListener());
1489
1490
1491
1492
1493
1494 addChangeListener(new ChangeListener()
1495 {
1496 public void stateChanged(ChangeEvent evt)
1497 {
1498 visibilityRuleDelegate.firePropertyChange("rule", null, null);
1499 updateDisplay();
1500 }
1501 });
1502
1503 visibilityRuleDelegate.addPropertyChangeListener(new PropertyChangeListener()
1504 {
1505 public void propertyChange(PropertyChangeEvent event)
1506 {
1507 if (event.getPropertyName().equals("hiddenSet")) {
1508 updateDisplay();
1509 }
1510 }
1511 });
1512 }
1513
1514 private void updateDisplay() {
1515 updateHiddenSetModels();
1516 updateIgnoreSummary();
1517 updateIgnoreExpressionSummary();
1518 updateAlwaysDisplayExpressionSummary();
1519 }
1520
1521 private void updateHiddenSetModels() {
1522 DefaultListModel model = (DefaultListModel) ignoreList.getModel();
1523 model.clear();
1524 List sortedIgnoreList = new ArrayList(hiddenSet);
1525 Collections.sort(sortedIgnoreList);
1526
1527 for (Iterator iter = sortedIgnoreList.iterator(); iter.hasNext();)
1528 {
1529 String string = (String) iter.next();
1530 model.addElement(string);
1531 }
1532
1533
1534
1535 }
1536 private void updateIgnoreSummary() {
1537 ignoreSummary.setText(ignoreList.getModel().getSize() + " hidden loggers");
1538 }
1539
1540 private void updateIgnoreExpressionSummary() {
1541 ignoreExpressionSummary.setText(ignoreExpressionRule != null?"Ignore (set)":"Ignore (unset)");
1542 }
1543
1544 private void updateAlwaysDisplayExpressionSummary() {
1545 alwaysDisplayExpressionSummary.setText(alwaysDisplayExpressionRule != null?"Always displayed (set)":"Always displayed (unset)");
1546 }
1547
1548 private void toggleFocusOnState()
1549 {
1550 setFocusOnSelected(!isFocusOnSelected());
1551 fireChangeEvent();
1552 }
1553
1554 public Collection getHiddenSet() {
1555 return Collections.unmodifiableSet(hiddenSet);
1556 }
1557
1558 public String getHiddenExpression() {
1559 String text = ignoreExpressionEntryField.getText();
1560 if (text == null || text.trim().equals("")) {
1561 return null;
1562 }
1563 return text.trim();
1564 }
1565
1566 public void setHiddenExpression(String hiddenExpression) {
1567 ignoreExpressionEntryField.setText(hiddenExpression);
1568 updateIgnoreExpression(hiddenExpression);
1569 }
1570
1571 public String getAlwaysDisplayExpression() {
1572 String text = alwaysDisplayExpressionEntryField.getText();
1573 if (text == null || text.trim().equals("")) {
1574 return null;
1575 }
1576 return text.trim();
1577 }
1578
1579 public void setAlwaysDisplayExpression(String alwaysDisplayExpression) {
1580 alwaysDisplayExpressionEntryField.setText(alwaysDisplayExpression);
1581 updateAlwaysDisplayExpression(alwaysDisplayExpression);
1582 }
1583
1584 public void loggerNameAdded(String loggerName)
1585 {
1586
1587 }
1588
1589 public void reset()
1590 {
1591 expandRootLatch = false;
1592
1593 final String logger = currentlySelectedLoggerName;
1594 final boolean focusOnSelected = isFocusOnSelected();
1595 if (logger == null || !focusOnSelected) {
1596 return;
1597 }
1598
1599
1600 logTreeModel.loggerNameAdded(logger);
1601 EventQueue.invokeLater(new Runnable() {
1602 public void run() {
1603 setFocusOn(logger);
1604 }
1605 });
1606 }
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619 private class LoggerNameTreeCellRenderer extends DefaultTreeCellRenderer
1620 {
1621
1622
1623
1624 private LoggerNameTreeCellRenderer()
1625 {
1626 super();
1627
1628
1629
1630 setLeafIcon(null);
1631 setOpaque(false);
1632 }
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652 public Component getTreeCellRendererComponent(
1653 JTree tree, Object value, boolean sel, boolean expanded, boolean leaf,
1654 int row, boolean focus)
1655 {
1656 JLabel component =
1657 (JLabel) super.getTreeCellRendererComponent(
1658 tree, value, sel, expanded, leaf, row, focus);
1659
1660 Font originalFont = new Font(component.getFont().getName(), component.getFont().getStyle(), component.getFont().getSize());
1661
1662 int style = Font.PLAIN;
1663
1664 if (sel && focusOnLoggerButton.isSelected())
1665 {
1666 style = style | Font.BOLD;
1667 }
1668
1669 String logger =
1670 getLoggerName(
1671 new TreePath(((DefaultMutableTreeNode) value).getPath()));
1672
1673 if (hiddenSet.contains(logger))
1674 {
1675
1676
1677 style = style | Font.ITALIC;
1678
1679
1680 }
1681 else
1682 {
1683
1684
1685 }
1686
1687 if (originalFont != null)
1688 {
1689 Font font2 = originalFont.deriveFont(style);
1690
1691 if (font2 != null)
1692 {
1693 component.setFont(font2);
1694 }
1695 }
1696
1697 return component;
1698 }
1699 }
1700
1701 private class LoggerTreePopupMenu extends JPopupMenu
1702 {
1703
1704
1705 JCheckBoxMenuItem focusOnCheck = new JCheckBoxMenuItem();
1706 JCheckBoxMenuItem hideCheck = new JCheckBoxMenuItem();
1707
1708
1709
1710 private LoggerTreePopupMenu()
1711 {
1712 initMenu();
1713 }
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727 public void show(Component invoker, int x, int y)
1728 {
1729 DefaultMutableTreeNode node =
1730 (DefaultMutableTreeNode) logTree.getLastSelectedPathComponent();
1731
1732 if (node == null)
1733 {
1734 return;
1735 }
1736
1737 super.show(invoker, x, y);
1738 }
1739
1740
1741
1742
1743 private void initMenu()
1744 {
1745 focusOnCheck.setAction(focusOnAction);
1746 hideCheck.setAction(hideAction);
1747 add(expandAction);
1748 add(collapseAction);
1749 addSeparator();
1750 add(focusOnCheck);
1751 add(hideCheck);
1752 addSeparator();
1753 add(setRefineFocusAction);
1754 add(updateRefineFocusAction);
1755 add(clearRefineFocusAction);
1756 addSeparator();
1757 add(findAction);
1758 add(updateFindAction);
1759 add(clearFindNextAction);
1760
1761 addSeparator();
1762 add(defineColorRuleForLoggerAction);
1763 addSeparator();
1764
1765 add(hideSubLoggersAction);
1766 add(clearIgnoreListAction);
1767 }
1768 }
1769
1770 private final class MouseFocusOnListener extends MouseAdapter
1771 {
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782 public void mouseClicked(MouseEvent e)
1783 {
1784 if (
1785 (e.getClickCount() > 1)
1786 && ((e.getModifiers() & InputEvent.CTRL_MASK) > 0)
1787 && ((e.getModifiers() & InputEvent.SHIFT_MASK) > 0))
1788 {
1789 ignoreLoggerAtPoint(e.getPoint());
1790 e.consume();
1791 fireChangeEvent();
1792 }
1793 else if (
1794 (e.getClickCount() > 1)
1795 && ((e.getModifiers() & InputEvent.CTRL_MASK) > 0))
1796 {
1797 focusAnLoggerAtPoint(e.getPoint());
1798 e.consume();
1799 fireChangeEvent();
1800 }
1801 }
1802
1803
1804
1805
1806
1807
1808 private void focusAnLoggerAtPoint(Point point)
1809 {
1810 String logger = getLoggerAtPoint(point);
1811
1812 if (logger != null)
1813 {
1814 toggleFocusOnState();
1815 }
1816 }
1817
1818
1819
1820
1821
1822
1823
1824 private String getLoggerAtPoint(Point point)
1825 {
1826 TreePath path = logTree.getPathForLocation(point.x, point.y);
1827
1828 if (path != null)
1829 {
1830 return getLoggerName(path);
1831 }
1832
1833 return null;
1834 }
1835
1836
1837
1838
1839
1840
1841 private void ignoreLoggerAtPoint(Point point)
1842 {
1843 String logger = getLoggerAtPoint(point);
1844
1845 if (logger != null)
1846 {
1847 toggleHiddenLogger(logger);
1848 fireChangeEvent();
1849 }
1850 }
1851 }
1852
1853 private final class MouseKeyIconListener extends MouseMotionAdapter
1854 implements MouseMotionListener
1855 {
1856
1857
1858 Cursor focusOnCursor =
1859 Toolkit.getDefaultToolkit().createCustomCursor(
1860 ChainsawIcons.FOCUS_ON_ICON.getImage(), new Point(10, 10), "");
1861 Cursor ignoreCursor =
1862 Toolkit.getDefaultToolkit().createCustomCursor(
1863 ChainsawIcons.IGNORE_ICON.getImage(), new Point(10, 10), "");
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875 public void mouseMoved(MouseEvent e)
1876 {
1877
1878 if (
1879 ((e.getModifiers() & InputEvent.CTRL_MASK) > 0)
1880 && ((e.getModifiers() & InputEvent.SHIFT_MASK) > 0))
1881 {
1882 logTree.setCursor(ignoreCursor);
1883 }
1884 else if ((e.getModifiers() & InputEvent.CTRL_MASK) > 0)
1885 {
1886 logTree.setCursor(focusOnCursor);
1887 }
1888 else
1889 {
1890 logTree.setCursor(Cursor.getDefaultCursor());
1891 }
1892 }
1893 }
1894
1895 class VisibilityRuleDelegate extends AbstractRule {
1896 public boolean evaluate(LoggingEvent e, Map matches)
1897 {
1898 String currentlySelectedLoggerName = getCurrentlySelectedLoggerName();
1899 boolean hiddenLogger = e.getLoggerName() != null && isHiddenLogger(e.getLoggerName());
1900 boolean hiddenExpression = (ignoreExpressionRule != null && ignoreExpressionRule.evaluate(e, null));
1901 boolean alwaysDisplayExpression = (alwaysDisplayExpressionRule != null && alwaysDisplayExpressionRule.evaluate(e, null));
1902 boolean hidden = (!alwaysDisplayExpression) && (hiddenLogger || hiddenExpression);
1903 if (currentlySelectedLoggerName == null) {
1904
1905 return !hidden;
1906 }
1907 boolean result = (e.getLoggerName() != null) && !hidden;
1908
1909 if (result && isFocusOnSelected())
1910 {
1911 result = (e.getLoggerName() != null && (e.getLoggerName().startsWith(currentlySelectedLoggerName+".") || e.getLoggerName().endsWith(currentlySelectedLoggerName)));
1912 }
1913
1914 return result;
1915 }
1916
1917 public void firePropertyChange(String propertyName, Object oldVal, Object newVal)
1918 {
1919 super.firePropertyChange(propertyName, oldVal, newVal);
1920 }
1921 }
1922
1923 }