KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > qfs > apps > qflog > logview > LogLevelView


1 // {{{ copyright
2

3 /********************************************************************
4  *
5  * $Id: LogLevelView.java,v 1.16 2000/07/05 14:07:44 gs Exp $
6  *
7  * The contents of this file are subject to the Mozilla Public
8  * License Version 1.1 (the "License"); you may not use this file
9  * except in compliance with the License. You may obtain a copy of
10  * the License at http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS
13  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14  * implied. See the License for the specific language governing
15  * rights and limitations under the License.
16  *
17  * The Original Code is qfs.de code.
18  *
19  * The Initial Developer of the Original Code is Gregor Schmid.
20  * Portions created by Gregor Schmid are
21  * Copyright (C) 1999 Quality First Software, Gregor Schmid.
22  * All Rights Reserved.
23  *
24  * Contributor(s):
25  *
26  *******************************************************************/

27
28 // }}}
29

30 package de.qfs.apps.qflog.logview;
31
32 // {{{ imports
33

34 import java.awt.BorderLayout JavaDoc;
35 import java.awt.Component JavaDoc;
36 import java.awt.Frame JavaDoc;
37 import java.awt.Window JavaDoc;
38 import java.awt.event.ActionEvent JavaDoc;
39 import java.awt.event.KeyEvent JavaDoc;
40 import java.awt.event.MouseAdapter JavaDoc;
41 import java.awt.event.MouseEvent JavaDoc;
42
43 import java.util.ResourceBundle JavaDoc;
44
45 import javax.swing.Action JavaDoc;
46 import javax.swing.AbstractAction JavaDoc;
47 import javax.swing.BorderFactory JavaDoc;
48 import javax.swing.Icon JavaDoc;
49 import javax.swing.KeyStroke JavaDoc;
50 import javax.swing.JLabel JavaDoc;
51 import javax.swing.JMenu JavaDoc;
52 import javax.swing.JMenuItem JavaDoc;
53 import javax.swing.JPanel JavaDoc;
54 import javax.swing.JPopupMenu JavaDoc;
55 import javax.swing.JScrollPane JavaDoc;
56 import javax.swing.JTree JavaDoc;
57 import javax.swing.SwingUtilities JavaDoc;
58 import javax.swing.tree.DefaultTreeCellRenderer JavaDoc;
59 import javax.swing.tree.TreePath JavaDoc;
60
61 import de.qfs.lib.gui.SwingUtil;
62 import de.qfs.lib.gui.WindowsTreeCellRenderer;
63 import de.qfs.lib.log.Log;
64 import de.qfs.lib.log.Logger;
65 import de.qfs.lib.option.OptionDialog;
66 import de.qfs.lib.util.MapResourceBundle;
67
68 // }}}
69

70 /**
71  * A view for display and manipulation of the log levels of an application. <p>
72  *
73  * A LogLevelView may be used either as a separate component, integrated into
74  * an applications GUI, to give visual feedback and access to the
75  * application's log levels, or as part of the {@link LogView LogView}
76  * component, that integrates the LogLevelView with other logging related
77  * views. <p>
78  *
79  * The LogLevelView must be initialized by a call to {@link #init init} after
80  * creation. It uses its own resources for localization, which can be modified
81  * via {@link #setResources setResources}. <p>
82  *
83  * The LogLevelView does not have any {@link Configurable Configurable} parts
84  * except for its {@link LogLevelTreeModel LogLevelTreeModel}, which must be
85  * handled by the caller if its state should be saved, unless the LogLevelView
86  * is used as part of a LogView. <p>
87  *
88  * @author Gregor Schmid
89  * @version $Revision: 1.16 $
90  */

