001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.log4j.lf5.viewer; 018 019import java.awt.BorderLayout; 020import java.awt.Color; 021import java.awt.Component; 022import java.awt.Dimension; 023import java.awt.FlowLayout; 024import java.awt.Font; 025import java.awt.GraphicsEnvironment; 026import java.awt.Toolkit; 027import java.awt.event.ActionEvent; 028import java.awt.event.ActionListener; 029import java.awt.event.WindowAdapter; 030import java.awt.event.WindowEvent; 031import java.io.File; 032import java.io.IOException; 033import java.io.InputStream; 034import java.net.MalformedURLException; 035import java.net.URL; 036import java.util.ArrayList; 037import java.util.HashMap; 038import java.util.Iterator; 039import java.util.List; 040import java.util.Map; 041import java.util.StringTokenizer; 042import java.util.Vector; 043 044import javax.swing.BorderFactory; 045import javax.swing.ImageIcon; 046import javax.swing.JButton; 047import javax.swing.JCheckBoxMenuItem; 048import javax.swing.JColorChooser; 049import javax.swing.JComboBox; 050import javax.swing.JFileChooser; 051import javax.swing.JFrame; 052import javax.swing.JLabel; 053import javax.swing.JMenu; 054import javax.swing.JMenuBar; 055import javax.swing.JMenuItem; 056import javax.swing.JOptionPane; 057import javax.swing.JPanel; 058import javax.swing.JScrollPane; 059import javax.swing.JSplitPane; 060import javax.swing.JTextArea; 061import javax.swing.JToolBar; 062import javax.swing.KeyStroke; 063import javax.swing.SwingUtilities; 064 065import org.apache.log4j.lf5.LogLevel; 066import org.apache.log4j.lf5.LogRecord; 067import org.apache.log4j.lf5.LogRecordFilter; 068import org.apache.log4j.lf5.util.DateFormatManager; 069import org.apache.log4j.lf5.util.LogFileParser; 070import org.apache.log4j.lf5.viewer.categoryexplorer.CategoryExplorerTree; 071import org.apache.log4j.lf5.viewer.categoryexplorer.CategoryPath; 072import org.apache.log4j.lf5.viewer.configure.ConfigurationManager; 073import org.apache.log4j.lf5.viewer.configure.MRUFileManager; 074 075/** 076 * LogBrokerMonitor 077 *. 078 * @author Michael J. Sikorsky 079 * @author Robert Shaw 080 * @author Brad Marlborough 081 * @author Richard Wan 082 * @author Brent Sprecher 083 * @author Richard Hurst 084 */ 085 086// Contributed by ThoughtWorks Inc. 087 088public class LogBrokerMonitor { 089 //-------------------------------------------------------------------------- 090 // Constants: 091 //-------------------------------------------------------------------------- 092 093 public static final String DETAILED_VIEW = "Detailed"; 094// public static final String STANDARD_VIEW = "Standard"; 095// public static final String COMPACT_VIEW = "Compact"; 096 //-------------------------------------------------------------------------- 097 // Protected Variables: 098 //-------------------------------------------------------------------------- 099 protected JFrame _logMonitorFrame; 100 protected int _logMonitorFrameWidth = 550; 101 protected int _logMonitorFrameHeight = 500; 102 protected LogTable _table; 103 protected CategoryExplorerTree _categoryExplorerTree; 104 protected String _searchText; 105 protected String _NDCTextFilter = ""; 106 protected LogLevel _leastSevereDisplayedLogLevel = LogLevel.DEBUG; 107 108 protected JScrollPane _logTableScrollPane; 109 protected JLabel _statusLabel; 110 protected Object _lock = new Object(); 111 protected JComboBox _fontSizeCombo; 112 113 protected int _fontSize = 10; 114 protected String _fontName = "Dialog"; 115 protected String _currentView = DETAILED_VIEW; 116 117 protected boolean _loadSystemFonts = false; 118 protected boolean _trackTableScrollPane = true; 119 protected Dimension _lastTableViewportSize; 120 protected boolean _callSystemExitOnClose = false; 121 protected List _displayedLogBrokerProperties = new Vector(); 122 123 protected Map _logLevelMenuItems = new HashMap(); 124 protected Map _logTableColumnMenuItems = new HashMap(); 125 126 protected List _levels = null; 127 protected List _columns = null; 128 protected boolean _isDisposed = false; 129 130 protected ConfigurationManager _configurationManager = null; 131 protected MRUFileManager _mruFileManager = null; 132 protected File _fileLocation = null; 133 134 //-------------------------------------------------------------------------- 135 // Private Variables: 136 //-------------------------------------------------------------------------- 137 138 //-------------------------------------------------------------------------- 139 // Constructors: 140 //-------------------------------------------------------------------------- 141 142 /** 143 * Construct a LogBrokerMonitor. 144 */ 145 public LogBrokerMonitor(List logLevels) { 146 147 _levels = logLevels; 148 _columns = LogTableColumn.getLogTableColumns(); 149 // This allows us to use the LogBroker in command line tools and 150 // have the option for it to shutdown. 151 152 String callSystemExitOnClose = 153 System.getProperty("monitor.exit"); 154 if (callSystemExitOnClose == null) { 155 callSystemExitOnClose = "false"; 156 } 157 callSystemExitOnClose = callSystemExitOnClose.trim().toLowerCase(); 158 159 if (callSystemExitOnClose.equals("true")) { 160 _callSystemExitOnClose = true; 161 } 162 163 initComponents(); 164 165 166 _logMonitorFrame.addWindowListener( 167 new LogBrokerMonitorWindowAdaptor(this)); 168 169 } 170 171 //-------------------------------------------------------------------------- 172 // Public Methods: 173 //-------------------------------------------------------------------------- 174 175 /** 176 * Show the frame for the LogBrokerMonitor. Dispatched to the 177 * swing thread. 178 */ 179 public void show(final int delay) { 180 if (_logMonitorFrame.isVisible()) { 181 return; 182 } 183 // This request is very low priority, let other threads execute first. 184 SwingUtilities.invokeLater(new Runnable() { 185 public void run() { 186 Thread.yield(); 187 pause(delay); 188 _logMonitorFrame.setVisible(true); 189 } 190 }); 191 } 192 193 public void show() { 194 show(0); 195 } 196 197 /** 198 * Dispose of the frame for the LogBrokerMonitor. 199 */ 200 public void dispose() { 201 _logMonitorFrame.dispose(); 202 _isDisposed = true; 203 204 if (_callSystemExitOnClose == true) { 205 System.exit(0); 206 } 207 } 208 209 /** 210 * Hide the frame for the LogBrokerMonitor. 211 */ 212 public void hide() { 213 _logMonitorFrame.setVisible(false); 214 } 215 216 /** 217 * Get the DateFormatManager for formatting dates. 218 */ 219 public DateFormatManager getDateFormatManager() { 220 return _table.getDateFormatManager(); 221 } 222 223 /** 224 * Set the date format manager for formatting dates. 225 */ 226 public void setDateFormatManager(DateFormatManager dfm) { 227 _table.setDateFormatManager(dfm); 228 } 229 230 /** 231 * Get the value of whether or not System.exit() will be called 232 * when the LogBrokerMonitor is closed. 233 */ 234 public boolean getCallSystemExitOnClose() { 235 return _callSystemExitOnClose; 236 } 237 238 /** 239 * Set the value of whether or not System.exit() will be called 240 * when the LogBrokerMonitor is closed. 241 */ 242 public void setCallSystemExitOnClose(boolean callSystemExitOnClose) { 243 _callSystemExitOnClose = callSystemExitOnClose; 244 } 245 246 /** 247 * Add a log record message to be displayed in the LogTable. 248 * This method is thread-safe as it posts requests to the SwingThread 249 * rather than processing directly. 250 */ 251 public void addMessage(final LogRecord lr) { 252 if (_isDisposed == true) { 253 // If the frame has been disposed of, do not log any more 254 // messages. 255 return; 256 } 257 258 SwingUtilities.invokeLater(new Runnable() { 259 public void run() { 260 _categoryExplorerTree.getExplorerModel().addLogRecord(lr); 261 _table.getFilteredLogTableModel().addLogRecord(lr); // update table 262 updateStatusLabel(); // show updated counts 263 } 264 }); 265 } 266 267 public void setMaxNumberOfLogRecords(int maxNumberOfLogRecords) { 268 _table.getFilteredLogTableModel().setMaxNumberOfLogRecords(maxNumberOfLogRecords); 269 } 270 271 public JFrame getBaseFrame() { 272 return _logMonitorFrame; 273 } 274 275 public void setTitle(String title) { 276 _logMonitorFrame.setTitle(title + " - LogFactor5"); 277 } 278 279 public void setFrameSize(int width, int height) { 280 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); 281 if (0 < width && width < screen.width) { 282 _logMonitorFrameWidth = width; 283 } 284 if (0 < height && height < screen.height) { 285 _logMonitorFrameHeight = height; 286 } 287 updateFrameSize(); 288 } 289 290 public void setFontSize(int fontSize) { 291 changeFontSizeCombo(_fontSizeCombo, fontSize); 292 // setFontSizeSilently(actualFontSize); - changeFontSizeCombo fires event 293 // refreshDetailTextArea(); 294 } 295 296 public void addDisplayedProperty(Object messageLine) { 297 _displayedLogBrokerProperties.add(messageLine); 298 } 299 300 public Map getLogLevelMenuItems() { 301 return _logLevelMenuItems; 302 } 303 304 public Map getLogTableColumnMenuItems() { 305 return _logTableColumnMenuItems; 306 } 307 308 public JCheckBoxMenuItem getTableColumnMenuItem(LogTableColumn column) { 309 return getLogTableColumnMenuItem(column); 310 } 311 312 public CategoryExplorerTree getCategoryExplorerTree() { 313 return _categoryExplorerTree; 314 } 315 316 // Added in version 1.2 - gets the value of the NDC text filter 317 // This value is set back to null each time the Monitor is initialized. 318 public String getNDCTextFilter() { 319 return _NDCTextFilter; 320 } 321 322 // Added in version 1.2 - sets the NDC Filter based on 323 // a String passed in by the user. This value is persisted 324 // in the XML Configuration file. 325 public void setNDCLogRecordFilter(String textFilter) { 326 _table.getFilteredLogTableModel(). 327 setLogRecordFilter(createNDCLogRecordFilter(textFilter)); 328 } 329 //-------------------------------------------------------------------------- 330 // Protected Methods: 331 //-------------------------------------------------------------------------- 332 333 protected void setSearchText(String text) { 334 _searchText = text; 335 } 336 337 // Added in version 1.2 - Sets the text filter for the NDC 338 protected void setNDCTextFilter(String text) { 339 // if no value is set, set it to a blank string 340 // otherwise use the value provided 341 if (text == null) { 342 _NDCTextFilter = ""; 343 } else { 344 _NDCTextFilter = text; 345 } 346 } 347 348 // Added in version 1.2 - Uses a different filter that sorts 349 // based on an NDC string passed in by the user. If the string 350 // is null or is an empty string, we do nothing. 351 protected void sortByNDC() { 352 String text = _NDCTextFilter; 353 if (text == null || text.length() == 0) { 354 return; 355 } 356 357 // Use new NDC filter 358 _table.getFilteredLogTableModel(). 359 setLogRecordFilter(createNDCLogRecordFilter(text)); 360 } 361 362 protected void findSearchText() { 363 String text = _searchText; 364 if (text == null || text.length() == 0) { 365 return; 366 } 367 int startRow = getFirstSelectedRow(); 368 int foundRow = findRecord( 369 startRow, 370 text, 371 _table.getFilteredLogTableModel().getFilteredRecords() 372 ); 373 selectRow(foundRow); 374 } 375 376 protected int getFirstSelectedRow() { 377 return _table.getSelectionModel().getMinSelectionIndex(); 378 } 379 380 protected void selectRow(int foundRow) { 381 if (foundRow == -1) { 382 String message = _searchText + " not found."; 383 JOptionPane.showMessageDialog( 384 _logMonitorFrame, 385 message, 386 "Text not found", 387 JOptionPane.INFORMATION_MESSAGE 388 ); 389 return; 390 } 391 LF5SwingUtils.selectRow(foundRow, _table, _logTableScrollPane); 392 } 393 394 protected int findRecord( 395 int startRow, 396 String searchText, 397 List records 398 ) { 399 if (startRow < 0) { 400 startRow = 0; // start at first element if no rows are selected 401 } else { 402 startRow++; // start after the first selected row 403 } 404 int len = records.size(); 405 406 for (int i = startRow; i < len; i++) { 407 if (matches((LogRecord) records.get(i), searchText)) { 408 return i; // found a record 409 } 410 } 411 // wrap around to beginning if when we reach the end with no match 412 len = startRow; 413 for (int i = 0; i < len; i++) { 414 if (matches((LogRecord) records.get(i), searchText)) { 415 return i; // found a record 416 } 417 } 418 // nothing found 419 return -1; 420 } 421 422 /** 423 * Check to see if the any records contain the search string. 424 * Searching now supports NDC messages and date. 425 */ 426 protected boolean matches(LogRecord record, String text) { 427 String message = record.getMessage(); 428 String NDC = record.getNDC(); 429 430 if (message == null && NDC == null || text == null) { 431 return false; 432 } 433 if (message.toLowerCase().indexOf(text.toLowerCase()) == -1 && 434 NDC.toLowerCase().indexOf(text.toLowerCase()) == -1) { 435 return false; 436 } 437 438 return true; 439 } 440 441 /** 442 * When the fontsize of a JTextArea is changed, the word-wrapped lines 443 * may become garbled. This method clears and resets the text of the 444 * text area. 445 */ 446 protected void refresh(JTextArea textArea) { 447 String text = textArea.getText(); 448 textArea.setText(""); 449 textArea.setText(text); 450 } 451 452 protected void refreshDetailTextArea() { 453 refresh(_table._detailTextArea); 454 } 455 456 protected void clearDetailTextArea() { 457 _table._detailTextArea.setText(""); 458 } 459 460 /** 461 * Changes the font selection in the combo box and returns the 462 * size actually selected. 463 * @return -1 if unable to select an appropriate font 464 */ 465 protected int changeFontSizeCombo(JComboBox box, int requestedSize) { 466 int len = box.getItemCount(); 467 int currentValue; 468 Object currentObject; 469 Object selectedObject = box.getItemAt(0); 470 int selectedValue = Integer.parseInt(String.valueOf(selectedObject)); 471 for (int i = 0; i < len; i++) { 472 currentObject = box.getItemAt(i); 473 currentValue = Integer.parseInt(String.valueOf(currentObject)); 474 if (selectedValue < currentValue && currentValue <= requestedSize) { 475 selectedValue = currentValue; 476 selectedObject = currentObject; 477 } 478 } 479 box.setSelectedItem(selectedObject); 480 return selectedValue; 481 } 482 483 /** 484 * Does not update gui or cause any events to be fired. 485 */ 486 protected void setFontSizeSilently(int fontSize) { 487 _fontSize = fontSize; 488 setFontSize(_table._detailTextArea, fontSize); 489 selectRow(0); 490 setFontSize(_table, fontSize); 491 } 492 493 protected void setFontSize(Component component, int fontSize) { 494 Font oldFont = component.getFont(); 495 Font newFont = 496 new Font(oldFont.getFontName(), oldFont.getStyle(), fontSize); 497 component.setFont(newFont); 498 } 499 500 protected void updateFrameSize() { 501 _logMonitorFrame.setSize(_logMonitorFrameWidth, _logMonitorFrameHeight); 502 centerFrame(_logMonitorFrame); 503 } 504 505 protected void pause(int millis) { 506 try { 507 Thread.sleep(millis); 508 } catch (InterruptedException e) { 509 510 } 511 } 512 513 protected void initComponents() { 514 // 515 // Configure the Frame. 516 // 517 _logMonitorFrame = new JFrame("LogFactor5"); 518 519 _logMonitorFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); 520 521 String resource = 522 "/org/apache/log4j/lf5/viewer/images/lf5_small_icon.gif"; 523 URL lf5IconURL = getClass().getResource(resource); 524 525 if (lf5IconURL != null) { 526 _logMonitorFrame.setIconImage(new ImageIcon(lf5IconURL).getImage()); 527 } 528 updateFrameSize(); 529 530 // 531 // Configure the LogTable. 532 // 533 JTextArea detailTA = createDetailTextArea(); 534 JScrollPane detailTAScrollPane = new JScrollPane(detailTA); 535 _table = new LogTable(detailTA); 536 setView(_currentView, _table); 537 _table.setFont(new Font(_fontName, Font.PLAIN, _fontSize)); 538 _logTableScrollPane = new JScrollPane(_table); 539 540 if (_trackTableScrollPane) { 541 _logTableScrollPane.getVerticalScrollBar().addAdjustmentListener( 542 new TrackingAdjustmentListener() 543 ); 544 } 545 546 547 // Configure the SplitPane between the LogTable & DetailTextArea 548 // 549 550 JSplitPane tableViewerSplitPane = new JSplitPane(); 551 tableViewerSplitPane.setOneTouchExpandable(true); 552 tableViewerSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT); 553 tableViewerSplitPane.setLeftComponent(_logTableScrollPane); 554 tableViewerSplitPane.setRightComponent(detailTAScrollPane); 555 // Make sure to do this last.. 556 //tableViewerSplitPane.setDividerLocation(1.0); Doesn't work 557 //the same under 1.2.x & 1.3 558 // "350" is a magic number that provides the correct default 559 // behaviour under 1.2.x & 1.3. For example, bumping this 560 // number to 400, causes the pane to be completely open in 1.2.x 561 // and closed in 1.3 562 tableViewerSplitPane.setDividerLocation(350); 563 564 // 565 // Configure the CategoryExplorer 566 // 567 568 _categoryExplorerTree = new CategoryExplorerTree(); 569 570 _table.getFilteredLogTableModel().setLogRecordFilter(createLogRecordFilter()); 571 572 JScrollPane categoryExplorerTreeScrollPane = 573 new JScrollPane(_categoryExplorerTree); 574 categoryExplorerTreeScrollPane.setPreferredSize(new Dimension(130, 400)); 575 576 // Load most recently used file list 577 _mruFileManager = new MRUFileManager(); 578 579 // 580 // Configure the SplitPane between the CategoryExplorer & (LogTable/Detail) 581 // 582 583 JSplitPane splitPane = new JSplitPane(); 584 splitPane.setOneTouchExpandable(true); 585 splitPane.setRightComponent(tableViewerSplitPane); 586 splitPane.setLeftComponent(categoryExplorerTreeScrollPane); 587 // Do this last. 588 splitPane.setDividerLocation(130); 589 // 590 // Add the MenuBar, StatusArea, CategoryExplorer|LogTable to the 591 // LogMonitorFrame. 592 // 593 _logMonitorFrame.getRootPane().setJMenuBar(createMenuBar()); 594 _logMonitorFrame.getContentPane().add(splitPane, BorderLayout.CENTER); 595 _logMonitorFrame.getContentPane().add(createToolBar(), 596 BorderLayout.NORTH); 597 _logMonitorFrame.getContentPane().add(createStatusArea(), 598 BorderLayout.SOUTH); 599 600 makeLogTableListenToCategoryExplorer(); 601 addTableModelProperties(); 602 603 // 604 // Configure ConfigurationManager 605 // 606 _configurationManager = new ConfigurationManager(this, _table); 607 608 } 609 610 protected LogRecordFilter createLogRecordFilter() { 611 LogRecordFilter result = new LogRecordFilter() { 612 public boolean passes(LogRecord record) { 613 CategoryPath path = new CategoryPath(record.getCategory()); 614 return 615 getMenuItem(record.getLevel()).isSelected() && 616 _categoryExplorerTree.getExplorerModel().isCategoryPathActive(path); 617 } 618 }; 619 return result; 620 } 621 622 // Added in version 1.2 - Creates a new filter that sorts records based on 623 // an NDC string passed in by the user. 624 protected LogRecordFilter createNDCLogRecordFilter(String text) { 625 _NDCTextFilter = text; 626 LogRecordFilter result = new LogRecordFilter() { 627 public boolean passes(LogRecord record) { 628 String NDC = record.getNDC(); 629 CategoryPath path = new CategoryPath(record.getCategory()); 630 if (NDC == null || _NDCTextFilter == null) { 631 return false; 632 } else if (NDC.toLowerCase().indexOf(_NDCTextFilter.toLowerCase()) == -1) { 633 return false; 634 } else { 635 return getMenuItem(record.getLevel()).isSelected() && 636 _categoryExplorerTree.getExplorerModel().isCategoryPathActive(path); 637 } 638 } 639 }; 640 641 return result; 642 } 643 644 645 protected void updateStatusLabel() { 646 _statusLabel.setText(getRecordsDisplayedMessage()); 647 } 648 649 protected String getRecordsDisplayedMessage() { 650 FilteredLogTableModel model = _table.getFilteredLogTableModel(); 651 return getStatusText(model.getRowCount(), model.getTotalRowCount()); 652 } 653 654 protected void addTableModelProperties() { 655 final FilteredLogTableModel model = _table.getFilteredLogTableModel(); 656 657 addDisplayedProperty(new Object() { 658 public String toString() { 659 return getRecordsDisplayedMessage(); 660 } 661 }); 662 addDisplayedProperty(new Object() { 663 public String toString() { 664 return "Maximum number of displayed LogRecords: " 665 + model._maxNumberOfLogRecords; 666 } 667 }); 668 } 669 670 protected String getStatusText(int displayedRows, int totalRows) { 671 StringBuffer result = new StringBuffer(); 672 result.append("Displaying: "); 673 result.append(displayedRows); 674 result.append(" records out of a total of: "); 675 result.append(totalRows); 676 result.append(" records."); 677 return result.toString(); 678 } 679 680 protected void makeLogTableListenToCategoryExplorer() { 681 ActionListener listener = new ActionListener() { 682 public void actionPerformed(ActionEvent e) { 683 _table.getFilteredLogTableModel().refresh(); 684 updateStatusLabel(); 685 } 686 }; 687 _categoryExplorerTree.getExplorerModel().addActionListener(listener); 688 } 689 690 protected JPanel createStatusArea() { 691 JPanel statusArea = new JPanel(); 692 JLabel status = 693 new JLabel("No log records to display."); 694 _statusLabel = status; 695 status.setHorizontalAlignment(JLabel.LEFT); 696 697 statusArea.setBorder(BorderFactory.createEtchedBorder()); 698 statusArea.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); 699 statusArea.add(status); 700 701 return (statusArea); 702 } 703 704 protected JTextArea createDetailTextArea() { 705 JTextArea detailTA = new JTextArea(); 706 detailTA.setFont(new Font("Monospaced", Font.PLAIN, 14)); 707 detailTA.setTabSize(3); 708 detailTA.setLineWrap(true); 709 detailTA.setWrapStyleWord(false); 710 return (detailTA); 711 } 712 713 protected JMenuBar createMenuBar() { 714 JMenuBar menuBar = new JMenuBar(); 715 menuBar.add(createFileMenu()); 716 menuBar.add(createEditMenu()); 717 menuBar.add(createLogLevelMenu()); 718 menuBar.add(createViewMenu()); 719 menuBar.add(createConfigureMenu()); 720 menuBar.add(createHelpMenu()); 721 722 return (menuBar); 723 } 724 725 protected JMenu createLogLevelMenu() { 726 JMenu result = new JMenu("Log Level"); 727 result.setMnemonic('l'); 728 Iterator levels = getLogLevels(); 729 while (levels.hasNext()) { 730 result.add(getMenuItem((LogLevel) levels.next())); 731 } 732 733 result.addSeparator(); 734 result.add(createAllLogLevelsMenuItem()); 735 result.add(createNoLogLevelsMenuItem()); 736 result.addSeparator(); 737 result.add(createLogLevelColorMenu()); 738 result.add(createResetLogLevelColorMenuItem()); 739 740 return result; 741 } 742 743 protected JMenuItem createAllLogLevelsMenuItem() { 744 JMenuItem result = new JMenuItem("Show all LogLevels"); 745 result.setMnemonic('s'); 746 result.addActionListener(new ActionListener() { 747 public void actionPerformed(ActionEvent e) { 748 selectAllLogLevels(true); 749 _table.getFilteredLogTableModel().refresh(); 750 updateStatusLabel(); 751 } 752 }); 753 return result; 754 } 755 756 protected JMenuItem createNoLogLevelsMenuItem() { 757 JMenuItem result = new JMenuItem("Hide all LogLevels"); 758 result.setMnemonic('h'); 759 result.addActionListener(new ActionListener() { 760 public void actionPerformed(ActionEvent e) { 761 selectAllLogLevels(false); 762 _table.getFilteredLogTableModel().refresh(); 763 updateStatusLabel(); 764 } 765 }); 766 return result; 767 } 768 769 protected JMenu createLogLevelColorMenu() { 770 JMenu colorMenu = new JMenu("Configure LogLevel Colors"); 771 colorMenu.setMnemonic('c'); 772 Iterator levels = getLogLevels(); 773 while (levels.hasNext()) { 774 colorMenu.add(createSubMenuItem((LogLevel) levels.next())); 775 } 776 777 return colorMenu; 778 } 779 780 protected JMenuItem createResetLogLevelColorMenuItem() { 781 JMenuItem result = new JMenuItem("Reset LogLevel Colors"); 782 result.setMnemonic('r'); 783 result.addActionListener(new ActionListener() { 784 public void actionPerformed(ActionEvent e) { 785 // reset the level colors in the map 786 LogLevel.resetLogLevelColorMap(); 787 788 // refresh the table 789 _table.getFilteredLogTableModel().refresh(); 790 } 791 }); 792 return result; 793 } 794 795 protected void selectAllLogLevels(boolean selected) { 796 Iterator levels = getLogLevels(); 797 while (levels.hasNext()) { 798 getMenuItem((LogLevel) levels.next()).setSelected(selected); 799 } 800 } 801 802 protected JCheckBoxMenuItem getMenuItem(LogLevel level) { 803 JCheckBoxMenuItem result = (JCheckBoxMenuItem) (_logLevelMenuItems.get(level)); 804 if (result == null) { 805 result = createMenuItem(level); 806 _logLevelMenuItems.put(level, result); 807 } 808 return result; 809 } 810 811 protected JMenuItem createSubMenuItem(LogLevel level) { 812 final JMenuItem result = new JMenuItem(level.toString()); 813 final LogLevel logLevel = level; 814 result.setMnemonic(level.toString().charAt(0)); 815 result.addActionListener(new ActionListener() { 816 public void actionPerformed(ActionEvent e) { 817 showLogLevelColorChangeDialog(result, logLevel); 818 } 819 }); 820 821 return result; 822 823 } 824 825 protected void showLogLevelColorChangeDialog(JMenuItem result, LogLevel level) { 826 JMenuItem menuItem = result; 827 Color newColor = JColorChooser.showDialog( 828 _logMonitorFrame, 829 "Choose LogLevel Color", 830 result.getForeground()); 831 832 if (newColor != null) { 833 // set the color for the record 834 level.setLogLevelColorMap(level, newColor); 835 _table.getFilteredLogTableModel().refresh(); 836 } 837 838 } 839 840 protected JCheckBoxMenuItem createMenuItem(LogLevel level) { 841 JCheckBoxMenuItem result = new JCheckBoxMenuItem(level.toString()); 842 result.setSelected(true); 843 result.setMnemonic(level.toString().charAt(0)); 844 result.addActionListener(new ActionListener() { 845 public void actionPerformed(ActionEvent e) { 846 _table.getFilteredLogTableModel().refresh(); 847 updateStatusLabel(); 848 } 849 }); 850 return result; 851 } 852 853 // view menu 854 protected JMenu createViewMenu() { 855 JMenu result = new JMenu("View"); 856 result.setMnemonic('v'); 857 Iterator columns = getLogTableColumns(); 858 while (columns.hasNext()) { 859 result.add(getLogTableColumnMenuItem((LogTableColumn) columns.next())); 860 } 861 862 result.addSeparator(); 863 result.add(createAllLogTableColumnsMenuItem()); 864 result.add(createNoLogTableColumnsMenuItem()); 865 return result; 866 } 867 868 protected JCheckBoxMenuItem getLogTableColumnMenuItem(LogTableColumn column) { 869 JCheckBoxMenuItem result = (JCheckBoxMenuItem) (_logTableColumnMenuItems.get(column)); 870 if (result == null) { 871 result = createLogTableColumnMenuItem(column); 872 _logTableColumnMenuItems.put(column, result); 873 } 874 return result; 875 } 876 877 protected JCheckBoxMenuItem createLogTableColumnMenuItem(LogTableColumn column) { 878 JCheckBoxMenuItem result = new JCheckBoxMenuItem(column.toString()); 879 880 result.setSelected(true); 881 result.setMnemonic(column.toString().charAt(0)); 882 result.addActionListener(new ActionListener() { 883 public void actionPerformed(ActionEvent e) { 884 // update list of columns and reset the view 885 List selectedColumns = updateView(); 886 _table.setView(selectedColumns); 887 } 888 }); 889 return result; 890 } 891 892 protected List updateView() { 893 ArrayList updatedList = new ArrayList(); 894 Iterator columnIterator = _columns.iterator(); 895 while (columnIterator.hasNext()) { 896 LogTableColumn column = (LogTableColumn) columnIterator.next(); 897 JCheckBoxMenuItem result = getLogTableColumnMenuItem(column); 898 // check and see if the checkbox is checked 899 if (result.isSelected()) { 900 updatedList.add(column); 901 } 902 } 903 904 return updatedList; 905 } 906 907 protected JMenuItem createAllLogTableColumnsMenuItem() { 908 JMenuItem result = new JMenuItem("Show all Columns"); 909 result.setMnemonic('s'); 910 result.addActionListener(new ActionListener() { 911 public void actionPerformed(ActionEvent e) { 912 selectAllLogTableColumns(true); 913 // update list of columns and reset the view 914 List selectedColumns = updateView(); 915 _table.setView(selectedColumns); 916 } 917 }); 918 return result; 919 } 920 921 protected JMenuItem createNoLogTableColumnsMenuItem() { 922 JMenuItem result = new JMenuItem("Hide all Columns"); 923 result.setMnemonic('h'); 924 result.addActionListener(new ActionListener() { 925 public void actionPerformed(ActionEvent e) { 926 selectAllLogTableColumns(false); 927 // update list of columns and reset the view 928 List selectedColumns = updateView(); 929 _table.setView(selectedColumns); 930 } 931 }); 932 return result; 933 } 934 935 protected void selectAllLogTableColumns(boolean selected) { 936 Iterator columns = getLogTableColumns(); 937 while (columns.hasNext()) { 938 getLogTableColumnMenuItem((LogTableColumn) columns.next()).setSelected(selected); 939 } 940 } 941 942 protected JMenu createFileMenu() { 943 JMenu fileMenu = new JMenu("File"); 944 fileMenu.setMnemonic('f'); 945 JMenuItem exitMI; 946 fileMenu.add(createOpenMI()); 947 fileMenu.add(createOpenURLMI()); 948 fileMenu.addSeparator(); 949 fileMenu.add(createCloseMI()); 950 createMRUFileListMI(fileMenu); 951 fileMenu.addSeparator(); 952 fileMenu.add(createExitMI()); 953 return fileMenu; 954 } 955 956 /** 957 * Menu item added to allow log files to be opened with 958 * the LF5 GUI. 959 */ 960 protected JMenuItem createOpenMI() { 961 JMenuItem result = new JMenuItem("Open..."); 962 result.setMnemonic('o'); 963 result.addActionListener(new ActionListener() { 964 public void actionPerformed(ActionEvent e) { 965 requestOpen(); 966 } 967 }); 968 return result; 969 } 970 971 /** 972 * Menu item added to allow log files loaded from a URL 973 * to be opened by the LF5 GUI. 974 */ 975 protected JMenuItem createOpenURLMI() { 976 JMenuItem result = new JMenuItem("Open URL..."); 977 result.setMnemonic('u'); 978 result.addActionListener(new ActionListener() { 979 public void actionPerformed(ActionEvent e) { 980 requestOpenURL(); 981 } 982 }); 983 return result; 984 } 985 986 protected JMenuItem createCloseMI() { 987 JMenuItem result = new JMenuItem("Close"); 988 result.setMnemonic('c'); 989 result.setAccelerator(KeyStroke.getKeyStroke("control Q")); 990 result.addActionListener(new ActionListener() { 991 public void actionPerformed(ActionEvent e) { 992 requestClose(); 993 } 994 }); 995 return result; 996 } 997 998 /** 999 * Creates a Most Recently Used file list to be 1000 * displayed in the File menu 1001 */ 1002 protected void createMRUFileListMI(JMenu menu) { 1003 1004 String[] files = _mruFileManager.getMRUFileList(); 1005 1006 if (files != null) { 1007 menu.addSeparator(); 1008 for (int i = 0; i < files.length; i++) { 1009 JMenuItem result = new JMenuItem((i + 1) + " " + files[i]); 1010 result.setMnemonic(i + 1); 1011 result.addActionListener(new ActionListener() { 1012 public void actionPerformed(ActionEvent e) { 1013 requestOpenMRU(e); 1014 } 1015 }); 1016 menu.add(result); 1017 } 1018 } 1019 } 1020 1021 protected JMenuItem createExitMI() { 1022 JMenuItem result = new JMenuItem("Exit"); 1023 result.setMnemonic('x'); 1024 result.addActionListener(new ActionListener() { 1025 public void actionPerformed(ActionEvent e) { 1026 requestExit(); 1027 } 1028 }); 1029 return result; 1030 } 1031 1032 protected JMenu createConfigureMenu() { 1033 JMenu configureMenu = new JMenu("Configure"); 1034 configureMenu.setMnemonic('c'); 1035 configureMenu.add(createConfigureSave()); 1036 configureMenu.add(createConfigureReset()); 1037 configureMenu.add(createConfigureMaxRecords()); 1038 1039 return configureMenu; 1040 } 1041 1042 protected JMenuItem createConfigureSave() { 1043 JMenuItem result = new JMenuItem("Save"); 1044 result.setMnemonic('s'); 1045 result.addActionListener(new ActionListener() { 1046 public void actionPerformed(ActionEvent e) { 1047 saveConfiguration(); 1048 } 1049 }); 1050 1051 return result; 1052 } 1053 1054 protected JMenuItem createConfigureReset() { 1055 JMenuItem result = new JMenuItem("Reset"); 1056 result.setMnemonic('r'); 1057 result.addActionListener(new ActionListener() { 1058 public void actionPerformed(ActionEvent e) { 1059 resetConfiguration(); 1060 } 1061 }); 1062 1063 return result; 1064 } 1065 1066 protected JMenuItem createConfigureMaxRecords() { 1067 JMenuItem result = new JMenuItem("Set Max Number of Records"); 1068 result.setMnemonic('m'); 1069 result.addActionListener(new ActionListener() { 1070 public void actionPerformed(ActionEvent e) { 1071 setMaxRecordConfiguration(); 1072 } 1073 }); 1074 1075 return result; 1076 } 1077 1078 1079 protected void saveConfiguration() { 1080 _configurationManager.save(); 1081 } 1082 1083 protected void resetConfiguration() { 1084 _configurationManager.reset(); 1085 } 1086 1087 protected void setMaxRecordConfiguration() { 1088 LogFactor5InputDialog inputDialog = new LogFactor5InputDialog( 1089 getBaseFrame(), "Set Max Number of Records", "", 10); 1090 1091 String temp = inputDialog.getText(); 1092 1093 if (temp != null) { 1094 try { 1095 setMaxNumberOfLogRecords(Integer.parseInt(temp)); 1096 } catch (NumberFormatException e) { 1097 LogFactor5ErrorDialog error = new LogFactor5ErrorDialog( 1098 getBaseFrame(), 1099 "'" + temp + "' is an invalid parameter.\nPlease try again."); 1100 setMaxRecordConfiguration(); 1101 } 1102 } 1103 } 1104 1105 1106 protected JMenu createHelpMenu() { 1107 JMenu helpMenu = new JMenu("Help"); 1108 helpMenu.setMnemonic('h'); 1109 helpMenu.add(createHelpProperties()); 1110 return helpMenu; 1111 } 1112 1113 protected JMenuItem createHelpProperties() { 1114 final String title = "LogFactor5 Properties"; 1115 final JMenuItem result = new JMenuItem(title); 1116 result.setMnemonic('l'); 1117 result.addActionListener(new ActionListener() { 1118 public void actionPerformed(ActionEvent e) { 1119 showPropertiesDialog(title); 1120 } 1121 }); 1122 return result; 1123 } 1124 1125 protected void showPropertiesDialog(String title) { 1126 JOptionPane.showMessageDialog( 1127 _logMonitorFrame, 1128 _displayedLogBrokerProperties.toArray(), 1129 title, 1130 JOptionPane.PLAIN_MESSAGE 1131 ); 1132 } 1133 1134 protected JMenu createEditMenu() { 1135 JMenu editMenu = new JMenu("Edit"); 1136 editMenu.setMnemonic('e'); 1137 editMenu.add(createEditFindMI()); 1138 editMenu.add(createEditFindNextMI()); 1139 editMenu.addSeparator(); 1140 editMenu.add(createEditSortNDCMI()); 1141 editMenu.add(createEditRestoreAllNDCMI()); 1142 return editMenu; 1143 } 1144 1145 protected JMenuItem createEditFindNextMI() { 1146 JMenuItem editFindNextMI = new JMenuItem("Find Next"); 1147 editFindNextMI.setMnemonic('n'); 1148 editFindNextMI.setAccelerator(KeyStroke.getKeyStroke("F3")); 1149 editFindNextMI.addActionListener(new ActionListener() { 1150 public void actionPerformed(ActionEvent e) { 1151 findSearchText(); 1152 } 1153 }); 1154 return editFindNextMI; 1155 } 1156 1157 protected JMenuItem createEditFindMI() { 1158 JMenuItem editFindMI = new JMenuItem("Find"); 1159 editFindMI.setMnemonic('f'); 1160 editFindMI.setAccelerator(KeyStroke.getKeyStroke("control F")); 1161 1162 editFindMI.addActionListener( 1163 new ActionListener() { 1164 public void actionPerformed(ActionEvent e) { 1165 String inputValue = 1166 JOptionPane.showInputDialog( 1167 _logMonitorFrame, 1168 "Find text: ", 1169 "Search Record Messages", 1170 JOptionPane.QUESTION_MESSAGE 1171 ); 1172 setSearchText(inputValue); 1173 findSearchText(); 1174 } 1175 } 1176 1177 ); 1178 return editFindMI; 1179 } 1180 1181 // Added version 1.2 - Allows users to Sort Log Records by an 1182 // NDC text filter. A new LogRecordFilter was created to 1183 // sort the records. 1184 protected JMenuItem createEditSortNDCMI() { 1185 JMenuItem editSortNDCMI = new JMenuItem("Sort by NDC"); 1186 editSortNDCMI.setMnemonic('s'); 1187 editSortNDCMI.addActionListener( 1188 new ActionListener() { 1189 public void actionPerformed(ActionEvent e) { 1190 String inputValue = 1191 JOptionPane.showInputDialog( 1192 _logMonitorFrame, 1193 "Sort by this NDC: ", 1194 "Sort Log Records by NDC", 1195 JOptionPane.QUESTION_MESSAGE 1196 ); 1197 setNDCTextFilter(inputValue); 1198 sortByNDC(); 1199 _table.getFilteredLogTableModel().refresh(); 1200 updateStatusLabel(); 1201 } 1202 } 1203 1204 ); 1205 return editSortNDCMI; 1206 } 1207 1208 // Added in version 1.2 - Resets the LogRecordFilter back to default 1209 // filter. 1210 protected JMenuItem createEditRestoreAllNDCMI() { 1211 JMenuItem editRestoreAllNDCMI = new JMenuItem("Restore all NDCs"); 1212 editRestoreAllNDCMI.setMnemonic('r'); 1213 editRestoreAllNDCMI.addActionListener( 1214 new ActionListener() { 1215 public void actionPerformed(ActionEvent e) { 1216 _table.getFilteredLogTableModel().setLogRecordFilter(createLogRecordFilter()); 1217 // reset the text filter 1218 setNDCTextFilter(""); 1219 _table.getFilteredLogTableModel().refresh(); 1220 updateStatusLabel(); 1221 } 1222 } 1223 ); 1224 return editRestoreAllNDCMI; 1225 } 1226 1227 protected JToolBar createToolBar() { 1228 JToolBar tb = new JToolBar(); 1229 tb.putClientProperty("JToolBar.isRollover", Boolean.TRUE); 1230 JComboBox fontCombo = new JComboBox(); 1231 JComboBox fontSizeCombo = new JComboBox(); 1232 _fontSizeCombo = fontSizeCombo; 1233 1234 ClassLoader cl = this.getClass().getClassLoader(); 1235 if(cl == null) { 1236 cl = ClassLoader.getSystemClassLoader(); 1237 } 1238 URL newIconURL = cl.getResource("org/apache/log4j/lf5/viewer/" + 1239 "images/channelexplorer_new.gif"); 1240 1241 ImageIcon newIcon = null; 1242 1243 if (newIconURL != null) { 1244 newIcon = new ImageIcon(newIconURL); 1245 } 1246 1247 JButton newButton = new JButton("Clear Log Table"); 1248 1249 if (newIcon != null) { 1250 newButton.setIcon(newIcon); 1251 } 1252 1253 newButton.setToolTipText("Clear Log Table."); 1254 //newButton.setBorder(BorderFactory.createEtchedBorder()); 1255 1256 newButton.addActionListener( 1257 new ActionListener() { 1258 public void actionPerformed(ActionEvent e) { 1259 _table.clearLogRecords(); 1260 _categoryExplorerTree.getExplorerModel().resetAllNodeCounts(); 1261 updateStatusLabel(); 1262 clearDetailTextArea(); 1263 LogRecord.resetSequenceNumber(); 1264 } 1265 } 1266 ); 1267 1268 Toolkit tk = Toolkit.getDefaultToolkit(); 1269 // This will actually grab all the fonts 1270 1271 String[] fonts; 1272 1273 if (_loadSystemFonts) { 1274 fonts = GraphicsEnvironment. 1275 getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); 1276 } else { 1277 fonts = tk.getFontList(); 1278 } 1279 1280 for (int j = 0; j < fonts.length; j++) { 1281 fontCombo.addItem(fonts[j]); 1282 } 1283 1284 fontCombo.setSelectedItem(_fontName); 1285 1286 fontCombo.addActionListener( 1287 1288 new ActionListener() { 1289 public void actionPerformed(ActionEvent e) { 1290 JComboBox box = (JComboBox) e.getSource(); 1291 String font = (String) box.getSelectedItem(); 1292 _table.setFont(new Font(font, Font.PLAIN, _fontSize)); 1293 _fontName = font; 1294 } 1295 } 1296 ); 1297 1298 fontSizeCombo.addItem("8"); 1299 fontSizeCombo.addItem("9"); 1300 fontSizeCombo.addItem("10"); 1301 fontSizeCombo.addItem("12"); 1302 fontSizeCombo.addItem("14"); 1303 fontSizeCombo.addItem("16"); 1304 fontSizeCombo.addItem("18"); 1305 fontSizeCombo.addItem("24"); 1306 1307 fontSizeCombo.setSelectedItem(String.valueOf(_fontSize)); 1308 fontSizeCombo.addActionListener( 1309 new ActionListener() { 1310 public void actionPerformed(ActionEvent e) { 1311 JComboBox box = (JComboBox) e.getSource(); 1312 String size = (String) box.getSelectedItem(); 1313 int s = Integer.valueOf(size).intValue(); 1314 1315 setFontSizeSilently(s); 1316 refreshDetailTextArea(); 1317 _fontSize = s; 1318 } 1319 } 1320 ); 1321 1322 tb.add(new JLabel(" Font: ")); 1323 tb.add(fontCombo); 1324 tb.add(fontSizeCombo); 1325 tb.addSeparator(); 1326 tb.addSeparator(); 1327 tb.add(newButton); 1328 1329 newButton.setAlignmentY(0.5f); 1330 newButton.setAlignmentX(0.5f); 1331 1332 fontCombo.setMaximumSize(fontCombo.getPreferredSize()); 1333 fontSizeCombo.setMaximumSize( 1334 fontSizeCombo.getPreferredSize()); 1335 1336 return (tb); 1337 } 1338 1339// protected void setView(String viewString, LogTable table) { 1340// if (STANDARD_VIEW.equals(viewString)) { 1341// table.setStandardView(); 1342// } else if (COMPACT_VIEW.equals(viewString)) { 1343// table.setCompactView(); 1344// } else if (DETAILED_VIEW.equals(viewString)) { 1345// table.setDetailedView(); 1346// } else { 1347// String message = viewString + "does not match a supported view."; 1348// throw new IllegalArgumentException(message); 1349// } 1350// _currentView = viewString; 1351// } 1352 1353 protected void setView(String viewString, LogTable table) { 1354 if (DETAILED_VIEW.equals(viewString)) { 1355 table.setDetailedView(); 1356 } else { 1357 String message = viewString + "does not match a supported view."; 1358 throw new IllegalArgumentException(message); 1359 } 1360 _currentView = viewString; 1361 } 1362 1363 protected JComboBox createLogLevelCombo() { 1364 JComboBox result = new JComboBox(); 1365 Iterator levels = getLogLevels(); 1366 while (levels.hasNext()) { 1367 result.addItem(levels.next()); 1368 } 1369 result.setSelectedItem(_leastSevereDisplayedLogLevel); 1370 1371 result.addActionListener(new ActionListener() { 1372 public void actionPerformed(ActionEvent e) { 1373 JComboBox box = (JComboBox) e.getSource(); 1374 LogLevel level = (LogLevel) box.getSelectedItem(); 1375 setLeastSevereDisplayedLogLevel(level); 1376 } 1377 }); 1378 result.setMaximumSize(result.getPreferredSize()); 1379 return result; 1380 } 1381 1382 protected void setLeastSevereDisplayedLogLevel(LogLevel level) { 1383 if (level == null || _leastSevereDisplayedLogLevel == level) { 1384 return; // nothing to do 1385 } 1386 _leastSevereDisplayedLogLevel = level; 1387 _table.getFilteredLogTableModel().refresh(); 1388 updateStatusLabel(); 1389 } 1390 1391 /** 1392 * Ensures that the Table's ScrollPane Viewport will "track" with updates 1393 * to the Table. When the vertical scroll bar is at its bottom anchor 1394 * and tracking is enabled then viewport will stay at the bottom most 1395 * point of the component. The purpose of this feature is to allow 1396 * a developer to watch the table as messages arrive and not have to 1397 * scroll after each new message arrives. When the vertical scroll bar 1398 * is at any other location, then no tracking will happen. 1399 * @deprecated tracking is now done automatically. 1400 */ 1401 protected void trackTableScrollPane() { 1402 // do nothing 1403 } 1404 1405 protected void centerFrame(JFrame frame) { 1406 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); 1407 Dimension comp = frame.getSize(); 1408 1409 frame.setLocation(((screen.width - comp.width) / 2), 1410 ((screen.height - comp.height) / 2)); 1411 1412 } 1413 1414 /** 1415 * Uses a JFileChooser to select a file to opened with the 1416 * LF5 GUI. 1417 */ 1418 protected void requestOpen() { 1419 JFileChooser chooser; 1420 1421 if (_fileLocation == null) { 1422 chooser = new JFileChooser(); 1423 } else { 1424 chooser = new JFileChooser(_fileLocation); 1425 } 1426 1427 int returnVal = chooser.showOpenDialog(_logMonitorFrame); 1428 if (returnVal == JFileChooser.APPROVE_OPTION) { 1429 File f = chooser.getSelectedFile(); 1430 if (loadLogFile(f)) { 1431 _fileLocation = chooser.getSelectedFile(); 1432 _mruFileManager.set(f); 1433 updateMRUList(); 1434 } 1435 } 1436 } 1437 1438 /** 1439 * Uses a Dialog box to accept a URL to a file to be opened 1440 * with the LF5 GUI. 1441 */ 1442 protected void requestOpenURL() { 1443 LogFactor5InputDialog inputDialog = new LogFactor5InputDialog( 1444 getBaseFrame(), "Open URL", "URL:"); 1445 String temp = inputDialog.getText(); 1446 1447 if (temp != null) { 1448 if (temp.indexOf("://") == -1) { 1449 temp = "http://" + temp; 1450 } 1451 1452 try { 1453 URL url = new URL(temp); 1454 if (loadLogFile(url)) { 1455 _mruFileManager.set(url); 1456 updateMRUList(); 1457 } 1458 } catch (MalformedURLException e) { 1459 LogFactor5ErrorDialog error = new LogFactor5ErrorDialog( 1460 getBaseFrame(), "Error reading URL."); 1461 } 1462 } 1463 } 1464 1465 /** 1466 * Removes old file list and creates a new file list 1467 * with the updated MRU list. 1468 */ 1469 protected void updateMRUList() { 1470 JMenu menu = _logMonitorFrame.getJMenuBar().getMenu(0); 1471 menu.removeAll(); 1472 menu.add(createOpenMI()); 1473 menu.add(createOpenURLMI()); 1474 menu.addSeparator(); 1475 menu.add(createCloseMI()); 1476 createMRUFileListMI(menu); 1477 menu.addSeparator(); 1478 menu.add(createExitMI()); 1479 } 1480 1481 protected void requestClose() { 1482 setCallSystemExitOnClose(false); 1483 closeAfterConfirm(); 1484 } 1485 1486 /** 1487 * Opens a file in the MRU list. 1488 */ 1489 protected void requestOpenMRU(ActionEvent e) { 1490 String file = e.getActionCommand(); 1491 StringTokenizer st = new StringTokenizer(file); 1492 String num = st.nextToken().trim(); 1493 file = st.nextToken("\n"); 1494 1495 try { 1496 int index = Integer.parseInt(num) - 1; 1497 1498 InputStream in = _mruFileManager.getInputStream(index); 1499 LogFileParser lfp = new LogFileParser(in); 1500 lfp.parse(this); 1501 1502 _mruFileManager.moveToTop(index); 1503 updateMRUList(); 1504 1505 } catch (Exception me) { 1506 LogFactor5ErrorDialog error = new LogFactor5ErrorDialog( 1507 getBaseFrame(), "Unable to load file " + file); 1508 } 1509 1510 } 1511 1512 protected void requestExit() { 1513 _mruFileManager.save(); 1514 setCallSystemExitOnClose(true); 1515 closeAfterConfirm(); 1516 } 1517 1518 protected void closeAfterConfirm() { 1519 StringBuffer message = new StringBuffer(); 1520 1521 if (_callSystemExitOnClose == false) { 1522 message.append("Are you sure you want to close the logging "); 1523 message.append("console?\n"); 1524 message.append("(Note: This will not shut down the Virtual Machine,\n"); 1525 message.append("or the Swing event thread.)"); 1526 } else { 1527 message.append("Are you sure you want to exit?\n"); 1528 message.append("This will shut down the Virtual Machine.\n"); 1529 } 1530 1531 String title = 1532 "Are you sure you want to dispose of the Logging Console?"; 1533 1534 if (_callSystemExitOnClose == true) { 1535 title = "Are you sure you want to exit?"; 1536 } 1537 int value = JOptionPane.showConfirmDialog( 1538 _logMonitorFrame, 1539 message.toString(), 1540 title, 1541 JOptionPane.OK_CANCEL_OPTION, 1542 JOptionPane.QUESTION_MESSAGE, 1543 null 1544 ); 1545 1546 if (value == JOptionPane.OK_OPTION) { 1547 dispose(); 1548 } 1549 } 1550 1551 protected Iterator getLogLevels() { 1552 return _levels.iterator(); 1553 } 1554 1555 protected Iterator getLogTableColumns() { 1556 return _columns.iterator(); 1557 } 1558 1559 /** 1560 * Loads and parses a log file. 1561 */ 1562 protected boolean loadLogFile(File file) { 1563 boolean ok = false; 1564 try { 1565 LogFileParser lfp = new LogFileParser(file); 1566 lfp.parse(this); 1567 ok = true; 1568 } catch (IOException e) { 1569 LogFactor5ErrorDialog error = new LogFactor5ErrorDialog( 1570 getBaseFrame(), "Error reading " + file.getName()); 1571 } 1572 1573 return ok; 1574 } 1575 1576 /** 1577 * Loads a parses a log file running on a server. 1578 */ 1579 protected boolean loadLogFile(URL url) { 1580 boolean ok = false; 1581 try { 1582 LogFileParser lfp = new LogFileParser(url.openStream()); 1583 lfp.parse(this); 1584 ok = true; 1585 } catch (IOException e) { 1586 LogFactor5ErrorDialog error = new LogFactor5ErrorDialog( 1587 getBaseFrame(), "Error reading URL:" + url.getFile()); 1588 } 1589 return ok; 1590 } 1591 //-------------------------------------------------------------------------- 1592 // Private Methods: 1593 //-------------------------------------------------------------------------- 1594 1595 //-------------------------------------------------------------------------- 1596 // Nested Top-Level Classes or Interfaces: 1597 //-------------------------------------------------------------------------- 1598 1599 class LogBrokerMonitorWindowAdaptor extends WindowAdapter { 1600 protected LogBrokerMonitor _monitor; 1601 1602 public LogBrokerMonitorWindowAdaptor(LogBrokerMonitor monitor) { 1603 _monitor = monitor; 1604 } 1605 1606 public void windowClosing(WindowEvent ev) { 1607 _monitor.requestClose(); 1608 } 1609 } 1610} 1611 1612