1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.log4j.chainsaw;
19
20 import java.awt.BorderLayout;
21 import java.awt.Component;
22 import java.awt.Container;
23 import java.awt.Dimension;
24 import java.awt.EventQueue;
25 import java.awt.Frame;
26 import java.awt.Point;
27 import java.awt.Toolkit;
28 import java.awt.event.ActionEvent;
29 import java.awt.event.ActionListener;
30 import java.awt.event.InputEvent;
31 import java.awt.event.KeyEvent;
32 import java.awt.event.MouseAdapter;
33 import java.awt.event.MouseEvent;
34 import java.awt.event.WindowAdapter;
35 import java.awt.event.WindowEvent;
36 import java.beans.PropertyChangeEvent;
37 import java.beans.PropertyChangeListener;
38 import java.io.File;
39 import java.io.IOException;
40 import java.lang.Thread.UncaughtExceptionHandler;
41 import java.lang.reflect.Method;
42 import java.net.MalformedURLException;
43 import java.net.URISyntaxException;
44 import java.net.URL;
45 import java.security.AllPermission;
46 import java.security.CodeSource;
47 import java.security.PermissionCollection;
48 import java.security.Permissions;
49 import java.security.Policy;
50 import java.util.ArrayList;
51 import java.util.Enumeration;
52 import java.util.HashMap;
53 import java.util.Iterator;
54 import java.util.List;
55 import java.util.Locale;
56 import java.util.Map;
57 import java.util.Set;
58
59 import javax.swing.AbstractAction;
60 import javax.swing.Action;
61 import javax.swing.BorderFactory;
62 import javax.swing.Box;
63 import javax.swing.Icon;
64 import javax.swing.ImageIcon;
65 import javax.swing.JButton;
66 import javax.swing.JComponent;
67 import javax.swing.JDialog;
68 import javax.swing.JEditorPane;
69 import javax.swing.JFrame;
70 import javax.swing.JOptionPane;
71 import javax.swing.JPanel;
72 import javax.swing.JPopupMenu;
73 import javax.swing.JScrollPane;
74 import javax.swing.JSplitPane;
75 import javax.swing.JToolBar;
76 import javax.swing.JWindow;
77 import javax.swing.KeyStroke;
78 import javax.swing.SwingConstants;
79 import javax.swing.SwingUtilities;
80 import javax.swing.ToolTipManager;
81 import javax.swing.UIManager;
82 import javax.swing.WindowConstants;
83 import javax.swing.event.ChangeEvent;
84 import javax.swing.event.ChangeListener;
85 import javax.swing.event.EventListenerList;
86 import javax.swing.event.HyperlinkEvent;
87 import javax.swing.event.HyperlinkListener;
88
89 import org.apache.log4j.Appender;
90 import org.apache.log4j.AppenderSkeleton;
91 import org.apache.log4j.Level;
92 import org.apache.log4j.LogManager;
93 import org.apache.log4j.Logger;
94 import org.apache.log4j.LoggerRepositoryExImpl;
95 import org.apache.log4j.chainsaw.color.RuleColorizer;
96 import org.apache.log4j.chainsaw.dnd.FileDnDTarget;
97 import org.apache.log4j.chainsaw.help.HelpManager;
98 import org.apache.log4j.chainsaw.help.Tutorial;
99 import org.apache.log4j.chainsaw.helper.SwingHelper;
100 import org.apache.log4j.chainsaw.icons.ChainsawIcons;
101 import org.apache.log4j.chainsaw.icons.LineIconFactory;
102 import org.apache.log4j.chainsaw.messages.MessageCenter;
103 import org.apache.log4j.chainsaw.osx.OSXIntegration;
104 import org.apache.log4j.chainsaw.plugins.PluginClassLoaderFactory;
105 import org.apache.log4j.chainsaw.prefs.LoadSettingsEvent;
106 import org.apache.log4j.chainsaw.prefs.MRUFileListPreferenceSaver;
107 import org.apache.log4j.chainsaw.prefs.SaveSettingsEvent;
108 import org.apache.log4j.chainsaw.prefs.SettingsListener;
109 import org.apache.log4j.chainsaw.prefs.SettingsManager;
110 import org.apache.log4j.chainsaw.receivers.ReceiversHelper;
111 import org.apache.log4j.chainsaw.receivers.ReceiversPanel;
112 import org.apache.log4j.chainsaw.vfs.VFSLogFilePatternReceiver;
113 import org.apache.log4j.net.SocketNodeEventListener;
114 import org.apache.log4j.plugins.Plugin;
115 import org.apache.log4j.plugins.PluginEvent;
116 import org.apache.log4j.plugins.PluginListener;
117 import org.apache.log4j.plugins.PluginRegistry;
118 import org.apache.log4j.plugins.Receiver;
119 import org.apache.log4j.rewrite.PropertyRewritePolicy;
120 import org.apache.log4j.rewrite.RewriteAppender;
121 import org.apache.log4j.rule.ExpressionRule;
122 import org.apache.log4j.rule.Rule;
123 import org.apache.log4j.spi.Decoder;
124 import org.apache.log4j.spi.LoggerRepository;
125 import org.apache.log4j.spi.LoggerRepositoryEx;
126 import org.apache.log4j.spi.LoggingEvent;
127 import org.apache.log4j.spi.RepositorySelector;
128 import org.apache.log4j.xml.DOMConfigurator;
129 import org.apache.log4j.xml.XMLDecoder;
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148 public class LogUI extends JFrame implements ChainsawViewer, SettingsListener {
149 private static final String MAIN_WINDOW_HEIGHT = "main.window.height";
150 private static final String MAIN_WINDOW_WIDTH = "main.window.width";
151 private static final String MAIN_WINDOW_Y = "main.window.y";
152 private static final String MAIN_WINDOW_X = "main.window.x";
153 private static ChainsawSplash splash;
154 private static final double DEFAULT_MAIN_RECEIVER_SPLIT_LOCATION = 0.85d;
155 private final JFrame preferencesFrame = new JFrame();
156 private boolean noReceiversDefined;
157 private ReceiversPanel receiversPanel;
158 private ChainsawTabbedPane tabbedPane;
159 private JToolBar toolbar;
160 private ChainsawStatusBar statusBar;
161 private ApplicationPreferenceModel applicationPreferenceModel;
162 private ApplicationPreferenceModelPanel applicationPreferenceModelPanel;
163 private final Map tableModelMap = new HashMap();
164 private final Map tableMap = new HashMap();
165 private final List filterableColumns = new ArrayList();
166 private final Map panelMap = new HashMap();
167 ChainsawAppenderHandler handler;
168 private ChainsawToolBarAndMenus tbms;
169 private ChainsawAbout aboutBox;
170 private final SettingsManager sm = SettingsManager.getInstance();
171 private final JFrame tutorialFrame = new JFrame("Chainsaw Tutorial");
172 private JSplitPane mainReceiverSplitPane;
173 private double lastMainReceiverSplitLocation = DEFAULT_MAIN_RECEIVER_SPLIT_LOCATION;
174 private final List identifierPanels = new ArrayList();
175 private int dividerSize;
176 private int cyclicBufferSize;
177 private static Logger logger;
178 private static String configurationURLAppArg;
179
180
181
182
183
184
185
186 private boolean isGUIFullyInitialized = false;
187 private Object initializationLock = new Object();
188
189
190
191
192
193
194 private Action shutdownAction = null;
195
196
197
198
199
200 private EventListenerList shutdownListenerList = new EventListenerList();
201 private WelcomePanel welcomePanel;
202
203 private static final Object repositorySelectorGuard = new Object();
204 private static final LoggerRepositoryExImpl repositoryExImpl = new LoggerRepositoryExImpl(LogManager.getLoggerRepository());
205
206 private PluginRegistry pluginRegistry;
207
208 private Map allColorizers = new HashMap();
209 private ReceiverConfigurationPanel receiverConfigurationPanel = new ReceiverConfigurationPanel();
210
211
212
213
214
215 public LogUI() {
216 super("Chainsaw");
217 setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
218
219 if (ChainsawIcons.WINDOW_ICON != null) {
220 setIconImage(new ImageIcon(ChainsawIcons.WINDOW_ICON).getImage());
221 }
222 }
223
224 private static final void showSplash(Frame owner) {
225 splash = new ChainsawSplash(owner);
226 SwingHelper.centerOnScreen(splash);
227 splash.setVisible(true);
228 }
229
230 private static final void removeSplash() {
231 if (splash != null) {
232 splash.setVisible(false);
233 splash.dispose();
234 }
235 }
236
237
238
239
240
241
242
243 public void addShutdownListener(ShutdownListener l) {
244 shutdownListenerList.add(ShutdownListener.class, l);
245 }
246
247
248
249
250
251
252
253 public void removeShutdownListener(ShutdownListener l) {
254 shutdownListenerList.remove(ShutdownListener.class, l);
255 }
256
257
258
259
260
261
262
263 public static void main(String[] args) {
264 if (args.length > 0) {
265 configurationURLAppArg = args[0];
266 }
267
268 if(OSXIntegration.IS_OSX) {
269 System.setProperty("apple.laf.useScreenMenuBar", "true");
270 }
271
272
273 LogManager.setRepositorySelector(new RepositorySelector() {
274
275 public LoggerRepository getLoggerRepository() {
276 return repositoryExImpl;
277 }}, repositorySelectorGuard);
278
279 final ApplicationPreferenceModel model = new ApplicationPreferenceModel();
280
281 SettingsManager.getInstance().configure(new ApplicationPreferenceModelSaver(model));
282
283 if (configurationURLAppArg != null) {
284 model.setBypassConfigurationURL(configurationURLAppArg);
285 }
286
287 EventQueue.invokeLater(new Runnable()
288 {
289 public void run()
290 {
291 String lookAndFeelClassName = model.getLookAndFeelClassName();
292 if (lookAndFeelClassName == null || lookAndFeelClassName.trim().equals("")) {
293 String osName = System.getProperty("os.name");
294 if (osName.toLowerCase(Locale.ENGLISH).startsWith("mac")) {
295
296 } else if (osName.toLowerCase(Locale.ENGLISH).startsWith("windows")) {
297 lookAndFeelClassName = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
298 model.setLookAndFeelClassName(lookAndFeelClassName);
299 } else if (osName.toLowerCase(Locale.ENGLISH).startsWith("linux")) {
300 lookAndFeelClassName = "com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
301 model.setLookAndFeelClassName(lookAndFeelClassName);
302 }
303 }
304
305 if (lookAndFeelClassName != null && !(lookAndFeelClassName.trim().equals(""))) {
306 loadLookAndFeelUsingPluginClassLoader(lookAndFeelClassName);
307 }
308 createChainsawGUI(model, null);
309 }
310 });
311 }
312
313
314
315
316
317
318
319
320
321
322 public static void createChainsawGUI(
323 ApplicationPreferenceModel model, Action newShutdownAction) {
324
325 if (model.isOkToRemoveSecurityManager()) {
326 MessageCenter
327 .getInstance()
328 .addMessage(
329 "User has authorised removal of Java Security Manager via preferences");
330 System.setSecurityManager(null);
331
332
333
334 Policy.setPolicy(new Policy() {
335
336 public void refresh() {
337 }
338
339 public PermissionCollection getPermissions(CodeSource codesource) {
340 Permissions perms = new Permissions();
341 perms.add(new AllPermission());
342 return (perms);
343 }
344 });
345 }
346
347 final LogUI logUI = new LogUI();
348 logUI.applicationPreferenceModel = model;
349
350 if (model.isShowSplash()) {
351 showSplash(logUI);
352 }
353 logUI.cyclicBufferSize = model.getCyclicBufferSize();
354 logUI.pluginRegistry = repositoryExImpl.getPluginRegistry();
355
356 logUI.handler = new ChainsawAppenderHandler();
357 logUI.handler.addEventBatchListener(logUI.new NewTabEventBatchReceiver());
358
359
360
361
362
363
364
365
366
367 logUI.ensureChainsawAppenderHandlerAdded();
368 logger = LogManager.getLogger(LogUI.class);
369
370
371
372 PropertyRewritePolicy policy = new PropertyRewritePolicy();
373 policy.setProperties("hostname=chainsaw,application=log,group=chainsaw");
374
375 RewriteAppender rewriteAppender = new RewriteAppender();
376 rewriteAppender.setRewritePolicy(policy);
377
378 Enumeration appenders = Logger.getLogger("org.apache").getAllAppenders();
379 if (!appenders.hasMoreElements()) {
380 appenders = Logger.getRootLogger().getAllAppenders();
381 }
382 while (appenders.hasMoreElements()) {
383 Appender nextAppender = (Appender)appenders.nextElement();
384 rewriteAppender.addAppender(nextAppender);
385 }
386 Logger.getLogger("org.apache").removeAllAppenders();
387 Logger.getLogger("org.apache").addAppender(rewriteAppender);
388 Logger.getLogger("org.apache").setAdditivity(false);
389
390
391 appenders = Logger.getLogger("httpclient").getAllAppenders();
392 if (!appenders.hasMoreElements()) {
393 appenders = Logger.getRootLogger().getAllAppenders();
394 }
395 while (appenders.hasMoreElements()) {
396 Appender nextAppender = (Appender)appenders.nextElement();
397 rewriteAppender.addAppender(nextAppender);
398 }
399 Logger.getLogger("httpclient").removeAllAppenders();
400 Logger.getLogger("httpclient").addAppender(rewriteAppender);
401 Logger.getLogger("httpclient").setAdditivity(false);
402
403
404 Logger.getLogger("org.apache.commons.vfs.cache").setLevel(Level.INFO);
405
406 Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
407 public void uncaughtException(Thread t, Throwable e) {
408 e.printStackTrace();
409 logger.error("Uncaught exception in thread " + t, e);
410 }
411 });
412
413 String config = configurationURLAppArg;
414 if (config != null) {
415 logger.info("Command-line configuration arg provided (overriding auto-configuration URL) - using: " + config);
416 } else {
417 config = model.getConfigurationURL();
418 }
419
420 if (config != null && (!config.trim().equals(""))) {
421 config = config.trim();
422 try {
423 URL configURL = new URL(config);
424 logger.info("Using '" + config + "' for auto-configuration");
425 logUI.loadConfigurationUsingPluginClassLoader(configURL);
426 } catch(MalformedURLException e) {
427 logger.error("Initial configuration - failed to convert config string to url", e);
428 } catch (IOException e) {
429 logger.error("Unable to access auto-configuration URL: " + config);
430 }
431 }
432
433
434
435 model.addPropertyChangeListener("configurationURL", new PropertyChangeListener() {
436 public void propertyChange(PropertyChangeEvent evt) {
437 String newConfiguration = evt.getNewValue().toString();
438 if (newConfiguration != null && !(newConfiguration.trim().equals(""))) {
439 newConfiguration = newConfiguration.trim();
440 try {
441 logger.info("loading updated configuration: " + newConfiguration);
442 URL newConfigurationURL = new URL(newConfiguration);
443 File file = new File(newConfigurationURL.toURI());
444 if (file.exists()) {
445 logUI.loadConfigurationUsingPluginClassLoader(newConfigurationURL);
446 } else {
447 logger.info("Updated configuration but file does not exist");
448 }
449 } catch (MalformedURLException e) {
450 logger.error("Updated configuration - failed to convert config string to URL", e);
451 }
452 catch (URISyntaxException e)
453 {
454 logger.error("Updated configuration - failed to convert config string to URL", e);
455 }
456 }
457 }});
458
459 LogManager.getRootLogger().setLevel(Level.TRACE);
460 EventQueue.invokeLater(new Runnable() {
461 public void run() {
462 logUI.activateViewer();
463 }
464 });
465
466 logger.info("SecurityManager is now: " + System.getSecurityManager());
467
468 if (newShutdownAction != null) {
469 logUI.setShutdownAction(newShutdownAction);
470 } else {
471 logUI.setShutdownAction(
472 new AbstractAction() {
473 public void actionPerformed(ActionEvent e) {
474 System.exit(0);
475 }
476 });
477 }
478 }
479
480
481
482
483
484
485
486 public void activateViewer(ChainsawAppender appender) {
487
488 if(OSXIntegration.IS_OSX) {
489 System.setProperty("apple.laf.useScreenMenuBar", "true");
490 }
491
492 LogManager.setRepositorySelector(new RepositorySelector() {
493
494 public LoggerRepository getLoggerRepository() {
495 return repositoryExImpl;
496 }}, repositorySelectorGuard);
497
498
499 LogManager.getRootLogger().setLevel(Level.TRACE);
500
501 final ApplicationPreferenceModel model = new ApplicationPreferenceModel();
502 SettingsManager.getInstance().configure(new ApplicationPreferenceModelSaver(model));
503
504 cyclicBufferSize = model.getCyclicBufferSize();
505
506 handler = new ChainsawAppenderHandler(appender);
507 handler.addEventBatchListener(new NewTabEventBatchReceiver());
508
509 logger = LogManager.getLogger(LogUI.class);
510
511 setShutdownAction(
512 new AbstractAction() {
513 public void actionPerformed(ActionEvent e) {
514 }
515 });
516
517 applicationPreferenceModel = new ApplicationPreferenceModel();
518
519 SettingsManager.getInstance().configure(new ApplicationPreferenceModelSaver(model));
520
521 EventQueue.invokeLater(new Runnable()
522 {
523 public void run()
524 {
525 loadLookAndFeelUsingPluginClassLoader(model.getLookAndFeelClassName());
526 createChainsawGUI(model, null);
527 getApplicationPreferenceModel().apply(model);
528 activateViewer();
529 }
530 });
531 }
532
533
534
535
536
537
538 private void initGUI() {
539
540 setupHelpSystem();
541 statusBar = new ChainsawStatusBar(this);
542 setupReceiverPanel();
543
544 setToolBarAndMenus(new ChainsawToolBarAndMenus(this));
545 toolbar = getToolBarAndMenus().getToolbar();
546 setJMenuBar(getToolBarAndMenus().getMenubar());
547
548 setTabbedPane(new ChainsawTabbedPane());
549 getSettingsManager().addSettingsListener(getTabbedPane());
550 getSettingsManager().configure(getTabbedPane());
551
552
553
554
555 FileDnDTarget dnDTarget = new FileDnDTarget(tabbedPane);
556 dnDTarget.addPropertyChangeListener("fileList", new PropertyChangeListener() {
557
558 public void propertyChange(PropertyChangeEvent evt) {
559 final List fileList = (List) evt.getNewValue();
560
561 Thread thread = new Thread(new Runnable() {
562
563
564 public void run() {
565 logger.debug("Loading files: " + fileList);
566 for (Iterator iter = fileList.iterator(); iter.hasNext();) {
567 File file = (File) iter.next();
568 final Decoder decoder = new XMLDecoder();
569 try {
570 getStatusBar().setMessage("Loading " + file.getAbsolutePath() + "...");
571 FileLoadAction.importURL(handler, decoder, file
572 .getName(), file.toURI().toURL());
573 } catch (Exception e) {
574 String errorMsg = "Failed to import a file";
575 logger.error(errorMsg, e);
576 getStatusBar().setMessage(errorMsg);
577 }
578 }
579
580 }});
581
582 thread.setPriority(Thread.MIN_PRIORITY);
583 thread.start();
584
585 }});
586
587 applicationPreferenceModelPanel = new ApplicationPreferenceModelPanel(applicationPreferenceModel);
588
589 applicationPreferenceModelPanel.setOkCancelActionListener(
590 new ActionListener() {
591 public void actionPerformed(ActionEvent e) {
592 preferencesFrame.setVisible(false);
593 }
594 });
595 KeyStroke escape = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false);
596 Action closeAction = new AbstractAction() {
597 public void actionPerformed(ActionEvent e) {
598 preferencesFrame.setVisible(false);
599 }
600 };
601 preferencesFrame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(escape, "ESCAPE"); preferencesFrame.getRootPane().
602 getActionMap().put("ESCAPE", closeAction);
603
604 OSXIntegration.init(this);
605
606 }
607
608 private void initPlugins(PluginRegistry pluginRegistry) {
609 pluginRegistry.addPluginListener(
610 new PluginListener() {
611 public void pluginStarted(PluginEvent e) {
612 if (e.getPlugin() instanceof JComponent) {
613 JComponent plugin = (JComponent) e.getPlugin();
614 getTabbedPane().addANewTab(plugin.getName(), plugin, null, null);
615 getPanelMap().put(plugin.getName(), plugin);
616 }
617 }
618
619 public void pluginStopped(PluginEvent e) {
620
621 }
622 });
623
624
625
626
627
628
629 try {
630 Class pluginClass = Class.forName("org.apache.log4j.chainsaw.zeroconf.ZeroConfPlugin");
631 Plugin plugin = (Plugin) pluginClass.newInstance();
632 pluginRegistry.addPlugin(plugin);
633 plugin.activateOptions();
634 MessageCenter.getInstance().getLogger().info("Looks like ZeroConf is available... WooHoo!");
635 } catch (Throwable e) {
636 MessageCenter.getInstance().getLogger().error("Doesn't look like ZeroConf is available", e);
637 }
638 }
639
640 private void setupReceiverPanel() {
641 receiversPanel = new ReceiversPanel();
642 receiversPanel.addPropertyChangeListener(
643 "visible",
644 new PropertyChangeListener() {
645 public void propertyChange(PropertyChangeEvent evt) {
646 getApplicationPreferenceModel().setReceivers(
647 ((Boolean) evt.getNewValue()).booleanValue());
648 }
649 });
650 }
651
652
653
654
655
656 private void setupHelpSystem() {
657 welcomePanel = new WelcomePanel();
658
659 JToolBar tb = welcomePanel.getToolbar();
660
661
662 tb.add(
663 new SmallButton(
664 new AbstractAction("Tutorial", new ImageIcon(ChainsawIcons.HELP)) {
665 public void actionPerformed(ActionEvent e) {
666 setupTutorial();
667 }
668 }));
669 tb.addSeparator();
670
671 final Action exampleConfigAction =
672 new AbstractAction("View example Receiver configuration") {
673 public void actionPerformed(ActionEvent e) {
674 HelpManager.getInstance().setHelpURL(
675 ChainsawConstants.EXAMPLE_CONFIG_URL);
676 }
677 };
678
679 exampleConfigAction.putValue(
680 Action.SHORT_DESCRIPTION,
681 "Displays an example Log4j configuration file with several Receivers defined.");
682
683 JButton exampleButton = new SmallButton(exampleConfigAction);
684 tb.add(exampleButton);
685
686 tb.add(Box.createHorizontalGlue());
687
688
689
690
691
692 HelpManager.getInstance().addPropertyChangeListener(
693 "helpURL",
694 new PropertyChangeListener() {
695 public void propertyChange(PropertyChangeEvent evt) {
696 URL newURL = (URL) evt.getNewValue();
697
698 if (newURL != null) {
699 welcomePanel.setURL(newURL);
700 ensureWelcomePanelVisible();
701 }
702 }
703 });
704 }
705
706 private void ensureWelcomePanelVisible() {
707
708 if(!getTabbedPane().containsWelcomePanel()) {
709 addWelcomePanel();
710 }
711 getTabbedPane().setSelectedComponent(welcomePanel);
712 }
713
714
715
716
717
718
719
720
721 public void loadSettings(LoadSettingsEvent event) {
722 setLocation(
723 event.asInt(LogUI.MAIN_WINDOW_X), event.asInt(LogUI.MAIN_WINDOW_Y));
724 int width = event.asInt(LogUI.MAIN_WINDOW_WIDTH);
725 int height = event.asInt(LogUI.MAIN_WINDOW_HEIGHT);
726 if (width == -1 && height == -1) {
727 width = Toolkit.getDefaultToolkit().getScreenSize().width;
728 height = Toolkit.getDefaultToolkit().getScreenSize().height;
729 setSize(width, height);
730 setExtendedState(getExtendedState() | MAXIMIZED_BOTH);
731 } else {
732 setSize(width, height);
733 }
734
735 getToolBarAndMenus().stateChange();
736 RuleColorizer colorizer = new RuleColorizer();
737 colorizer.loadColorSettings(ChainsawConstants.DEFAULT_COLOR_RULE_NAME);
738 allColorizers.put(ChainsawConstants.DEFAULT_COLOR_RULE_NAME, colorizer);
739 if (event.getSetting("SavedConfig.logFormat") != null) {
740 receiverConfigurationPanel.getModel().setLogFormat(event.getSetting("SavedConfig.logFormat"));
741 }
742 }
743
744
745
746
747
748
749
750 public void saveSettings(SaveSettingsEvent event) {
751 event.saveSetting(LogUI.MAIN_WINDOW_X, (int) getLocation().getX());
752 event.saveSetting(LogUI.MAIN_WINDOW_Y, (int) getLocation().getY());
753
754 event.saveSetting(LogUI.MAIN_WINDOW_WIDTH, getWidth());
755 event.saveSetting(LogUI.MAIN_WINDOW_HEIGHT, getHeight());
756 RuleColorizer colorizer = (RuleColorizer) allColorizers.get(ChainsawConstants.DEFAULT_COLOR_RULE_NAME);
757 colorizer.saveColorSettings(ChainsawConstants.DEFAULT_COLOR_RULE_NAME);
758 if (receiverConfigurationPanel.getModel().getLogFormat() != null ) {
759 event.saveSetting("SavedConfig.logFormat", receiverConfigurationPanel.getModel().getLogFormat());
760 }
761 }
762
763
764
765
766
767
768 public void activateViewer() {
769 LoggerRepository repo = LogManager.getLoggerRepository();
770 if (repo instanceof LoggerRepositoryEx) {
771 this.pluginRegistry = ((LoggerRepositoryEx) repo).getPluginRegistry();
772 }
773 initGUI();
774
775 initPrefModelListeners();
776
777
778
779
780
781 MessageCenter.getInstance().getLogger().addAppender(
782 new AppenderSkeleton() {
783 protected void append(LoggingEvent event) {
784 getStatusBar().setMessage(event.getMessage().toString());
785 }
786
787 public void close() {
788 }
789
790 public boolean requiresLayout() {
791 return false;
792 }
793 });
794
795
796
797 initSocketConnectionListener();
798
799 if (pluginRegistry.getPlugins(Receiver.class).size() == 0) {
800 noReceiversDefined = true;
801 }
802
803 getFilterableColumns().add(ChainsawConstants.LEVEL_COL_NAME);
804 getFilterableColumns().add(ChainsawConstants.LOGGER_COL_NAME);
805 getFilterableColumns().add(ChainsawConstants.THREAD_COL_NAME);
806 getFilterableColumns().add(ChainsawConstants.NDC_COL_NAME);
807 getFilterableColumns().add(ChainsawConstants.PROPERTIES_COL_NAME);
808 getFilterableColumns().add(ChainsawConstants.CLASS_COL_NAME);
809 getFilterableColumns().add(ChainsawConstants.METHOD_COL_NAME);
810 getFilterableColumns().add(ChainsawConstants.FILE_COL_NAME);
811 getFilterableColumns().add(ChainsawConstants.NONE_COL_NAME);
812
813 JPanel panePanel = new JPanel();
814 panePanel.setLayout(new BorderLayout(2, 2));
815
816 getContentPane().setLayout(new BorderLayout());
817
818 getTabbedPane().addChangeListener(getToolBarAndMenus());
819 getTabbedPane().addChangeListener(new ChangeListener()
820 {
821 public void stateChanged(ChangeEvent e)
822 {
823 LogPanel thisLogPanel = getCurrentLogPanel();
824 if (thisLogPanel != null)
825 {
826 thisLogPanel.updateStatusBar();
827 }
828 }
829 });
830
831 KeyStroke ksRight =
832 KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
833 KeyStroke ksLeft =
834 KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
835 KeyStroke ksGotoLine =
836 KeyStroke.getKeyStroke(KeyEvent.VK_G, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
837
838 getTabbedPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
839 ksRight, "MoveRight");
840 getTabbedPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
841 ksLeft, "MoveLeft");
842 getTabbedPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
843 ksGotoLine, "GotoLine");
844
845 Action moveRight =
846 new AbstractAction() {
847 public void actionPerformed(ActionEvent e) {
848 int temp = getTabbedPane().getSelectedIndex();
849 ++temp;
850
851 if (temp != getTabbedPane().getTabCount()) {
852 getTabbedPane().setSelectedTab(temp);
853 }
854 }
855 };
856
857 Action moveLeft =
858 new AbstractAction() {
859 public void actionPerformed(ActionEvent e) {
860 int temp = getTabbedPane().getSelectedIndex();
861 --temp;
862
863 if (temp > -1) {
864 getTabbedPane().setSelectedTab(temp);
865 }
866 }
867 };
868
869 Action gotoLine =
870 new AbstractAction() {
871 public void actionPerformed(ActionEvent e) {
872 String inputLine = JOptionPane.showInputDialog(LogUI.this, "Enter the line number to go:", "Goto Line", -1);
873 try {
874 int lineNumber = Integer.parseInt(inputLine);
875 int row = getCurrentLogPanel().setSelectedEvent(lineNumber);
876 if (row == -1) {
877 JOptionPane.showMessageDialog(LogUI.this, "You have entered an invalid line number", "Error", 0);
878 }
879 } catch (NumberFormatException nfe) {
880 JOptionPane.showMessageDialog(LogUI.this, "You have entered an invalid line number", "Error", 0);
881 }
882 }
883 };
884
885
886 getTabbedPane().getActionMap().put("MoveRight", moveRight);
887 getTabbedPane().getActionMap().put("MoveLeft", moveLeft);
888 getTabbedPane().getActionMap().put("GotoLine", gotoLine);
889
890
891
892
893
894 getTabbedPane().addMouseListener(
895 new MouseAdapter() {
896 public void mouseClicked(MouseEvent e) {
897 super.mouseClicked(e);
898
899 if (
900 (e.getClickCount() > 1)
901 && ((e.getModifiers() & InputEvent.BUTTON1_MASK) > 0)) {
902 int tabIndex = getTabbedPane().getSelectedIndex();
903
904 if (
905 (tabIndex != -1)
906 && (tabIndex == getTabbedPane().getSelectedIndex())) {
907 LogPanel logPanel = getCurrentLogPanel();
908
909 if (logPanel != null) {
910 logPanel.undock();
911 }
912 }
913 }
914 }
915 });
916
917 panePanel.add(getTabbedPane());
918 addWelcomePanel();
919
920 getContentPane().add(toolbar, BorderLayout.NORTH);
921 getContentPane().add(statusBar, BorderLayout.SOUTH);
922
923 mainReceiverSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panePanel, receiversPanel);
924 dividerSize = mainReceiverSplitPane.getDividerSize();
925 mainReceiverSplitPane.setDividerLocation(-1);
926
927 getContentPane().add(mainReceiverSplitPane, BorderLayout.CENTER);
928
929
930
931
932
933
934 initPlugins(pluginRegistry);
935
936 mainReceiverSplitPane.setResizeWeight(1.0);
937 addWindowListener(
938 new WindowAdapter() {
939 public void windowClosing(WindowEvent event) {
940 exit();
941 }
942 });
943 preferencesFrame.setTitle("'Application-wide Preferences");
944 preferencesFrame.setIconImage(
945 ((ImageIcon) ChainsawIcons.ICON_PREFERENCES).getImage());
946 preferencesFrame.getContentPane().add(applicationPreferenceModelPanel);
947
948 preferencesFrame.setSize(750, 520);
949
950 Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
951 preferencesFrame.setLocation(
952 new Point(
953 (screenDimension.width / 2) - (preferencesFrame.getSize().width / 2),
954 (screenDimension.height / 2) - (preferencesFrame.getSize().height / 2)));
955
956 pack();
957
958 final JPopupMenu tabPopup = new JPopupMenu();
959 final Action hideCurrentTabAction =
960 new AbstractAction("Hide") {
961 public void actionPerformed(ActionEvent e) {
962 Component selectedComp = getTabbedPane().getSelectedComponent();
963 if (selectedComp instanceof LogPanel) {
964 displayPanel(getCurrentLogPanel().getIdentifier(), false);
965 tbms.stateChange();
966 } else {
967 getTabbedPane().remove(selectedComp);
968 }
969 }
970 };
971
972 final Action hideOtherTabsAction =
973 new AbstractAction("Hide Others") {
974 public void actionPerformed(ActionEvent e) {
975 Component selectedComp = getTabbedPane().getSelectedComponent();
976 String currentName;
977 if (selectedComp instanceof LogPanel) {
978 currentName = getCurrentLogPanel().getIdentifier();
979 } else if (selectedComp instanceof WelcomePanel) {
980 currentName = ChainsawTabbedPane.WELCOME_TAB;
981 } else {
982 currentName = ChainsawTabbedPane.ZEROCONF;
983 }
984
985 int count = getTabbedPane().getTabCount();
986 int index = 0;
987
988 for (int i = 0; i < count; i++) {
989 String name = getTabbedPane().getTitleAt(index);
990
991 if (
992 getPanelMap().keySet().contains(name)
993 && !name.equals(currentName)) {
994 displayPanel(name, false);
995 tbms.stateChange();
996 } else {
997 index++;
998 }
999 }
1000 }
1001 };
1002
1003 Action showHiddenTabsAction =
1004 new AbstractAction("Show All Hidden") {
1005 public void actionPerformed(ActionEvent e) {
1006 for (Iterator iter = getPanels().entrySet().iterator();
1007 iter.hasNext();) {
1008 Map.Entry entry = (Map.Entry)iter.next();
1009 Boolean docked = (Boolean)entry.getValue();
1010 if (docked.booleanValue()) {
1011 String identifier = (String) entry.getKey();
1012 int count = getTabbedPane().getTabCount();
1013 boolean found = false;
1014
1015 for (int i = 0; i < count; i++) {
1016 String name = getTabbedPane().getTitleAt(i);
1017
1018 if (name.equals(identifier)) {
1019 found = true;
1020
1021 break;
1022 }
1023 }
1024
1025 if (!found) {
1026 displayPanel(identifier, true);
1027 tbms.stateChange();
1028 }
1029 }
1030 }
1031 }
1032 };
1033
1034 tabPopup.add(hideCurrentTabAction);
1035 tabPopup.add(hideOtherTabsAction);
1036 tabPopup.addSeparator();
1037 tabPopup.add(showHiddenTabsAction);
1038
1039 final PopupListener tabPopupListener = new PopupListener(tabPopup);
1040 getTabbedPane().addMouseListener(tabPopupListener);
1041
1042 this.handler.addPropertyChangeListener(
1043 "dataRate",
1044 new PropertyChangeListener() {
1045 public void propertyChange(PropertyChangeEvent evt) {
1046 double dataRate = ((Double) evt.getNewValue()).doubleValue();
1047 statusBar.setDataRate(dataRate);
1048 }
1049 });
1050
1051 getSettingsManager().addSettingsListener(this);
1052 getSettingsManager().addSettingsListener(MRUFileListPreferenceSaver.getInstance());
1053 getSettingsManager().addSettingsListener(receiversPanel);
1054 try {
1055
1056 getSettingsManager().loadSettings();
1057 } catch (Exception e) {
1058 e.printStackTrace();
1059 }
1060
1061
1062 getSettingsManager().addSettingsListener(new ApplicationPreferenceModelSaver(applicationPreferenceModel));
1063
1064 setVisible(true);
1065
1066 if (applicationPreferenceModel.isReceivers()) {
1067 showReceiverPanel();
1068 } else {
1069 hideReceiverPanel();
1070 }
1071
1072 removeSplash();
1073
1074 synchronized (initializationLock) {
1075 isGUIFullyInitialized = true;
1076 initializationLock.notifyAll();
1077 }
1078
1079 if (
1080 noReceiversDefined
1081 && applicationPreferenceModel.isShowNoReceiverWarning()) {
1082 SwingHelper.invokeOnEDT(new Runnable() {
1083 public void run() {
1084 showReceiverConfigurationPanel();
1085 }
1086 });
1087 }
1088
1089 Container container = tutorialFrame.getContentPane();
1090 final JEditorPane tutorialArea = new JEditorPane();
1091 tutorialArea.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
1092 tutorialArea.setEditable(false);
1093 container.setLayout(new BorderLayout());
1094
1095 try {
1096 tutorialArea.setPage(ChainsawConstants.TUTORIAL_URL);
1097 JTextComponentFormatter.applySystemFontAndSize(tutorialArea);
1098
1099 container.add(new JScrollPane(tutorialArea), BorderLayout.CENTER);
1100 } catch (Exception e) {
1101 MessageCenter.getInstance().getLogger().error(
1102 "Error occurred loading the Tutorial", e);
1103 }
1104
1105 tutorialFrame.setIconImage(new ImageIcon(ChainsawIcons.HELP).getImage());
1106 tutorialFrame.setSize(new Dimension(640, 480));
1107
1108 final Action startTutorial =
1109 new AbstractAction(
1110 "Start Tutorial", new ImageIcon(ChainsawIcons.ICON_RESUME_RECEIVER)) {
1111 public void actionPerformed(ActionEvent e) {
1112 if (
1113 JOptionPane.showConfirmDialog(
1114 null,
1115 "This will start 3 \"Generator\" receivers for use in the Tutorial. Is that ok?",
1116 "Confirm", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
1117 new Thread(new Tutorial()).start();
1118 putValue("TutorialStarted", Boolean.TRUE);
1119 } else {
1120 putValue("TutorialStarted", Boolean.FALSE);
1121 }
1122 }
1123 };
1124
1125 final Action stopTutorial =
1126 new AbstractAction(
1127 "Stop Tutorial", new ImageIcon(ChainsawIcons.ICON_STOP_RECEIVER)) {
1128 public void actionPerformed(ActionEvent e) {
1129 if (
1130 JOptionPane.showConfirmDialog(
1131 null,
1132 "This will stop all of the \"Generator\" receivers used in the Tutorial, but leave any other Receiver untouched. Is that ok?",
1133 "Confirm", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
1134 new Thread(
1135 new Runnable() {
1136 public void run() {
1137 LoggerRepository repo = LogManager.getLoggerRepository();
1138 if (repo instanceof LoggerRepositoryEx) {
1139 PluginRegistry pluginRegistry = ((LoggerRepositoryEx) repo).getPluginRegistry();
1140 List list = pluginRegistry.getPlugins(Generator.class);
1141
1142 for (Iterator iter = list.iterator(); iter.hasNext();) {
1143 Plugin plugin = (Plugin) iter.next();
1144 pluginRegistry.stopPlugin(plugin.getName());
1145 }
1146 }
1147 }
1148 }).start();
1149 setEnabled(false);
1150 startTutorial.putValue("TutorialStarted", Boolean.FALSE);
1151 }
1152 }
1153 };
1154
1155 stopTutorial.putValue(
1156 Action.SHORT_DESCRIPTION,
1157 "Removes all of the Tutorials Generator Receivers, leaving all other Receivers untouched");
1158 startTutorial.putValue(
1159 Action.SHORT_DESCRIPTION,
1160 "Begins the Tutorial, starting up some Generator Receivers so you can see Chainsaw in action");
1161 stopTutorial.setEnabled(false);
1162
1163 final SmallToggleButton startButton = new SmallToggleButton(startTutorial);
1164 PropertyChangeListener pcl =
1165 new PropertyChangeListener() {
1166 public void propertyChange(PropertyChangeEvent evt) {
1167 stopTutorial.setEnabled(
1168 ((Boolean) startTutorial.getValue("TutorialStarted")).equals(
1169 Boolean.TRUE));
1170 startButton.setSelected(stopTutorial.isEnabled());
1171 }
1172 };
1173
1174 startTutorial.addPropertyChangeListener(pcl);
1175 stopTutorial.addPropertyChangeListener(pcl);
1176
1177 pluginRegistry.addPluginListener(
1178 new PluginListener() {
1179 public void pluginStarted(PluginEvent e) {
1180 }
1181
1182 public void pluginStopped(PluginEvent e) {
1183 List list = pluginRegistry.getPlugins(Generator.class);
1184
1185 if (list.size() == 0) {
1186 startTutorial.putValue("TutorialStarted", Boolean.FALSE);
1187 }
1188 }
1189 });
1190
1191 final SmallButton stopButton = new SmallButton(stopTutorial);
1192
1193 final JToolBar tutorialToolbar = new JToolBar();
1194 tutorialToolbar.setFloatable(false);
1195 tutorialToolbar.add(startButton);
1196 tutorialToolbar.add(stopButton);
1197 container.add(tutorialToolbar, BorderLayout.NORTH);
1198 tutorialArea.addHyperlinkListener(
1199 new HyperlinkListener() {
1200 public void hyperlinkUpdate(HyperlinkEvent e) {
1201 if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
1202 if (e.getDescription().equals("StartTutorial")) {
1203 startTutorial.actionPerformed(null);
1204 } else if (e.getDescription().equals("StopTutorial")) {
1205 stopTutorial.actionPerformed(null);
1206 } else {
1207 try {
1208 tutorialArea.setPage(e.getURL());
1209 } catch (IOException e1) {
1210 MessageCenter.getInstance().getLogger().error(
1211 "Failed to change the URL for the Tutorial", e1);
1212 }
1213 }
1214 }
1215 }
1216 });
1217
1218
1219
1220
1221
1222
1223 if (!getTabbedPane().tabSetting.isWelcome()){
1224 displayPanel(ChainsawTabbedPane.WELCOME_TAB, false);
1225 }
1226 if (!getTabbedPane().tabSetting.isZeroconf()){
1227 displayPanel(ChainsawTabbedPane.ZEROCONF, false);
1228 }
1229 tbms.stateChange();
1230
1231 }
1232
1233
1234
1235
1236 private void showReceiverPanel() {
1237 mainReceiverSplitPane.setDividerSize(dividerSize);
1238 mainReceiverSplitPane.setDividerLocation(lastMainReceiverSplitLocation);
1239 receiversPanel.setVisible(true);
1240 mainReceiverSplitPane.repaint();
1241 }
1242
1243
1244
1245
1246 private void hideReceiverPanel() {
1247
1248 int currentSize = mainReceiverSplitPane.getWidth() - mainReceiverSplitPane.getDividerSize();
1249 if (mainReceiverSplitPane.getDividerLocation() > -1) {
1250 if (!(((mainReceiverSplitPane.getDividerLocation() + 1) == currentSize)
1251 || ((mainReceiverSplitPane.getDividerLocation() - 1) == 0))) {
1252 lastMainReceiverSplitLocation = ((double) mainReceiverSplitPane
1253 .getDividerLocation() / currentSize);
1254 }
1255 }
1256 mainReceiverSplitPane.setDividerSize(0);
1257 receiversPanel.setVisible(false);
1258 mainReceiverSplitPane.repaint();
1259 }
1260
1261 private void initSocketConnectionListener() {
1262 final SocketNodeEventListener socketListener =
1263 new SocketNodeEventListener() {
1264 public void socketOpened(String remoteInfo) {
1265 statusBar.remoteConnectionReceived(remoteInfo);
1266 }
1267
1268 public void socketClosedEvent(Exception e) {
1269 MessageCenter.getInstance().getLogger().info(
1270 "Connection lost! :: " + e.getMessage());
1271 }
1272 };
1273
1274 PluginListener pluginListener =
1275 new PluginListener() {
1276 public void pluginStarted(PluginEvent e) {
1277 MessageCenter.getInstance().getLogger().info(
1278 e.getPlugin().getName() + " started!");
1279
1280 Method method = getAddListenerMethod(e.getPlugin());
1281
1282 if (method != null) {
1283 try {
1284 method.invoke(e.getPlugin(), new Object[] { socketListener });
1285 } catch (Exception ex) {
1286 MessageCenter.getInstance().getLogger().error(
1287 "Failed to add a SocketNodeEventListener", ex);
1288 }
1289 }
1290 }
1291
1292 Method getRemoveListenerMethod(Plugin p) {
1293 try {
1294 return p.getClass().getMethod(
1295 "removeSocketNodeEventListener",
1296 new Class[] { SocketNodeEventListener.class });
1297 } catch (Exception e) {
1298 return null;
1299 }
1300 }
1301
1302 Method getAddListenerMethod(Plugin p) {
1303 try {
1304 return p.getClass().getMethod(
1305 "addSocketNodeEventListener",
1306 new Class[] { SocketNodeEventListener.class });
1307 } catch (Exception e) {
1308 return null;
1309 }
1310 }
1311
1312 public void pluginStopped(PluginEvent e) {
1313 Method method = getRemoveListenerMethod(e.getPlugin());
1314
1315 if (method != null) {
1316 try {
1317 method.invoke(e.getPlugin(), new Object[] { socketListener });
1318 } catch (Exception ex) {
1319 MessageCenter.getInstance().getLogger().error(
1320 "Failed to remove SocketNodeEventListener", ex);
1321 }
1322 }
1323
1324 MessageCenter.getInstance().getLogger().info(
1325 e.getPlugin().getName() + " stopped!");
1326 }
1327 };
1328
1329 pluginRegistry.addPluginListener(pluginListener);
1330 }
1331
1332 private void initPrefModelListeners() {
1333 applicationPreferenceModel.addPropertyChangeListener(
1334 "identifierExpression",
1335 new PropertyChangeListener() {
1336 public void propertyChange(PropertyChangeEvent evt) {
1337 handler.setIdentifierExpression(evt.getNewValue().toString());
1338 }
1339 });
1340 handler.setIdentifierExpression(applicationPreferenceModel.getIdentifierExpression());
1341
1342
1343 applicationPreferenceModel.addPropertyChangeListener(
1344 "toolTipDisplayMillis",
1345 new PropertyChangeListener() {
1346 public void propertyChange(PropertyChangeEvent evt) {
1347 ToolTipManager.sharedInstance().setDismissDelay(
1348 ((Integer) evt.getNewValue()).intValue());
1349 }
1350 });
1351 ToolTipManager.sharedInstance().setDismissDelay(
1352 applicationPreferenceModel.getToolTipDisplayMillis());
1353
1354 applicationPreferenceModel.addPropertyChangeListener(
1355 "responsiveness",
1356 new PropertyChangeListener() {
1357 public void propertyChange(PropertyChangeEvent evt) {
1358 int value = ((Integer) evt.getNewValue()).intValue();
1359 handler.setQueueInterval((value * 1000) - 750);
1360 }
1361 });
1362 handler.setQueueInterval((applicationPreferenceModel.getResponsiveness() * 1000) - 750);
1363
1364 applicationPreferenceModel.addPropertyChangeListener(
1365 "tabPlacement",
1366 new PropertyChangeListener() {
1367 public void propertyChange(final PropertyChangeEvent evt) {
1368 SwingUtilities.invokeLater(
1369 new Runnable() {
1370 public void run() {
1371 int placement = ((Integer) evt.getNewValue()).intValue();
1372
1373 switch (placement) {
1374 case SwingConstants.TOP:
1375 case SwingConstants.BOTTOM:
1376 tabbedPane.setTabPlacement(placement);
1377
1378 break;
1379
1380 default:
1381 break;
1382 }
1383 }
1384 });
1385 }
1386 });
1387
1388 applicationPreferenceModel.addPropertyChangeListener(
1389 "statusBar",
1390 new PropertyChangeListener() {
1391 public void propertyChange(PropertyChangeEvent evt) {
1392 boolean value = ((Boolean) evt.getNewValue()).booleanValue();
1393 setStatusBarVisible(value);
1394 }
1395 });
1396 setStatusBarVisible(applicationPreferenceModel.isStatusBar());
1397
1398 applicationPreferenceModel.addPropertyChangeListener(
1399 "receivers",
1400 new PropertyChangeListener() {
1401 public void propertyChange(PropertyChangeEvent evt) {
1402 boolean value = ((Boolean) evt.getNewValue()).booleanValue();
1403
1404 if (value) {
1405 showReceiverPanel();
1406 } else {
1407 hideReceiverPanel();
1408 }
1409 }
1410 });
1411
1412
1413
1414
1415
1416
1417
1418 applicationPreferenceModel.addPropertyChangeListener(
1419 "toolbar",
1420 new PropertyChangeListener() {
1421 public void propertyChange(PropertyChangeEvent evt) {
1422 boolean value = ((Boolean) evt.getNewValue()).booleanValue();
1423 toolbar.setVisible(value);
1424 }
1425 });
1426 toolbar.setVisible(applicationPreferenceModel.isToolbar());
1427
1428 }
1429
1430
1431
1432
1433 private void showReceiverConfigurationPanel() {
1434 SwingUtilities.invokeLater(
1435 new Runnable() {
1436 public void run() {
1437 final JDialog dialog = new JDialog(LogUI.this, true);
1438 dialog.setTitle("Load events into Chainsaw");
1439 dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
1440
1441 dialog.setResizable(false);
1442
1443 receiverConfigurationPanel.setCompletionActionListener(
1444 new ActionListener() {
1445 public void actionPerformed(ActionEvent e) {
1446 dialog.setVisible(false);
1447
1448 if (receiverConfigurationPanel.getModel().isCancelled()) {
1449 return;
1450 }
1451 applicationPreferenceModel.setShowNoReceiverWarning(!receiverConfigurationPanel.isDontWarnMeAgain());
1452
1453 List plugins = pluginRegistry.getPlugins();
1454 for (Iterator iter = plugins.iterator();iter.hasNext();) {
1455 Plugin plugin = (Plugin)iter.next();
1456
1457 if (!plugin.getName().toLowerCase(Locale.ENGLISH).contains("zeroconf")) {
1458 pluginRegistry.stopPlugin(plugin.getName());
1459 }
1460 }
1461 URL configURL = null;
1462
1463 if (receiverConfigurationPanel.getModel().isNetworkReceiverMode()) {
1464 int port = receiverConfigurationPanel.getModel().getNetworkReceiverPort();
1465
1466 try {
1467 Class receiverClass = receiverConfigurationPanel.getModel().getNetworkReceiverClass();
1468 Receiver networkReceiver = (Receiver) receiverClass.newInstance();
1469 networkReceiver.setName(receiverClass.getSimpleName() + "-" + port);
1470
1471 Method portMethod =
1472 networkReceiver.getClass().getMethod(
1473 "setPort", new Class[] { int.class });
1474 portMethod.invoke(
1475 networkReceiver, new Object[] { new Integer(port) });
1476
1477 networkReceiver.setThreshold(Level.TRACE);
1478
1479 pluginRegistry.addPlugin(networkReceiver);
1480 networkReceiver.activateOptions();
1481 receiversPanel.updateReceiverTreeInDispatchThread();
1482 } catch (Exception e3) {
1483 MessageCenter.getInstance().getLogger().error(
1484 "Error creating Receiver", e3);
1485 MessageCenter.getInstance().getLogger().info(
1486 "An error occurred creating your Receiver");
1487 }
1488 } else if (receiverConfigurationPanel.getModel().isLog4jConfig()) {
1489 File log4jConfigFile = receiverConfigurationPanel.getModel().getLog4jConfigFile();
1490 if (log4jConfigFile != null) {
1491 try {
1492 Map entries = LogFilePatternLayoutBuilder.getAppenderConfiguration(log4jConfigFile);
1493 for (Iterator iter = entries.entrySet().iterator();iter.hasNext();) {
1494 try {
1495 Map.Entry entry = (Map.Entry)iter.next();
1496 String name = (String) entry.getKey();
1497 Map values = (Map) entry.getValue();
1498
1499 String conversionPattern = values.get("conversion").toString();
1500 File file = new File(values.get("file").toString());
1501 URL fileURL = file.toURI().toURL();
1502 String timestampFormat = LogFilePatternLayoutBuilder.getTimeStampFormat(conversionPattern);
1503 String receiverPattern = LogFilePatternLayoutBuilder.getLogFormatFromPatternLayout(conversionPattern);
1504 VFSLogFilePatternReceiver fileReceiver = new VFSLogFilePatternReceiver();
1505 fileReceiver.setName(name);
1506 fileReceiver.setAutoReconnect(true);
1507 fileReceiver.setContainer(LogUI.this);
1508 fileReceiver.setAppendNonMatches(true);
1509 fileReceiver.setFileURL(fileURL.toURI().toString());
1510 fileReceiver.setTailing(true);
1511 fileReceiver.setLogFormat(receiverPattern);
1512 fileReceiver.setTimestampFormat(timestampFormat);
1513 fileReceiver.setThreshold(Level.TRACE);
1514 pluginRegistry.addPlugin(fileReceiver);
1515 fileReceiver.activateOptions();
1516 receiversPanel.updateReceiverTreeInDispatchThread();
1517 } catch (URISyntaxException e1) {
1518 e1.printStackTrace();
1519 }
1520 }
1521 } catch (IOException e1) {
1522 e1.printStackTrace();
1523 }
1524 }
1525 } else if (receiverConfigurationPanel.getModel().isLoadConfig()) {
1526 configURL = receiverConfigurationPanel.getModel().getConfigToLoad();
1527 } else if (receiverConfigurationPanel.getModel().isLogFileReceiverConfig()) {
1528 try {
1529 URL fileURL = receiverConfigurationPanel.getModel().getLogFileURL();
1530 if (fileURL != null) {
1531 VFSLogFilePatternReceiver fileReceiver = new VFSLogFilePatternReceiver();
1532 fileReceiver.setName(fileURL.getFile());
1533 fileReceiver.setAutoReconnect(true);
1534 fileReceiver.setContainer(LogUI.this);
1535 fileReceiver.setAppendNonMatches(true);
1536 fileReceiver.setFileURL(fileURL.toURI().toString());
1537 fileReceiver.setTailing(true);
1538 if (receiverConfigurationPanel.getModel().isPatternLayoutLogFormat()) {
1539 fileReceiver.setLogFormat(LogFilePatternLayoutBuilder.getLogFormatFromPatternLayout(receiverConfigurationPanel.getModel().getLogFormat()));
1540 } else {
1541 fileReceiver.setLogFormat(receiverConfigurationPanel.getModel().getLogFormat());
1542 }
1543 fileReceiver.setTimestampFormat(receiverConfigurationPanel.getModel().getLogFormatTimestampFormat());
1544 fileReceiver.setThreshold(Level.TRACE);
1545
1546 pluginRegistry.addPlugin(fileReceiver);
1547 fileReceiver.activateOptions();
1548 receiversPanel.updateReceiverTreeInDispatchThread();
1549 }
1550 } catch (Exception e2) {
1551 MessageCenter.getInstance().getLogger().error(
1552 "Error creating Receiver", e2);
1553 MessageCenter.getInstance().getLogger().info(
1554 "An error occurred creating your Receiver");
1555 }
1556 }
1557 if (configURL == null && receiverConfigurationPanel.isDontWarnMeAgain()) {
1558
1559 if (receiverConfigurationPanel.getModel().getSaveConfigFile() != null) {
1560 try {
1561 configURL = receiverConfigurationPanel.getModel().getSaveConfigFile().toURI().toURL();
1562 } catch (MalformedURLException e1) {
1563 e1.printStackTrace();
1564 }
1565 } else {
1566
1567 configURL = receiverConfigurationPanel.getModel().getDefaultConfigFileURL();
1568 }
1569 }
1570 if (configURL != null) {
1571 MessageCenter.getInstance().getLogger().debug(
1572 "Initialiazing Log4j with " + configURL.toExternalForm());
1573 final URL finalURL = configURL;
1574 new Thread(
1575 new Runnable() {
1576 public void run() {
1577 if (receiverConfigurationPanel.isDontWarnMeAgain()) {
1578 applicationPreferenceModel.setConfigurationURL(finalURL.toExternalForm());
1579 } else {
1580 try {
1581 if (new File(finalURL.toURI()).exists()) {
1582 loadConfigurationUsingPluginClassLoader(finalURL);
1583 }
1584 }
1585 catch (URISyntaxException e) {
1586
1587 }
1588 }
1589
1590 receiversPanel.updateReceiverTreeInDispatchThread();
1591 }
1592 }).start();
1593 }
1594 File saveConfigFile = receiverConfigurationPanel.getModel().getSaveConfigFile();
1595 if (saveConfigFile != null) {
1596 ReceiversHelper.getInstance().saveReceiverConfiguration(saveConfigFile);
1597 }
1598 }
1599 });
1600
1601 receiverConfigurationPanel.setDialog(dialog);
1602 dialog.getContentPane().add(receiverConfigurationPanel);
1603
1604 dialog.pack();
1605
1606 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
1607 dialog.setLocation(
1608 (screenSize.width / 2) - (dialog.getWidth() / 2),
1609 (screenSize.height / 2) - (dialog.getHeight() / 2));
1610
1611 dialog.setVisible(true);
1612 }
1613 });
1614 }
1615
1616
1617
1618
1619
1620 public boolean exit() {
1621 getSettingsManager().saveSettings();
1622
1623 return shutdown();
1624 }
1625
1626 void addWelcomePanel() {
1627 getTabbedPane().insertTab(
1628 ChainsawTabbedPane.WELCOME_TAB, new ImageIcon(ChainsawIcons.ABOUT),welcomePanel,
1629 "Welcome/Help", 0);
1630 getTabbedPane().setSelectedComponent(welcomePanel);
1631 getPanelMap().put(ChainsawTabbedPane.WELCOME_TAB, welcomePanel);
1632 }
1633
1634 void removeWelcomePanel() {
1635 EventQueue.invokeLater(new Runnable()
1636 {
1637 public void run()
1638 {
1639 if (getTabbedPane().containsWelcomePanel()) {
1640 getTabbedPane().remove(
1641 getTabbedPane().getComponentAt(getTabbedPane().indexOfTab(ChainsawTabbedPane.WELCOME_TAB)));
1642 }
1643 }
1644 });
1645 }
1646
1647 ChainsawStatusBar getStatusBar() {
1648 return statusBar;
1649 }
1650
1651 public void showApplicationPreferences() {
1652 applicationPreferenceModelPanel.updateModel();
1653 preferencesFrame.setVisible(true);
1654 }
1655
1656 public void showReceiverConfiguration() {
1657 showReceiverConfigurationPanel();
1658 }
1659
1660 public void showAboutBox() {
1661 if (aboutBox == null) {
1662 aboutBox = new ChainsawAbout(this);
1663 }
1664
1665 aboutBox.setVisible(true);
1666 }
1667
1668 Map getPanels() {
1669 Map m = new HashMap();
1670 Set panelSet = getPanelMap().entrySet();
1671 Iterator iter = panelSet.iterator();
1672
1673 while (iter.hasNext()) {
1674 Map.Entry entry = (Map.Entry) iter.next();
1675 Object o = entry.getValue();
1676 boolean valueToSend;
1677 if (o instanceof LogPanel){
1678 valueToSend = ((DockablePanel) entry.getValue()).isDocked();
1679 } else {
1680 valueToSend = true;
1681 }
1682 m.put(entry.getKey(), new Boolean(valueToSend));
1683 }
1684
1685 return m;
1686 }
1687
1688 void displayPanel(String panelName, boolean display) {
1689 Component p = (Component)getPanelMap().get(panelName);
1690
1691 int index = getTabbedPane().indexOfTab(panelName);
1692
1693 if ((index == -1) && display) {
1694 getTabbedPane().addTab(panelName, p);
1695 }
1696
1697 if ((index > -1) && !display) {
1698 getTabbedPane().removeTabAt(index);
1699 }
1700 }
1701
1702
1703
1704
1705
1706 public boolean shutdown() {
1707 if (getApplicationPreferenceModel().isConfirmExit()) {
1708 if (
1709 JOptionPane.showConfirmDialog(
1710 LogUI.this, "Are you sure you want to exit Chainsaw?",
1711 "Confirm Exit", JOptionPane.YES_NO_OPTION,
1712 JOptionPane.INFORMATION_MESSAGE) != JOptionPane.YES_OPTION) {
1713 return false;
1714 }
1715
1716 }
1717
1718 final JWindow progressWindow = new JWindow();
1719 final ProgressPanel panel = new ProgressPanel(1, 3, "Shutting down");
1720 progressWindow.getContentPane().add(panel);
1721 progressWindow.pack();
1722
1723 Point p = new Point(getLocation());
1724 p.move((int) getSize().getWidth() >> 1, (int) getSize().getHeight() >> 1);
1725 progressWindow.setLocation(p);
1726 progressWindow.setVisible(true);
1727
1728 Runnable runnable =
1729 new Runnable() {
1730 public void run() {
1731 try {
1732 int progress = 1;
1733 final int delay = 25;
1734
1735 handler.close();
1736 panel.setProgress(progress++);
1737
1738 Thread.sleep(delay);
1739
1740 pluginRegistry.stopAllPlugins();
1741 panel.setProgress(progress++);
1742
1743 Thread.sleep(delay);
1744
1745 panel.setProgress(progress++);
1746 Thread.sleep(delay);
1747 } catch (Exception e) {
1748 e.printStackTrace();
1749 }
1750
1751 fireShutdownEvent();
1752 performShutdownAction();
1753 progressWindow.setVisible(false);
1754 }
1755 };
1756
1757 if (OSXIntegration.IS_OSX) {
1758
1759
1760
1761
1762
1763 runnable.run();
1764 }else {
1765 new Thread(runnable).start();
1766 }
1767 return true;
1768 }
1769
1770
1771
1772
1773 private void fireShutdownEvent() {
1774 ShutdownListener[] listeners =
1775 (ShutdownListener[]) shutdownListenerList.getListeners(
1776 ShutdownListener.class);
1777
1778 for (int i = 0; i < listeners.length; i++) {
1779 listeners[i].shuttingDown();
1780 }
1781 }
1782
1783
1784
1785
1786
1787
1788
1789
1790 public final void setShutdownAction(Action shutdownAction) {
1791 this.shutdownAction = shutdownAction;
1792 }
1793
1794
1795
1796
1797
1798
1799 private void performShutdownAction() {
1800 MessageCenter.getInstance().getLogger().debug(
1801 "Calling the shutdown Action. Goodbye!");
1802
1803 shutdownAction.actionPerformed(
1804 new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "Shutting Down"));
1805 }
1806
1807
1808
1809
1810
1811
1812 LogPanel getCurrentLogPanel() {
1813 Component selectedTab = getTabbedPane().getSelectedComponent();
1814
1815 if (selectedTab instanceof LogPanel) {
1816 return (LogPanel) selectedTab;
1817 }
1818
1819 return null;
1820 }
1821
1822
1823
1824
1825 private void setStatusBarVisible(final boolean visible) {
1826 MessageCenter.getInstance().getLogger().debug(
1827 "Setting StatusBar to " + visible);
1828 SwingUtilities.invokeLater(
1829 new Runnable() {
1830 public void run() {
1831 statusBar.setVisible(visible);
1832 }
1833 });
1834 }
1835
1836 boolean isStatusBarVisible() {
1837 return statusBar.isVisible();
1838 }
1839
1840
1841
1842
1843
1844
1845 public String getActiveTabName() {
1846 int index = getTabbedPane().getSelectedIndex();
1847
1848 if (index == -1) {
1849 return null;
1850 } else {
1851 return getTabbedPane().getTitleAt(index);
1852 }
1853 }
1854
1855
1856
1857
1858
1859
1860
1861
1862 public void showHelp(URL url) {
1863 ensureWelcomePanelVisible();
1864
1865 getWelcomePanel().setURL(url);
1866 }
1867
1868
1869
1870
1871
1872
1873 private WelcomePanel getWelcomePanel() {
1874 return welcomePanel;
1875 }
1876
1877
1878
1879
1880
1881
1882 public boolean isLogTreePanelVisible() {
1883 if (getCurrentLogPanel() == null) {
1884 return false;
1885 }
1886
1887 return getCurrentLogPanel().isLogTreeVisible();
1888 }
1889
1890
1891
1892
1893
1894
1895 public Map getPanelMap() {
1896 return panelMap;
1897 }
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908 public SettingsManager getSettingsManager() {
1909 return sm;
1910 }
1911
1912
1913
1914
1915
1916
1917 public List getFilterableColumns() {
1918 return filterableColumns;
1919 }
1920
1921
1922
1923
1924
1925
1926
1927 public void setToolBarAndMenus(ChainsawToolBarAndMenus tbms) {
1928 this.tbms = tbms;
1929 }
1930
1931
1932
1933
1934
1935
1936 public ChainsawToolBarAndMenus getToolBarAndMenus() {
1937 return tbms;
1938 }
1939
1940
1941
1942
1943
1944
1945 public Map getTableMap() {
1946 return tableMap;
1947 }
1948
1949
1950
1951
1952
1953
1954 public Map getTableModelMap() {
1955 return tableModelMap;
1956 }
1957
1958
1959
1960
1961
1962
1963
1964 public void setTabbedPane(ChainsawTabbedPane tabbedPane) {
1965 this.tabbedPane = tabbedPane;
1966 }
1967
1968
1969
1970
1971
1972
1973 public ChainsawTabbedPane getTabbedPane() {
1974 return tabbedPane;
1975 }
1976
1977
1978
1979
1980 public final ApplicationPreferenceModel getApplicationPreferenceModel() {
1981 return applicationPreferenceModel;
1982 }
1983
1984
1985
1986
1987 public void setupTutorial() {
1988 SwingUtilities.invokeLater(
1989 new Runnable() {
1990 public void run() {
1991 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
1992 setLocation(0, getLocation().y);
1993
1994 double chainsawwidth = 0.7;
1995 double tutorialwidth = 1 - chainsawwidth;
1996 setSize((int) (screen.width * chainsawwidth), getSize().height);
1997 invalidate();
1998 validate();
1999
2000 Dimension size = getSize();
2001 Point loc = getLocation();
2002 tutorialFrame.setSize(
2003 (int) (screen.width * tutorialwidth), size.height);
2004 tutorialFrame.setLocation(loc.x + size.width, loc.y);
2005 tutorialFrame.setVisible(true);
2006 }
2007 });
2008 }
2009
2010 private void buildLogPanel(
2011 boolean customExpression, final String ident, final List events)
2012 throws IllegalArgumentException {
2013 final LogPanel thisPanel = new LogPanel(getStatusBar(), ident, cyclicBufferSize, allColorizers, applicationPreferenceModel);
2014
2015 getSettingsManager().addSettingsListener(thisPanel);
2016 getSettingsManager().configure(thisPanel);
2017
2018
2019
2020
2021
2022
2023 if (customExpression) {
2024 handler.addCustomEventBatchListener(ident, thisPanel);
2025 } else {
2026 identifierPanels.add(thisPanel);
2027 handler.addEventBatchListener(thisPanel);
2028 }
2029
2030 TabIconHandler iconHandler = new TabIconHandler(ident);
2031 thisPanel.addEventCountListener(iconHandler);
2032
2033
2034
2035 tabbedPane.addChangeListener(iconHandler);
2036
2037 PropertyChangeListener toolbarMenuUpdateListener =
2038 new PropertyChangeListener() {
2039 public void propertyChange(PropertyChangeEvent evt) {
2040 tbms.stateChange();
2041 }
2042 };
2043
2044 thisPanel.addPropertyChangeListener(toolbarMenuUpdateListener);
2045 thisPanel.addPreferencePropertyChangeListener(toolbarMenuUpdateListener);
2046
2047 thisPanel.addPropertyChangeListener(
2048 "docked",
2049 new PropertyChangeListener() {
2050 public void propertyChange(PropertyChangeEvent evt) {
2051 LogPanel logPanel = (LogPanel) evt.getSource();
2052
2053 if (logPanel.isDocked()) {
2054 getPanelMap().put(logPanel.getIdentifier(), logPanel);
2055 getTabbedPane().addANewTab(
2056 logPanel.getIdentifier(), logPanel, null);
2057 getTabbedPane().setSelectedTab(getTabbedPane().indexOfTab(logPanel.getIdentifier()));
2058 } else {
2059 getTabbedPane().remove(logPanel);
2060 }
2061 }
2062 });
2063
2064 logger.debug("adding logpanel to tabbed pane: " + ident);
2065
2066
2067
2068
2069 getTabbedPane().add(ident, thisPanel);
2070 getPanelMap().put(ident, thisPanel);
2071
2072
2073
2074
2075
2076 SwingUtilities.invokeLater(
2077 new Runnable() {
2078 public void run() {
2079 getTabbedPane().addANewTab(
2080 ident, thisPanel, new ImageIcon(ChainsawIcons.ANIM_RADIO_TOWER));
2081 thisPanel.layoutComponents();
2082 thisPanel.receiveEventBatch(ident, events);
2083 if(!getTabbedPane().tabSetting.isChainsawLog()){
2084 displayPanel("chainsaw-log", false);
2085 }
2086 }
2087 });
2088
2089 String msg = "added tab " + ident;
2090 MessageCenter.getInstance().getLogger().debug(msg);
2091 }
2092
2093
2094 public void createCustomExpressionLogPanel(String ident) {
2095
2096 try {
2097 List list = new ArrayList();
2098 Rule rule = ExpressionRule.getRule(ident);
2099 Iterator iter = identifierPanels.iterator();
2100
2101 while (iter.hasNext()) {
2102 LogPanel panel = (LogPanel) iter.next();
2103 Iterator iter2 = panel.getMatchingEvents(rule).iterator();
2104
2105 while (iter2.hasNext()) {
2106 LoggingEventWrapper e = (LoggingEventWrapper) iter2.next();
2107 list.add(e.getLoggingEvent());
2108 }
2109 }
2110
2111 buildLogPanel(true, ident, list);
2112 } catch (IllegalArgumentException iae) {
2113 MessageCenter.getInstance().getLogger().info(
2114 "Unable to add tab using expression: " + ident + ", reason: "
2115 + iae.getMessage());
2116 }
2117 }
2118
2119
2120
2121
2122
2123
2124
2125
2126 private void loadConfigurationUsingPluginClassLoader(final URL url) {
2127 ClassLoader classLoader = PluginClassLoaderFactory.getInstance().getClassLoader();
2128 ClassLoader previousTCCL = Thread.currentThread().getContextClassLoader();
2129
2130 if(url!=null) {
2131 try {
2132
2133 Thread.currentThread().setContextClassLoader(classLoader);
2134 try {
2135 DOMConfigurator.configure(url);
2136 } catch (Exception e) {
2137 logger.warn("Unable to load configuration URL: " + url, e);
2138 }
2139 }finally{
2140
2141 Thread.currentThread().setContextClassLoader(previousTCCL);
2142 }
2143 }
2144 ensureChainsawAppenderHandlerAdded();
2145 }
2146
2147 private static void loadLookAndFeelUsingPluginClassLoader(String lookAndFeelClassName) {
2148 ClassLoader classLoader = PluginClassLoaderFactory.getInstance().getClassLoader();
2149 ClassLoader previousTCCL = Thread.currentThread().getContextClassLoader();
2150 try {
2151
2152 Thread.currentThread().setContextClassLoader(classLoader);
2153 UIManager.setLookAndFeel(lookAndFeelClassName);
2154 UIManager.getLookAndFeelDefaults().put("ClassLoader", classLoader);
2155 } catch (Exception e) {
2156 e.printStackTrace();
2157 } finally{
2158
2159 Thread.currentThread().setContextClassLoader(previousTCCL);
2160 }
2161 }
2162
2163
2164
2165
2166
2167 private void ensureChainsawAppenderHandlerAdded() {
2168 if(!LogManager.getLoggerRepository().getRootLogger().isAttached(handler)) {
2169 LogManager.getLoggerRepository().getRootLogger().addAppender(handler);
2170 }
2171 }
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182 private class NewTabEventBatchReceiver implements EventBatchListener {
2183
2184
2185
2186
2187
2188
2189 public void receiveEventBatch(
2190 final String ident, final List events) {
2191 if (events.size() == 0) {
2192 return;
2193 }
2194
2195 if (!isGUIFullyInitialized) {
2196 synchronized (initializationLock) {
2197 while (!isGUIFullyInitialized) {
2198 System.out.println(
2199 "Wanting to add a row, but GUI not initialized, waiting...");
2200
2201
2202
2203
2204 try {
2205 initializationLock.wait(1000);
2206 logger.debug("waiting for initialization to complete");
2207 } catch (InterruptedException e) {
2208 }
2209 }
2210 logger.debug("out of system initialization wait loop");
2211 }
2212 }
2213
2214 if (!getPanelMap().containsKey(ident)) {
2215 logger.debug("panel " + ident + " does not exist - creating");
2216 try {
2217 buildLogPanel(false, ident, events);
2218 } catch (IllegalArgumentException iae) {
2219 logger.error("error creating log panel", iae);
2220
2221 }
2222 }
2223 }
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236 public String getInterestedIdentifier() {
2237
2238 return null;
2239 }
2240 }
2241
2242 private class TabIconHandler implements EventCountListener, ChangeListener {
2243
2244
2245 private boolean newEvents = true;
2246 private boolean seenEvents = false;
2247 private final String ident;
2248 ImageIcon NEW_EVENTS = new ImageIcon(ChainsawIcons.ANIM_RADIO_TOWER);
2249 ImageIcon HAS_EVENTS = new ImageIcon(ChainsawIcons.INFO);
2250 Icon SELECTED = LineIconFactory.createBlankIcon();
2251
2252 public TabIconHandler(String identifier) {
2253 ident = identifier;
2254
2255 new Thread(
2256 new Runnable() {
2257 public void run() {
2258 while (true) {
2259
2260
2261 if (getTabbedPane().indexOfTab(ident) > -1 &&
2262 getTabbedPane().getSelectedIndex() == getTabbedPane()
2263 .indexOfTab(ident)) {
2264 getTabbedPane().setIconAt(
2265 getTabbedPane().indexOfTab(ident), SELECTED);
2266 newEvents = false;
2267 seenEvents = true;
2268 } else if (getTabbedPane().indexOfTab(ident) > -1) {
2269 if (newEvents) {
2270 getTabbedPane().setIconAt(
2271 getTabbedPane().indexOfTab(ident), NEW_EVENTS);
2272 newEvents = false;
2273 seenEvents = false;
2274 } else if (!seenEvents) {
2275 getTabbedPane().setIconAt(
2276 getTabbedPane().indexOfTab(ident), HAS_EVENTS);
2277 }
2278 }
2279
2280 try {
2281 Thread.sleep(handler.getQueueInterval() + 1000);
2282 } catch (InterruptedException ie) {
2283 }
2284 }
2285 }
2286 }).start();
2287 }
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297 public void eventCountChanged(int currentCount, int totalCount) {
2298 newEvents = true;
2299 }
2300
2301 public void stateChanged(ChangeEvent event) {
2302 if (
2303 getTabbedPane().indexOfTab(ident) > -1 && getTabbedPane().indexOfTab(ident) == getTabbedPane().getSelectedIndex()) {
2304 getTabbedPane().setIconAt(getTabbedPane().indexOfTab(ident), SELECTED);
2305 }
2306 }
2307 }
2308 }