91 public class LogLevelView
92     extends JPanel JavaDoc
93 {
94     // {{{ variables
95

96     /**
97      * The Logger used for logging.
98      */

99     private final static Logger logger = new Logger (LogLevelView.class);
100
101     /**
102      * The model of log levels.
103      */

104     private transient LogLevelTreeModel model;
105
106     /**
107      * Whether the view has been initialized.
108      */

109     private transient boolean initialized;
110
111     /**
112      * The tree component.
113      */

114     private transient JTree JavaDoc tree;
115
116     /**
117      * The resources to use.
118      */

119     private transient MapResourceBundle resources;
120
121     /**
122      * Popup menu for context menu.
123      */

124     private transient JPopupMenu JavaDoc popup;
125
126     /**
127      * Mouse listener for the popup menu.
128      */

129     private transient PopupListener popupListener;
130
131     /**
132      * Dialog to edit the options.
133      */

134     private OptionDialog optionDialog;
135
136     /**
137      * Whether logging is enabled (true) or disabled (false);
138      */

139     private boolean logging;
140
141     //----------------------------------------------------------------------
142
// The actions
143
//----------------------------------------------------------------------
144
/**
145      * Remove log levels (non recursive).
146      */

147     private Action JavaDoc removeAction;
148
149     /**
150      * Remove log levels (recursive).
151      */

152     private Action JavaDoc removeRecursiveAction;
153
154     /**
155      * Set log levels to Log.ERR
156      */

157     private Action JavaDoc setERRAction;
158
159     /**
160      * Set log levels to Log.ERRDETAIL
161      */

162     private Action JavaDoc setERRDETAILAction;
163
164     /**
165      * Set log levels to Log.WRN
166      */

167     private Action JavaDoc setWRNAction;
168
169     /**
170      * Set log levels to Log.WRNDETAIL
171      */

172     private Action JavaDoc setWRNDETAILAction;
173
174     /**
175      * Set log levels to Log.MSG
176      */

177     private Action JavaDoc setMSGAction;
178
179     /**
180      * Set log levels to Log.MSGDETAIL
181      */

182     private Action JavaDoc setMSGDETAILAction;
183
184     /**
185      * Set log levels to Log.MTD
186      */

187     private Action JavaDoc setMTDAction;
188
189     /**
190      * Set log levels to Log.MTDDETAIL
191      */

192     private Action JavaDoc setMTDDETAILAction;
193
194     /**
195      * Set log levels to Log.DBG
196      */

197     private Action JavaDoc setDBGAction;
198
199     /**
200      * Set log levels to Log.DBGDETAIL
201      */

202     private Action JavaDoc setDBGDETAILAction;
203
204     /**
205      * Expand path and all descendants.
206      */

207     private Action JavaDoc expandAllAction;
208
209     /**
210      * Collapse path and all descendants.
211      */

212     private Action JavaDoc collapseAllAction;
213
214     /**
215      * Display all nodes with a non-null level.
216      */

217     private Action JavaDoc showSetLevelsAction;
218
219     /**
220      * Edit the options.
221      */

222     private Action JavaDoc editOptionsAction;
223
224     // }}}
225

226     // {{{ constructor
227

228     /**
229      * Create a new LogLevelView.
230      *
231      * @param model The mode to use for the tree.
232      */

233     public LogLevelView(LogLevelTreeModel model)
234     {
235         boolean excluded = ! logging;
236         if (excluded) {
237             Log.excludeThread();
238         }
239         try {
240             this.model = model;
241             resources = new MapResourceBundle ();
242             resources.fetchProperties
243                 ("/de/qfs/apps/qflog/logview/resources/properties/loglevelview",
244                  LogLevelView.class);
245             model.setRootName(resources.getString("logLevelView.root.name",
246                                                   "default"));
247         } finally {
248             if (excluded) {
249                 Log.includeThread();
250             }
251         }
252     }
253
254     // }}}
255

256     // {{{ setLoggingEnabled
257

258     /**
259      * Enable or disable logging output caused directly or indirectly by
260      * LogLevelView methods. If logging is disabled, all calls to
261      * methods that might create log messages will be protected with {@link
262      * de.qfs.lib.log.Log#excludeThread de.qfs.lib.log.Log.excludeThread}.
263      * This is necessary, if the LogFilterTreeModel is used inside the
264      * application whose logs it is supposed to filter. <p>
265      *
266      * The default value is false.
267      *
268      * @param enable True to enable logging, false to disable it.
269      */

270     public final void setLoggingEnabled(boolean enable)
271     {
272         logging = enable;
273         model.setLoggingEnabled(enable);
274     }
275
276     // }}}
277

278     //----------------------------------------------------------------------
279
// Initialization
280
//----------------------------------------------------------------------
281
// {{{ init
282

283     /**
284      * Initialize the components of the view. This method is not called by the
285      * constructor to enable further configuration like setting the resources,
286      * befor the view is initialized.
287      */

288     public void init()
289     {
290         if (initialized) {
291             return;
292         }
293         initialized = true;
294
295         boolean excluded = ! logging;
296         if (excluded) {
297             Log.excludeThread();
298         }
299         try {
300             setLayout(new BorderLayout JavaDoc ());
301             setBorder(null);
302
303             JPanel JavaDoc top = new JPanel JavaDoc ();
304             top.setLayout(new BorderLayout JavaDoc ());
305             top.setBorder(null);
306
307             String JavaDoc title = resources.getString("logLevelView.title",
308                                                "Log levels");
309             JLabel JavaDoc titleLabel = new JLabel JavaDoc (title);
310             titleLabel.setBorder(BorderFactory.createEtchedBorder());
311             top.add(titleLabel, BorderLayout.NORTH);
312
313             tree = new JTree JavaDoc (model) {
314                 public boolean hasBeenExpanded(TreePath JavaDoc path) {
315                     return false;
316                 }
317             };
318             tree.setBorder(null);
319             tree.setCellRenderer(new Renderer JavaDoc ());
320
321             JScrollPane JavaDoc treePane = new JScrollPane JavaDoc (tree);
322             SwingUtil.constrainScroll(treePane);
323             treePane.setBorder(BorderFactory.createLoweredBevelBorder());
324             top.add(treePane, BorderLayout.CENTER);
325             add(top, BorderLayout.CENTER);
326
327             // Default selection
328
tree.setSelectionRow(0);
329
330             // setup and bind actions
331
setupActions();
332
333             tree.registerKeyboardAction
334                 (removeAction, "remove",
335                  KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0),
336                  tree.WHEN_FOCUSED);
337             tree.registerKeyboardAction
338                 (removeRecursiveAction, "removeRecursive",
339                  KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,
340                                         KeyEvent.CTRL_MASK),
341                  tree.WHEN_FOCUSED);
342
343             tree.registerKeyboardAction
344                 (setERRAction, "setERR",
345                  KeyStroke.getKeyStroke(KeyEvent.VK_1, 0),
346                  tree.WHEN_FOCUSED);
347             tree.registerKeyboardAction
348                 (setERRDETAILAction, "setERRDETAIL",
349                  KeyStroke.getKeyStroke(KeyEvent.VK_2, 0),
350                  tree.WHEN_FOCUSED);
351             tree.registerKeyboardAction
352                 (setWRNAction, "setWRN",
353                  KeyStroke.getKeyStroke(KeyEvent.VK_3, 0),
354                  tree.WHEN_FOCUSED);
355             tree.registerKeyboardAction
356                 (setWRNDETAILAction, "setWRNDETAIL",
357                  KeyStroke.getKeyStroke(KeyEvent.VK_4, 0),
358                  tree.WHEN_FOCUSED);
359             tree.registerKeyboardAction
360                 (setMSGAction, "MSGERR",
361                  KeyStroke.getKeyStroke(KeyEvent.VK_5, 0),
362                  tree.WHEN_FOCUSED);
363             tree.registerKeyboardAction
364                 (setMSGDETAILAction, "setMSGDETAIL",
365                  KeyStroke.getKeyStroke(KeyEvent.VK_6, 0),
366                  tree.WHEN_FOCUSED);
367             tree.registerKeyboardAction
368                 (setMTDAction, "setMTD",
369                  KeyStroke.getKeyStroke(KeyEvent.VK_7, 0),
370                  tree.WHEN_FOCUSED);
371             tree.registerKeyboardAction
372                 (setMTDDETAILAction, "setMTDDETAIL",
373                  KeyStroke.getKeyStroke(KeyEvent.VK_8, 0),
374                  tree.WHEN_FOCUSED);
375             tree.registerKeyboardAction
376                 (setDBGAction, "setDBG",
377                  KeyStroke.getKeyStroke(KeyEvent.VK_9, 0),
378                  tree.WHEN_FOCUSED);
379             tree.registerKeyboardAction
380                 (setDBGDETAILAction, "setDBGDETAIL",
381                  KeyStroke.getKeyStroke(KeyEvent.VK_0, 0),
382                  tree.WHEN_FOCUSED);
383
384             tree.registerKeyboardAction
385                 (expandAllAction, "expandAll",
386                  KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, KeyEvent.ALT_MASK),
387                  tree.WHEN_FOCUSED);
388
389             tree.registerKeyboardAction
390                 (collapseAllAction, "collapseAll",
391                  KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, KeyEvent.ALT_MASK),
392                  tree.WHEN_FOCUSED);
393
394             // popup menu
395
popup = new JPopupMenu JavaDoc ();
396             fillMenu(popup);
397             popupListener = new PopupListener ();
398             tree.addMouseListener(popupListener);
399
400             showSetLevels();
401         } finally {
402             if (excluded) {
403                 Log.includeThread();
404             }
405         }
406     }
407
408     // }}}
409
// {{{ cleanup
410

411     /**
412      * Try to remove everything that might prevent the LogLevelView from
413      * being garbage collected.
414      */

415     public void cleanup()
416     {
417         if (logging && logger.level >= Log.MTD) {
418             logger.log(Log.MTD, "cleanup()", "");
419         }
420
421         SwingUtil.cleanup(this);
422
423         tree.removeMouseListener(popupListener);
424         popupListener = null;
425         SwingUtil.cleanup(popup);
426         popup = null;
427
428         tree.resetKeyboardActions();
429         tree = null;
430         resources = null;
431
432         model.cleanup();
433         model = null;
434     }
435
436     // }}}
437
// {{{ finalize
438

439     /**
440      * Finalize the LogLevelView.
441      */

442     public void finalize()
443     {
444         if (logging && logger.level >= Log.MTD) {
445             logger.log(Log.MTD, "finalize()", "");
446         }
447     }
448
449     // }}}
450

451     //----------------------------------------------------------------------
452
// Access
453
//----------------------------------------------------------------------
454
// {{{ getModel
455

456     /**
457      * Get the view's associated LogLevelTreeModel.
458      *
459      * @return The model of the view.
460      */

461     public final LogLevelTreeModel getModel()
462     {
463         return model;
464     }
465
466     // }}}
467
// {{{ getTree
468

469     /**
470      * Get the JTree component of the view.
471      *
472      * @return The tree.
473      */

474     public final JTree JavaDoc getTree()
475     {
476         return tree;
477     }
478
479     // }}}
480
// {{{ fillMenu
481

482     /**
483      * Fill a JMenu with menu items for the LogLevelView.
484      *
485      * @param menu The JMenu to fill.
486      */

487     public void fillMenu(JMenu JavaDoc menu)
488     {
489         menu.add(removeAction);
490         menu.add(removeRecursiveAction);
491
492         menu.addSeparator();
493
494         menu.add(setERRAction);
495         menu.add(setERRDETAILAction);
496         menu.add(setWRNAction);
497         menu.add(setWRNDETAILAction);
498         menu.add(setMSGAction);
499         menu.add(setMSGDETAILAction);
500         menu.add(setMTDAction);
501         menu.add(setMTDDETAILAction);
502         menu.add(setDBGAction);
503         menu.add(setDBGDETAILAction);
504
505         menu.addSeparator();
506
507         menu.add(showSetLevelsAction);
508
509         menu.addSeparator();
510
511         JMenuItem JavaDoc mi = menu.add(editOptionsAction);
512         String JavaDoc mnemo = resources.getString
513             ("logLevelView.action.editOptions.mnemonic", null);
514         if (mnemo != null) {
515             mi.setMnemonic(mnemo.charAt(0));
516         }
517     }
518
519     /**
520      * Fill a JPopupMenu with menu items for the LogLevelView.
521      *
522      * @param menu The JPopupMenu to fill.
523      */

524     public void fillMenu(JPopupMenu JavaDoc menu)
525     {
526         menu.add(removeAction);
527         menu.add(removeRecursiveAction);
528
529         menu.addSeparator();
530
531         menu.add(setERRAction);
532         menu.add(setERRDETAILAction);
533         menu.add(setWRNAction);
534         menu.add(setWRNDETAILAction);
535         menu.add(setMSGAction);
536         menu.add(setMSGDETAILAction);
537         menu.add(setMTDAction);
538         menu.add(setMTDDETAILAction);
539         menu.add(setDBGAction);
540         menu.add(setDBGDETAILAction);
541
542         menu.addSeparator();
543
544         menu.add(showSetLevelsAction);
545
546         menu.addSeparator();
547
548         menu.add(editOptionsAction);
549     }
550
551     // }}}
552

553     //----------------------------------------------------------------------
554
// Configuration
555
//----------------------------------------------------------------------
556
// {{{ setResources
557

558     /**
559      * Override the default resources used by the LogLevelView. If this method
560      * is not called, the LogLevelView will use its default resource settings.
561      *
562      * @param rb ResourceBundle containing the resources to use.
563      */

564     public void setResources(ResourceBundle JavaDoc rb)
565     {
566         resources.addResources(rb);
567     }
568
569
570     // }}}
571
// {{{ showSetLevels
572

573     /**
574      * Expand or collapse tree nodes so that all nodes with a non-null level
575      * are displayed.
576      */

577     public void showSetLevels()
578     {
579         SwingUtilities.invokeLater(new Runnable JavaDoc () {
580             public void run() {
581                 showSetLevelsAction.actionPerformed(null);
582             }
583         });
584     }
585
586     // }}}
587

588     //----------------------------------------------------------------------
589
// Helper methods
590
//----------------------------------------------------------------------
591
// {{{ setupActions
592

593     /**
594      * Set up the actions for the LogLevelView.
595      */

596     private void setupActions()
597     {
598         // do this only once
599
if (removeAction == null) {
600             removeAction = new RemoveLevelAction (false);
601             setActionProperties(removeAction, "removeLevel");
602             removeRecursiveAction = new RemoveLevelAction (true);
603             setActionProperties(removeRecursiveAction, "removeLevelRecursive");
604
605             setERRAction = new ChangeLevelAction (Log.ERR);
606             setActionProperties(setERRAction, "setLevelERR");
607             setERRDETAILAction = new ChangeLevelAction (Log.ERRDETAIL);
608             setActionProperties(setERRDETAILAction, "setLevelERRDETAIL");
609             setWRNAction = new ChangeLevelAction (Log.WRN);
610             setActionProperties(setWRNAction, "setLevelWRN");
611             setWRNDETAILAction = new ChangeLevelAction (Log.WRNDETAIL);
612             setActionProperties(setWRNDETAILAction, "setLevelWRNDETAIL");
613             setMSGAction = new ChangeLevelAction (Log.MSG);
614             setActionProperties(setMSGAction, "setLevelMSG");
615             setMSGDETAILAction = new ChangeLevelAction (Log.MSGDETAIL);
616             setActionProperties(setMSGDETAILAction, "setLevelMSGDETAIL");
617             setMTDAction = new ChangeLevelAction (Log.MTD);
618             setActionProperties(setMTDAction, "setLevelMTD");
619             setMTDDETAILAction = new ChangeLevelAction (Log.MTDDETAIL);
620             setActionProperties(setMTDDETAILAction, "setLevelMTDDETAIL");
621             setDBGAction = new ChangeLevelAction (Log.DBG);
622             setActionProperties(setDBGAction, "setLevelDBG");
623             setDBGDETAILAction = new ChangeLevelAction (Log.DBGDETAIL);
624             setActionProperties(setDBGDETAILAction, "setLevelDBGDETAIL");
625
626             expandAllAction = new AbstractAction JavaDoc () {
627                 public void actionPerformed(ActionEvent JavaDoc e) {
628                     TreePath JavaDoc path = tree.getSelectionPath();
629                     if (path != null) {
630                         boolean excluded = ! logging;
631                         if (excluded) {
632                             Log.excludeThread();
633                         }
634                         try {
635                             SwingUtil.expandAll(tree, path);
636                         } finally {
637                             if (excluded) {
638                                 Log.includeThread();
639                             }
640                         }
641                     }
642                 }
643             };
644
645             collapseAllAction = new AbstractAction JavaDoc () {
646                 public void actionPerformed(ActionEvent JavaDoc e) {
647                     TreePath JavaDoc path = tree.getSelectionPath();
648                     if (path != null) {
649                         boolean excluded = ! logging;
650                         if (excluded) {
651                             Log.excludeThread();
652                         }
653                         try {
654                             SwingUtil.collapseAll(tree, path);
655                         } finally {
656                             if (excluded) {
657                                 Log.includeThread();
658                             }
659                         }
660                     }
661                 }
662             };
663
664             showSetLevelsAction = new ShowSetLevelsAction ();
665             setActionProperties(showSetLevelsAction, "showSetLevels");
666
667             editOptionsAction = new AbstractAction JavaDoc () {
668                 public void actionPerformed (ActionEvent JavaDoc e) {
669                     editOptions();
670                 }
671             };
672             setActionProperties(editOptionsAction,
673                                 "editOptions");
674
675         }
676     }
677
678     // }}}
679
// {{{ setActionProperties
680

681     /**
682      * Set name and icon for an action from the LogLevelView's resources.
683      *
684      * @param action The action to prepare.
685      * @param resource Identifier for the action's resources.
686      */

687     private void setActionProperties(Action JavaDoc action, String JavaDoc resource)
688     {
689         String JavaDoc name = resources.getString
690             ("logLevelView.action." + resource + ".name", null);
691         if (name != null) {
692             action.putValue(Action.NAME, name);
693         }
694
695         String JavaDoc iconName = resources.getString
696             ("logLevelView.action." + resource + ".icon", null);
697         if (iconName != null) {
698             Icon JavaDoc icon = resources.getIcon (iconName, null);
699             if (icon != null) {
700                 action.putValue(Action.SMALL_ICON, icon);
701             }
702         }
703     }
704
705     // }}}
706
// {{{ editOptions
707

708     /**
709      * Bring up a dialog to edit the options for the LogLevelView.
710      */

711     private void editOptions()
712     {
713         if (logging && logger.level >= Log.MTD) {
714             logger.log(Log.MTD, "editOptions()", "");
715         }
716
717         boolean excluded = ! logging;
718         if (excluded) {
719             Log.excludeThread();
720         }
721         try {
722             Frame JavaDoc frame;
723             Window JavaDoc win = SwingUtilities.windowForComponent(this);
724             if (win instanceof Frame JavaDoc) {
725                 frame = (Frame JavaDoc) win;
726             } else {
727                 // create a dummy parent
728
frame = new Frame JavaDoc();
729             }
730             if (optionDialog == null) {
731                 optionDialog = new OptionDialog
732                     (frame, resources.getString
733                          ("logLevelView.optionDialog.title", "MISSING"),
734                      model.getOptions(), "levelview");
735             } else {
736                 optionDialog.update(model.getOptions());
737             }
738             optionDialog.setLocationRelativeTo(this);
739             optionDialog.doModal();
740         } finally {
741             if (excluded) {
742                 Log.includeThread();
743             }
744         }
745     }
746
747     // }}}
748

749     //----------------------------------------------------------------------
750
// Action classes
751
//----------------------------------------------------------------------
752
// {{{ class ChangeLevelAction
753

754     /**
755      * Change the level of the selected tree nodes.
756      */

757     private class ChangeLevelAction
758         extends AbstractAction JavaDoc
759     {
760         /**
761          * The level to set on the selected nodes.
762          */

763         private int level;
764
765         // {{{ constructor
766

767         /**
768          * Create a new ChangeLevelAction.
769          *
770          * @param level The level to set on the selected nodes.
771          */

772         public ChangeLevelAction(int level)
773         {
774             this.level = level;
775         }
776
777         // }}}
778

779         // {{{ actionPerformed
780

781         /**
782          * Change the level of the selected tree nodes.
783          *
784          * @param e Ignored.
785          */

786         public void actionPerformed (ActionEvent JavaDoc e)
787         {
788             TreePath JavaDoc[] paths = tree.getSelectionPaths();
789
790             if (paths != null) {
791                 for (int i = 0; i < paths.length; i++) {
792                     model.setLogLevel(paths[i], level);
793                 }
794             }
795         }
796
797         // }}}
798
}
799
800     // }}}
801
// {{{ class RemoveLevelAction
802

803     /**
804      * Remove the level from the selected nodes of the tree.
805      */

806     private class RemoveLevelAction
807         extends AbstractAction JavaDoc
808     {
809         /**
810          * Whether levels should be removed recusively.
811          */

812         private boolean recurse;
813
814         // {{{ constructor
815

816         /**
817          * Create a new RemoveLevelAction.
818          *
819          * @param recurse Whether levels should be removed recusively.
820          */

821         public RemoveLevelAction(boolean recurse)
822         {
823             this.recurse = recurse;
824         }
825
826         // }}}
827

828         // {{{ actionPerformed
829

830         /**
831          * Remove the level from the selected nodes of the tree.
832          *
833          * @param e Ignored.
834          */

835         public void actionPerformed (ActionEvent JavaDoc e)
836         {
837             TreePath JavaDoc[] paths = tree.getSelectionPaths();
838
839             if (paths != null) {
840                 for (int i = 0; i < paths.length; i++) {
841                     model.removeLogLevel(paths[i], recurse);
842                 }
843             }
844         }
845
846         // }}}
847
}
848
849     // }}}
850
// {{{ class ShowSetLevelsAction
851

852     /**
853      * Expand or collapse tree nodes so that all nodes with a non-null level
854      * are displayed.
855      */

856     private class ShowSetLevelsAction
857         extends AbstractAction JavaDoc
858     {
859         // {{{ constructor
860

861         /**
862          * Create a new ShowSetLevelsAction.
863          */

864         public ShowSetLevelsAction()
865         {
866         }
867
868         // }}}
869

870         // {{{ actionPerformed
871

872         /**
873          * Expand/collapse tree nodes according to the levels.
874          *
875          * @param e Ignored.
876          */

877         public void actionPerformed (ActionEvent JavaDoc e)
878         {
879             boolean excluded = !logging;
880             if (excluded) {
881                 Log.excludeThread();
882             }
883             try {
884                 maybeExpandPath(new TreePath JavaDoc (new Object JavaDoc[] {model.getRoot()}));
885             } finally {
886                 if (excluded) {
887                     Log.includeThread();
888                 }
889             }
890         }
891
892         // }}}
893
// {{{ maybeExpandPath
894

895         /**
896          * Recursively expand/collapse the child nodes or a node while
897          * checking whether the node has any direct or indirect children with
898          * a non-null level.
899          *
900          * @param path Path to the start node.
901          *
902          * @return True if the node has children wit a non-null level.
903          */

904         private boolean maybeExpandPath(TreePath JavaDoc path)
905         {
906             if (logging && logger.level >= Log.MTD) {
907                 logger.log(Log.MTD, "maybeExpandPath(TreePath)",
908                            logger.level < Log.MTDDETAIL ? "" :
909                            "path: " + path);
910             }
911             Object JavaDoc node = path.getLastPathComponent();
912             boolean isLevel = model.getLevel(node) != null;
913             boolean expand = false;
914             if (model.isLeaf(node)) {
915                 return isLevel;
916             }
917
918             int num = model.getChildCount(node);
919             for (int i = 0; i < num; i++) {
920                 Object JavaDoc child = model.getChild(node, i);
921                 if (maybeExpandPath(path.pathByAddingChild(child))) {
922                     expand = true;
923                 }
924             }
925             if (logger.level >= Log.DBG) {
926                 logger.log(Log.DBG, "maybeExpandPath(TreePath)",
927                            "expand: " + expand);
928             }
929
930             if (expand) {
931                 tree.expandPath(path);
932             } else {
933                 tree.collapsePath(path);
934             }
935             return expand || isLevel;
936         }
937
938         // }}}
939
}
940
941     // }}}
942

943     //----------------------------------------------------------------------
944
// Popup menu listener
945
//----------------------------------------------------------------------
946
// {{{ class PopupListener
947

948     /**
949      * Listener for mouseclicks that brings up a popup menu.
950      */

951     class PopupListener
952         extends MouseAdapter JavaDoc
953     {
954         /**
955          * Notify the listener that a mouse button has been pressed.
956          *
957          * @param event Details aobut the event.
958          */

959         public void mousePressed(MouseEvent JavaDoc event)
960         {
961             maybePopup(event);
962         }
963
964         /**
965          * Notify the listener that a mouse button has been released.
966          *
967          * @param event Details aobut the event.
968          */

969         public void mouseReleased(MouseEvent JavaDoc event)
970         {
971             maybePopup(event);
972         }
973
974         /**
975          * Check if the event is a popup trigger and bring up a popup menu if
976          * required. If the click happens on a tree node that is selected, the
977          * selection doesn't change. If the node is not selected, it will be
978          * made the only selected node.
979          *
980          * @param event The MouseEvent containing the details.
981          */

982         private void maybePopup(MouseEvent JavaDoc event)
983         {
984             boolean excluded = !logging;
985             if (excluded) {
986                 Log.excludeThread();
987             }
988             try {
989                 if (event.isPopupTrigger()) {
990                     int row =
991                         tree.getRowForLocation(event.getX(), event.getY());
992                     if (row >= 0) {
993                         if (! tree.isRowSelected(row)) {
994                             tree.setSelectionRow(row);
995                         }
996                     } else if (tree.isSelectionEmpty()) {
997                         // no applicable nodes - ignore
998
return;
999                     }
1000                    SwingUtil.showPopup(popup, tree,
1001                                        event.getX(), event.getY(),
1002                                        false);
1003                }
1004            } finally {
1005                if (excluded) {
1006                    Log.includeThread();
1007                }
1008            }
1009        }
1010    }
1011
1012    // }}}
1013

1014    //----------------------------------------------------------------------
1015
// Renderer for the tree
1016
//----------------------------------------------------------------------
1017
// {{{ class Renderer
1018

1019    // {{{ static Renderer variables
1020

1021    /**
1022     * Index of the class icon.
1023     */

1024    private final static int CLASS = 10;
1025
1026    /**
1027     * Index of the package icon.
1028     */

1029    private final static int PACKAGE = 11;
1030
1031    /**
1032     * Index of the open package icon.
1033     */

1034    private final static int PACKAGE_OPEN = 12;
1035
1036    /**
1037     * The names of the icons resources.
1038     */

1039    private final static String JavaDoc iconNames[] = {
1040        "logLevelView.icon.err", "logLevelView.icon.errDetail",
1041        "logLevelView.icon.wrn", "logLevelView.icon.wrnDetail",
1042        "logLevelView.icon.msg", "logLevelView.icon.msgDetail",
1043        "logLevelView.icon.mtd", "logLevelView.icon.mtdDetail",
1044        "logLevelView.icon.dbg", "logLevelView.icon.dbgDetail",
1045        "logLevelView.icon.class",
1046        "logLevelView.icon.package", "logLevelView.icon.packageOpen"
1047    };
1048
1049    /**
1050     * The icons to render.
1051     */

1052    private final static Icon JavaDoc[] icons = new Icon JavaDoc[iconNames.length];
1053
1054    // }}}
1055

1056    /**
1057     * Renderer for the tree nodes. Sets package or class icons if no level is
1058     * set, or the level icon for the node's level.
1059     */

1060    private class Renderer
1061        extends WindowsTreeCellRenderer
1062    {
1063        // {{{ constructor
1064

1065        /**
1066         * Create a new Renderer.
1067         */

1068        public Renderer ()
1069        {
1070            initIcons();
1071        }
1072
1073        // }}}
1074

1075        // {{{ getTreeCellRendererComponent
1076

1077        /**
1078         * Get the renderer component for the tree node.
1079         *
1080         * @param tree The tree being drawn.
1081         * @param obj The tree node.
1082         * @param selected Whether the node is selected.
1083         * @param expanded Whether the node is expanded.
1084         * @param leaf Whether the node is a leaf.
1085         * @param row The node's row index.
1086         * @param hasFocus Whether the node has the focus.
1087         *
1088         * @return A label with the node's name and correct icon.
1089         */

1090        public Component JavaDoc getTreeCellRendererComponent
1091        (JTree JavaDoc tree, Object JavaDoc obj, boolean selected, boolean expanded,
1092         boolean leaf, int row, boolean hasFocus)
1093        {
1094            JLabel JavaDoc com = (JLabel JavaDoc) super.getTreeCellRendererComponent
1095                (tree, obj, selected, expanded, leaf, row, hasFocus);
1096
1097            Integer JavaDoc level = model.getLevel(obj);
1098
1099            int icon = leaf
1100                ? CLASS
1101                : (expanded ? PACKAGE_OPEN : PACKAGE);
1102            if (level == null) {
1103                com.setIcon(icons[icon]);
1104                return com;
1105            }
1106            int lvl = level.intValue();
1107            if (lvl < Log.ERR || lvl > Log.DBGDETAIL) {
1108                com.setIcon(icons[icon]);
1109            } else {
1110                com.setIcon(icons[level.intValue() - 1]);
1111            }
1112            return com;
1113        }
1114
1115        // }}}
1116
// {{{ initIcons
1117

1118        /**
1119         * Fetch the icons.
1120         */

1121        private void initIcons()
1122        {
1123            if (icons[0] == null) {
1124                for (int i = 0; i < icons.length; i++) {
1125                    icons[i] = resources.getIcon(iconNames[i], null);
1126                }
1127            }
1128        }
1129
1130        // }}}
1131
}
1132
1133    // }}}
1134
}
1135
Popular Tags