svn commit: r930171 - in /logging/chainsaw/trunk/src/main: java/org/apache/log4j/chainsaw/ java/org/apache/log4j/chainsaw/color/ java/org/apache/log4j/chainsaw/icons/ resources/org/apache/log4j/chainsaw/help/

[email protected]
Newsgroups gmane.comp.apache.logging
Message-ID <[email protected]>
Author: sdeboy
Date: Fri Apr  2 06:03:00 2010
New Revision: 930171

URL: http://svn.apache.org/viewvc?rev=930171&view=rev
Log:
Chainsaw updates to thumbnail panel and event container
 - event container (tablemodel) now holds ExtendedLoggingEvent instances (subclass of LoggingEvent which remembers if the event matches the current search query as well as current foreground and background colors)
 - now displaying all events matching color rules in thumbnail (not just warnings, error & fatal)
 - now displaying search matches in left half of the thumbnail (allowing you to still see the event color in the thumbnail)
 - added ctrl-n accelerator to navigate to next colorized event, ctrl-p to navigate to previous colorized event

Added:
    logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ExtendedLoggingEvent.java
Modified:
    logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ChainsawConstants.java
    logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ChainsawCyclicBufferTableModel.java
    logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ChainsawToolBarAndMenus.java
    logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/EventContainer.java
    logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanel.java
    logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/TableColorizingRenderer.java
    logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/color/RuleColorizer.java
    logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/icons/ChainsawIcons.java
    logging/chainsaw/trunk/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html

Modified: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ChainsawConstants.java
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ChainsawConstants.java?rev=930171&r1=930170&r2=930171&view=diff
==============================================================================
--- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ChainsawConstants.java (original)
+++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ChainsawConstants.java Fri Apr  2 06:03:00 2010
@@ -31,9 +31,15 @@ import java.net.URL;
 public class ChainsawConstants {
   private ChainsawConstants(){}
   
+  public static final Color COLOR_DEFAULT_BACKGROUND = new Color(255,255,255);
+  public static final Color COLOR_DEFAULT_FOREGROUND = Color.BLACK;
+
+  public static final Color FIND_LOGGER_BACKGROUND = new Color(40, 40, 40);
+  public static final Color FIND_LOGGER_FOREGROUND = Color.WHITE;
+
   public static final Color COLOR_ODD_ROW = new Color(215, 215, 215);
-  public static final Color COLOR_EVEN_ROW = new Color(255,255,255);
-  
+  public static final Color COLOR_EVEN_ROW = COLOR_DEFAULT_BACKGROUND;
+
   public static final URL WELCOME_URL = ChainsawConstants.class.getClassLoader().getResource(
   "org/apache/log4j/chainsaw/WelcomePanel.html");
   

Modified: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ChainsawCyclicBufferTableModel.java
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ChainsawCyclicBufferTableModel.java?rev=930171&r1=930170&r2=930171&view=diff
==============================================================================
--- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ChainsawCyclicBufferTableModel.java (original)
+++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ChainsawCyclicBufferTableModel.java Fri Apr  2 06:03:00 2010
@@ -35,6 +35,7 @@ import javax.swing.table.AbstractTableMo
 
 import org.apache.log4j.LogManager;
 import org.apache.log4j.Logger;
+import org.apache.log4j.chainsaw.color.RuleColorizer;
 import org.apache.log4j.chainsaw.helper.SwingHelper;
 import org.apache.log4j.helpers.Constants;
 import org.apache.log4j.rule.Rule;
@@ -73,20 +74,20 @@ class ChainsawCyclicBufferTableModel ext
   private final Logger logger = LogManager.getLogger(ChainsawCyclicBufferTableModel.class);
 
   //  protected final Object syncLock = new Object();
-  private final LoggerNameModel loggerNameModelDelegate =
-    new LoggerNameModelSupport();
+  private final LoggerNameModel loggerNameModelDelegate = new LoggerNameModelSupport();
 
   //because we may be using a cyclic buffer, if an ID is not provided in the property, 
   //use and increment this row counter as the ID for each received row
   int uniqueRow;
   private final Set uniquePropertyKeys = new HashSet();
   private Rule displayRule;
-  private final PropertyChangeSupport propertySupport =
-    new PropertyChangeSupport(this);
+  private final PropertyChangeSupport propertySupport = new PropertyChangeSupport(this);
+  private RuleColorizer colorizer;
 
-  public ChainsawCyclicBufferTableModel(int cyclicBufferSize) {
+    public ChainsawCyclicBufferTableModel(int cyclicBufferSize, RuleColorizer colorizer) {
     propertySupport.addPropertyChangeListener("cyclic", new ModelChanger());
     this.cyclicBufferSize = cyclicBufferSize;
+    this.colorizer = colorizer;
 
     unfilteredList = new CyclicBufferList(cyclicBufferSize);
     filteredList = new CyclicBufferList(cyclicBufferSize);
@@ -344,6 +345,36 @@ class ChainsawCyclicBufferTableModel ext
         }
     }
 
+    public void updateEventsWithFindRule(Rule findRule) {
+        for (Iterator iter = unfilteredList.iterator();iter.hasNext();) {
+            ((ExtendedLoggingEvent)iter.next()).evaluateSearchRule(findRule);
+        }
+    }
+
+    public int findColoredRow(int startLocation, boolean searchForward) {
+        synchronized (filteredList) {
+        if (searchForward) {
+          for (int i = startLocation; i < filteredList.size(); i++) {
+            ExtendedLoggingEvent event = (ExtendedLoggingEvent)filteredList.get(i);
+            if (!event.getColorRuleBackground().equals(ChainsawConstants.COLOR_DEFAULT_BACKGROUND) ||
+                    !event.getColorRuleForeground().equals(ChainsawConstants.COLOR_DEFAULT_FOREGROUND)) {
+                return i;
+            }
+          }
+        } else {
+          for (int i = startLocation; i > -1; i--) {
+              ExtendedLoggingEvent event = (ExtendedLoggingEvent)filteredList.get(i);
+              if (!event.getColorRuleBackground().equals(ChainsawConstants.COLOR_DEFAULT_BACKGROUND) ||
+                      !event.getColorRuleForeground().equals(ChainsawConstants.COLOR_DEFAULT_FOREGROUND)) {
+                  return i;
+            }
+          }
+        }
+      }
+
+      return -1;
+    }
+
     public int getColumnCount() {
     return columnNames.size();
   }
@@ -352,10 +383,10 @@ class ChainsawCyclicBufferTableModel ext
       return (String) columnNames.get(column);
   }
 
-  public LoggingEvent getRow(int row) {
+  public ExtendedLoggingEvent getRow(int row) {
     synchronized (filteredList) {
       if (row < filteredList.size()) {
-        return (LoggingEvent) filteredList.get(row);
+        return (ExtendedLoggingEvent) filteredList.get(row);
       }
     }
 
@@ -461,7 +492,13 @@ class ChainsawCyclicBufferTableModel ext
     return "";
   }
 
-  public boolean isAddRow(LoggingEvent e) {
+  public boolean isAddRow(ExtendedLoggingEvent e) {
+    e.updateColorRuleColors(colorizer.getBackgroundColor(e), colorizer.getForegroundColor(e));
+    Rule findRule = colorizer.getFindRule();
+    if (findRule != null) {
+      e.evaluateSearchRule(colorizer.getFindRule());
+    }
+
     boolean rowAdded = false;
 
     Object id = e.getProperty(Constants.LOG4J_ID_KEY);
@@ -480,7 +517,7 @@ class ChainsawCyclicBufferTableModel ext
     if (isCyclic()) {
             CyclicBufferList bufferList = (CyclicBufferList) unfilteredList;
             if (bufferList.size() == bufferList.getMaxSize()) {
-                LoggingEvent aboutToBeDropped = (LoggingEvent) unfilteredList.get(0);
+                ExtendedLoggingEvent aboutToBeDropped = (ExtendedLoggingEvent) unfilteredList.get(0);
                 reachedCapacity = true;
             }
     }
@@ -498,7 +535,7 @@ class ChainsawCyclicBufferTableModel ext
     return rowAdded;
   }
 
-   private void checkForNewColumn(LoggingEvent e)
+   private void checkForNewColumn(ExtendedLoggingEvent e)
    {
       /**
        * Is this a new Property key we haven't seen before?  Remember that now MDC has been merged
@@ -561,6 +598,13 @@ class ChainsawCyclicBufferTableModel ext
   }
 
     public void fireRowUpdated(int row, boolean checkForNewColumns) {
+        ExtendedLoggingEvent event = getRow(row);
+        event.updateColorRuleColors(colorizer.getBackgroundColor(event), colorizer.getForegroundColor(event));
+        Rule findRule = colorizer.getFindRule();
+        if (findRule != null) {
+          event.evaluateSearchRule(colorizer.getFindRule());
+        }
+
         fireTableRowsUpdated(row, row);
         if (checkForNewColumns) {
             //row may have had a column added..if so, make sure a column is added

Modified: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ChainsawToolBarAndMenus.java
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ChainsawToolBarAndMenus.java?rev=930171&r1=930170&r2=930171&view=diff
==============================================================================
--- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ChainsawToolBarAndMenus.java (original)
+++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ChainsawToolBarAndMenus.java Fri Apr  2 06:03:00 2010
@@ -77,6 +77,8 @@ class ChainsawToolBarAndMenus implements
   private final Action closeAction;
   private final Action findNextAction;
   private final Action findPreviousAction;
+  private final Action findPreviousColorizedEventAction;
+  private final Action findNextColorizedEventAction;
   private final Action findNextMarkerAction;
   private final Action findPreviousMarkerAction;
   private final Action toggleMarkerAction;
@@ -132,6 +134,8 @@ class ChainsawToolBarAndMenus implements
     findNextAction = getFindNextAction();
     findPreviousAction = getFindPreviousAction();
     findNextMarkerAction = createFindNextMarkerAction();
+    findPreviousColorizedEventAction = getFindPreviousColorizedEventAction();
+    findNextColorizedEventAction = getFindNextColorizedEventAction();
     findPreviousMarkerAction = createFindPreviousMarkerAction();
     toggleMarkerAction = createToggleMarkerAction();
     clearAllMarkersAction = createClearAllMarkersAction();
@@ -169,7 +173,8 @@ class ChainsawToolBarAndMenus implements
 
     logPanelSpecificActions =
       new Action[] {
-        pauseAction, findNextAction, findPreviousAction, findNextMarkerAction, findPreviousMarkerAction,
+        pauseAction, findNextAction, findPreviousAction, findNextColorizedEventAction, findPreviousColorizedEventAction,
+        findNextMarkerAction, findPreviousMarkerAction,
         toggleMarkerAction, clearAllMarkersAction, scrollToTopAction, clearAction,
         fileMenu.getFileSaveAction(), toggleDetailPaneAction,
         showPreferencesAction, showColorPanelAction, undockAction,
@@ -524,11 +529,13 @@ class ChainsawToolBarAndMenus implements
     activeTabMenu.add(new JMenuItem(findPreviousMarkerAction));
     activeTabMenu.add(new JMenuItem(clearAllMarkersAction));
 
+    activeTabMenu.add(new JMenuItem(findNextColorizedEventAction));
+    activeTabMenu.add(new JMenuItem(findPreviousColorizedEventAction));
+
     activeTabMenu.addSeparator();
     activeTabMenu.add(new JMenuItem(scrollToTopAction));
     activeTabMenu.add(toggleScrollToBottomMenuItem);
     activeTabMenu.add(menuItemUseRightMouse);
-
     
     viewMenu.add(showToolbarCheck);
     viewMenu.add(toggleStatusBarCheck);
@@ -771,14 +778,14 @@ class ChainsawToolBarAndMenus implements
     detailPaneButton.setText(null);
     detailPaneButton.getActionMap().put(
       toggleDetailPaneAction.getValue(Action.NAME), toggleDetailPaneAction);
-    detailPaneButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
+    detailPaneButton.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
       KeyStroke.getKeyStroke(KeyEvent.VK_D, InputEvent.ALT_MASK),
       toggleDetailPaneAction.getValue(Action.NAME));
 
     logTreePaneButton.setAction(toggleLogTreeAction);
     logTreePaneButton.getActionMap().put(
       toggleLogTreeAction.getValue(Action.NAME), toggleLogTreeAction);
-    logTreePaneButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
+    logTreePaneButton.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
       KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.ALT_MASK),
       toggleLogTreeAction.getValue(Action.NAME));
     logTreePaneButton.setText(null);
@@ -786,7 +793,7 @@ class ChainsawToolBarAndMenus implements
     scrollToBottomButton.setAction(toggleScrollToBottomAction);
     scrollToBottomButton.getActionMap().put(
       toggleScrollToBottomAction.getValue(Action.NAME), toggleScrollToBottomAction);
-    scrollToBottomButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
+    scrollToBottomButton.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
       KeyStroke.getKeyStroke(KeyEvent.VK_B, InputEvent.CTRL_MASK),
       toggleScrollToBottomAction.getValue(Action.NAME));
     scrollToBottomButton.setText(null);
@@ -1003,6 +1010,43 @@ class ChainsawToolBarAndMenus implements
     return action;
   }
 
+    private Action getFindNextColorizedEventAction() {
+      final Action action =
+        new AbstractAction("Find next colorized event") {
+          public void actionPerformed(ActionEvent e) {
+            LogPanel p = logui.getCurrentLogPanel();
+            if (p != null) {
+              p.findNextColorizedEvent();
+            }
+          }
+        };
+        action.putValue(Action.SHORT_DESCRIPTION, "Searches for the next colorized event from the current location");
+        action.putValue("enabled", Boolean.TRUE);
+        action.putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_N));
+        action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_DOWN_MASK));
+
+      return action;
+    }
+
+    private Action getFindPreviousColorizedEventAction() {
+      final Action action =
+        new AbstractAction("Find previous colorized event") {
+          public void actionPerformed(ActionEvent e) {
+            LogPanel p = logui.getCurrentLogPanel();
+
+            if (p != null) {
+              p.findPreviousColorizedEvent();
+            }
+          }
+        };
+        action.putValue(Action.SHORT_DESCRIPTION, "Searches for the next colorized event from the current location");
+        action.putValue("enabled", Boolean.TRUE);
+        action.putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_P));
+        action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_P, InputEvent.CTRL_DOWN_MASK));
+
+      return action;
+    }
+
   private JPanel getCustomExpressionPanel() {
     final JPanel panel = new JPanel(new BorderLayout());
     panel.add(

Modified: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/EventContainer.java
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/EventContainer.java?rev=930171&r1=930170&r2=930171&view=diff
==============================================================================
--- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/EventContainer.java (original)
+++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/EventContainer.java Fri Apr  2 06:03:00 2010
@@ -121,7 +121,7 @@ public interface EventContainer extends 
   /**
    * Returns the vector representing the row.
    */
-  LoggingEvent getRow(int row);
+  ExtendedLoggingEvent getRow(int row);
 
   /**
    * Return the last added row.
@@ -133,7 +133,7 @@ public interface EventContainer extends 
    * @param e event
    * @return flag representing whether or not the row is being displayed (not filtered)
    */
-  boolean isAddRow(LoggingEvent e);
+  boolean isAddRow(ExtendedLoggingEvent e);
 
   /**
    * Fire appropriate table update events for the range.
@@ -173,4 +173,18 @@ public interface EventContainer extends 
    * @param propName the property name to remove
    */
   void removePropertyFromEvents(String propName);
+
+  /**
+   * Evaluate all events against the find rule
+   * @param findRule
+   */
+  void updateEventsWithFindRule(Rule findRule);
+
+  /**
+   * Determine next row with a non-default color 
+   * @param currentRow
+   * @param forward
+   * @return
+   */
+  int findColoredRow(int currentRow, boolean forward);
 }

Added: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ExtendedLoggingEvent.java
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ExtendedLoggingEvent.java?rev=930171&view=auto
==============================================================================
--- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ExtendedLoggingEvent.java (added)
+++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/ExtendedLoggingEvent.java Fri Apr  2 06:03:00 2010
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.log4j.chainsaw;
+
+import java.awt.Color;
+
+import org.apache.log4j.rule.Rule;
+import org.apache.log4j.spi.LoggingEvent;
+
+public class ExtendedLoggingEvent extends LoggingEvent
+{
+    private Color colorRuleBackground = ChainsawConstants.COLOR_DEFAULT_BACKGROUND;
+    private Color colorRuleForeground = ChainsawConstants.COLOR_DEFAULT_FOREGROUND;
+
+    private boolean searchMatch = false;
+
+    //copy constructor
+    public ExtendedLoggingEvent(LoggingEvent e) {
+        super(e.getFQNOfLoggerClass(), e.getLogger(), e.getTimeStamp(), e.getLevel(), e.getMessage(), e.getThreadName(), e.getThrowableInformation(), e.getNDC(), e.getLocationInformation(), e.getProperties());
+    }
+
+    public void updateColorRuleColors(Color backgroundColor, Color foregroundColor) {
+        if (backgroundColor != null && foregroundColor != null) {
+            this.colorRuleBackground = backgroundColor;
+            this.colorRuleForeground = foregroundColor;
+        } else {
+            this.colorRuleBackground = ChainsawConstants.COLOR_DEFAULT_BACKGROUND;
+            this.colorRuleForeground = ChainsawConstants.COLOR_DEFAULT_FOREGROUND;
+        }
+    }
+
+    public void evaluateSearchRule(Rule searchRule) {
+        searchMatch = searchRule != null && searchRule.evaluate(this);
+    }
+
+    public Color getForeground() {
+        return searchMatch ? ChainsawConstants.FIND_LOGGER_FOREGROUND : colorRuleForeground;
+    }
+
+    public Color getBackground() {
+        return searchMatch ? ChainsawConstants.FIND_LOGGER_BACKGROUND : colorRuleBackground;
+    }
+
+    public Color getColorRuleBackground() {
+        return colorRuleBackground;
+    }
+
+    public Color getColorRuleForeground() {
+        return colorRuleForeground;
+    }
+
+    public boolean isSearchMatch() {
+        return searchMatch;
+    }
+
+    public String toString() {
+        return "ExtendedLoggingEvent - id: " + getProperty("log4jid") + " background: " + getBackground() + ", foreground: " + getForeground() + ", msg: " + getMessage();
+    }
+}

Modified: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanel.java
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanel.java?rev=930171&r1=930170&r2=930171&view=diff
==============================================================================
--- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanel.java (original)
+++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/LogPanel.java Fri Apr  2 06:03:00 2010
@@ -145,7 +145,6 @@ import org.apache.log4j.chainsaw.prefs.S
 import org.apache.log4j.chainsaw.prefs.SettingsManager;
 import org.apache.log4j.chainsaw.xstream.TableColumnConverter;
 import org.apache.log4j.helpers.Constants;
-import org.apache.log4j.rule.ColorRule;
 import org.apache.log4j.rule.ExpressionRule;
 import org.apache.log4j.rule.Rule;
 import org.apache.log4j.spi.LoggingEvent;
@@ -229,20 +228,18 @@ public class LogPanel extends DockablePa
   private final JPanel detailPanel = new JPanel(new BorderLayout());
   private final JSplitPane nameTreeAndMainPanelSplit;
   private final LoggerNameTreePanel logTreePanel;
-  private final LogPanelPreferenceModel preferenceModel =
-    new LogPanelPreferenceModel();
-  private final LogPanelPreferencePanel preferencesPanel =
-    new LogPanelPreferencePanel(preferenceModel);
+  private final LogPanelPreferenceModel preferenceModel = new LogPanelPreferenceModel();
+  private final LogPanelPreferencePanel preferencesPanel = new LogPanelPreferencePanel(preferenceModel);
   private final FilterModel filterModel = new FilterModel();
   private final RuleColorizer colorizer = new RuleColorizer();
   private final RuleMediator ruleMediator = new RuleMediator();
   private final EventDetailLayout detailLayout = new EventDetailLayout();
   private double lastDetailPanelSplitLocation = DEFAULT_DETAIL_SPLIT_LOCATION;
-  private double lastLogTreePanelSplitLocation =
-    DEFAULT_LOG_TREE_SPLIT_LOCATION;
+  private double lastLogTreePanelSplitLocation = DEFAULT_LOG_TREE_SPLIT_LOCATION;
   private Point currentPoint;
   private boolean paused = false;
   private Rule findRule;
+  private String currentFindRuleText;
   private Rule findMarkerRule;
   private final JPanel findPanel;
   private JTextField findField;
@@ -587,7 +584,7 @@ public class LogPanel extends DockablePa
     /*
      *End of preferenceModel listeners
      */
-    tableModel = new ChainsawCyclicBufferTableModel(cyclicBufferSize);
+    tableModel = new ChainsawCyclicBufferTableModel(cyclicBufferSize, colorizer);
     table = new JSortTable(tableModel);
 
     //we've mapped f2, shift f2 and ctrl-f2 to marker-related actions, unmap them from the table
@@ -1079,7 +1076,9 @@ public class LogPanel extends DockablePa
     JPanel rightPanel = new JPanel();
     rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.Y_AXIS));
     JPanel thumbNailPanel = new EventMatchThumbnail();
-    thumbNailPanel.setPreferredSize(new Dimension(10, -1));
+
+    //set thumbnail width to be a bit narrower than scrollbar width
+    thumbNailPanel.setPreferredSize(new Dimension(((Integer)UIManager.get("ScrollBar.width")).intValue() -4, -1));
     rightPanel.add(thumbNailPanel);
     eventsAndStatusPanel.add(rightPanel, BorderLayout.EAST);
 
@@ -1476,8 +1475,6 @@ public class LogPanel extends DockablePa
       new ActionListener() {
         public void actionPerformed(ActionEvent e) {
           if (currentPoint != null) {
-            int row = table.rowAtPoint(currentPoint);
-            LoggingEvent event = tableModel.getRow(row);
             renderer.setUseNormalTimes();
             tableModel.reFilter();
             menuItemDisplayNormalTimes.setEnabled(false);
@@ -1598,7 +1595,7 @@ public class LogPanel extends DockablePa
         }
         final int selectedRow = table.getSelectedRow();
         final int startingRow = table.getRowCount();
-        final LoggingEvent selectedEvent;
+        final ExtendedLoggingEvent selectedEvent;
         if (selectedRow >= 0) {
           selectedEvent = tableModel.getRow(selectedRow);
         } else {
@@ -1609,7 +1606,7 @@ public class LogPanel extends DockablePa
 
         int addedRowCount = 0;
         for (Iterator iter = events.iterator(); iter.hasNext();) {
-          LoggingEvent event = (LoggingEvent) iter.next();
+          ExtendedLoggingEvent event = new ExtendedLoggingEvent((LoggingEvent) iter.next());
 
           updateOtherModels(event);
 
@@ -2003,32 +2000,36 @@ public class LogPanel extends DockablePa
     return tableModel.isCyclic();
   }
 
-  public boolean updateRule(String ruleText) {
+  public void updateRule(String ruleText) {
     if ((ruleText == null) || (ruleText.trim().equals(""))) {
       findRule = null;
+      tableModel.updateEventsWithFindRule(null);
       colorizer.setFindRule(null);
       //reset background color in case we were previously an invalid expression
       findField.setBackground(UIManager.getColor("TextField.background"));
       findField.setToolTipText(
         "Enter expression - right click or ctrl-space for menu");
-      return false;
     } else {
       //only turn off scrolltobottom when finding something (find not empty)
       preferenceModel.setScrollToBottom(false);
+      if(ruleText.equals(currentFindRuleText)) {
+          //don't update events if rule hasn't changed (we're finding next/previous)
+          return;
+      }
+      currentFindRuleText = ruleText;
       try {
         findField.setToolTipText(
           "Enter expression - right click or ctrl-space for menu");
         findRule = ExpressionRule.getRule(ruleText);
+        tableModel.updateEventsWithFindRule(findRule);
         colorizer.setFindRule(findRule);
         //valid expression, reset background color in case we were previously an invalid expression
         findField.setBackground(UIManager.getColor("TextField.background"));
-        return true;
       } catch (IllegalArgumentException re) {
         findField.setToolTipText(re.getMessage());
         findField.setBackground(INVALID_EXPRESSION_BACKGROUND);
         colorizer.setFindRule(null);
-
-        return false;
+        tableModel.updateEventsWithFindRule(null);
       }
     }
   }
@@ -2181,7 +2182,7 @@ public class LogPanel extends DockablePa
       Action.SHORT_DESCRIPTION, "Removes all the events from the current view");
 
     final SmallButton dockClearButton = new SmallButton(undockedClearAction);
-    dockClearButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
+    dockClearButton.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
       KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, InputEvent.CTRL_MASK),
       undockedClearAction.getValue(Action.NAME));
     dockClearButton.getActionMap().put(
@@ -2211,7 +2212,7 @@ public class LogPanel extends DockablePa
       	}
       });
 
-      toggleScrollToBottomButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
+      toggleScrollToBottomButton.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
   	      KeyStroke.getKeyStroke(KeyEvent.VK_B, InputEvent.CTRL_MASK),
   	      dockToggleScrollToBottomAction.getValue(Action.NAME));
   	    toggleScrollToBottomButton.getActionMap().put(
@@ -2280,9 +2281,8 @@ public class LogPanel extends DockablePa
     undockedFindPreviousButton.getActionMap().put(
       undockedFindPreviousAction.getValue(Action.NAME),
       undockedFindPreviousAction);
-    undockedFindPreviousButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
-                              .put(
-      KeyStroke.getKeyStroke(KeyEvent.VK_F3, InputEvent.SHIFT_MASK),
+    undockedFindPreviousButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
+            KeyStroke.getKeyStroke(KeyEvent.VK_F3, InputEvent.SHIFT_MASK),
       undockedFindPreviousAction.getValue(Action.NAME));
 
     Dimension findPanelSize = new Dimension(310, 30);
@@ -2371,6 +2371,20 @@ public class LogPanel extends DockablePa
     statusBar.setNothingSelected();
   }
 
+  public void findNextColorizedEvent() {
+    int nextRow = tableModel.findColoredRow(table.getSelectedRow() + 1, true);        
+    if (nextRow > -1) {
+      table.scrollToRow(nextRow);
+    }
+  }
+
+  public void findPreviousColorizedEvent() {
+    int previousRow = tableModel.findColoredRow(table.getSelectedRow() - 1, false);
+    if (previousRow > -1) {
+      table.scrollToRow(previousRow);
+    }
+  }
+
   /**
    * Finds the next row matching the current find rule, and ensures it is made
    * visible
@@ -2381,8 +2395,7 @@ public class LogPanel extends DockablePa
 
     if (findRule != null) {
       try {
-        final int nextRow =
-          tableModel.find(findRule, table.getSelectedRow() + 1, true);
+        int nextRow = tableModel.find(findRule, table.getSelectedRow() + 1, true);
 
         if (nextRow > -1) {
           table.scrollToRow(nextRow);
@@ -2781,7 +2794,7 @@ public class LogPanel extends DockablePa
           if (evt.getClickCount() == 2) {
               int row = table.rowAtPoint(evt.getPoint());
               if (row != -1) {
-                LoggingEvent event = tableModel.getRow(row);
+                ExtendedLoggingEvent event = tableModel.getRow(row);
                 Object marker = event.getProperty(ChainsawConstants.LOG4J_MARKER_COL_NAME_LOWERCASE);
                 if (marker == null) {
                     event.setProperty(ChainsawConstants.LOG4J_MARKER_COL_NAME_LOWERCASE, "set");
@@ -2821,7 +2834,7 @@ public class LogPanel extends DockablePa
 
         currentRow = row;
 
-        LoggingEvent event = tableModel.getRow(currentRow);
+        ExtendedLoggingEvent event = tableModel.getRow(currentRow);
 
         if (event != null) {
           StringBuffer buf = new StringBuffer();
@@ -2933,7 +2946,7 @@ public class LogPanel extends DockablePa
         return;
       }
 
-	      LoggingEvent event = null;
+	      ExtendedLoggingEvent event = null;
 	      if (selectedRow != -1 && (lastRow != selectedRow)) {
 	        event = tableModel.getRow(selectedRow);
 	
@@ -2991,7 +3004,7 @@ public class LogPanel extends DockablePa
     private class MarkerCellEditor implements TableCellEditor {
         JTextField textField = new JTextField();
         Set cellEditorListeners = new HashSet();
-        private LoggingEvent currentEvent;
+        private ExtendedLoggingEvent currentEvent;
 
         public Object getCellEditorValue()
         {
@@ -3051,13 +3064,10 @@ public class LogPanel extends DockablePa
     }
 
     private class EventMatchThumbnail extends JPanel {
-        private List errors= new ArrayList();
-        private List warnings = new ArrayList();
+        private List all = new ArrayList();
+        private List findMatches = new ArrayList();
 
-        private Color WARNING_COLOR = colorizer.getDefaultWarnColor();
-        private Color ERROR_OR_FATAL_COLOR = colorizer.getDefaultErrorOrFatalColor();
-
-        private final int eventHeight = 8;
+        private final int maxEventHeight = 6;
 
         public EventMatchThumbnail() {
             configureColors();
@@ -3115,15 +3125,17 @@ public class LogPanel extends DockablePa
                     if (e.getType() == TableModelEvent.INSERT) {
 //                        System.out.println("insert - current warnings: " + warnings.size() + ", errors: " + errors.size() + ", first row: " + firstRow + ", last row: " + lastRow);
                         for (int i=firstRow;i<lastRow;i++) {
-                            LoggingEvent event = (LoggingEvent)displayedEvents.get(i);
-                            if (isWarningEvent(event)) {
-                                warnings.add(new EventWrapper(i, event));
+                            ExtendedLoggingEvent event = (ExtendedLoggingEvent)displayedEvents.get(i);
+                            EventWrapper wrapper = new EventWrapper(i, event);
+                            if (event.isSearchMatch()) {
+                                findMatches.add(wrapper);
 //                                System.out.println("added warning: " + i + " - " + event.getLevel());
                             }
-                            if (isErrorOrFatalEvent(event)) {
-                                errors.add(new EventWrapper(i, event));
-//                                System.out.println("added error: " + i + " - " + event.getLevel());
+                            if (!wrapper.loggingEvent.getColorRuleBackground().equals(ChainsawConstants.COLOR_DEFAULT_BACKGROUND)) {
+                                //add to this one
+                                all.add(wrapper);
                             }
+//                                System.out.println("added error: " + i + " - " + event.getLevel());
                         }
 //                        System.out.println("insert- new warnings: " + warnings + ", errors: " + errors);
 
@@ -3131,14 +3143,14 @@ public class LogPanel extends DockablePa
                     } else if (e.getType() == TableModelEvent.DELETE) {
                         //find each eventwrapper with an id in the deleted range and remove it...
 //                        System.out.println("delete- current warnings: " + warnings.size() + ", errors: " + errors.size() + ", first row: " + firstRow + ", last row: " + lastRow + ", displayed event count: " + displayedEvents.size() );
-                        for (Iterator iter = warnings.iterator();iter.hasNext();) {
+                        for (Iterator iter = findMatches.iterator();iter.hasNext();) {
                             EventWrapper wrapper = (EventWrapper)iter.next();
                             if ((wrapper.rowNum >= firstRow) && (wrapper.rowNum <= lastRow)) {
-//                                System.out.println("deleting warning: " + wrapper);
+//                                System.out.println("deleting find: " + wrapper);
                                 iter.remove();
                             }
                         }
-                        for (Iterator iter = errors.iterator();iter.hasNext();) {
+                        for (Iterator iter = all.iterator();iter.hasNext();) {
                             EventWrapper wrapper = (EventWrapper)iter.next();
                             if ((wrapper.rowNum >= firstRow) && (wrapper.rowNum <= lastRow)) {
 //                                System.out.println("deleting error: " + wrapper);
@@ -3151,14 +3163,14 @@ public class LogPanel extends DockablePa
                     } else if (e.getType() == TableModelEvent.UPDATE) {
 //                        System.out.println("update - about to delete old warnings in range: " + firstRow + " to " + lastRow + ", current warnings: " + warnings.size() + ", errors: " + errors.size());
                         //find each eventwrapper with an id in the deleted range and remove it...
-                        for (Iterator iter = warnings.iterator();iter.hasNext();) {
+                        for (Iterator iter = findMatches.iterator();iter.hasNext();) {
                             EventWrapper wrapper = (EventWrapper)iter.next();
                             if ((wrapper.rowNum >= firstRow) && (wrapper.rowNum <= lastRow)) {
 //                                System.out.println("update - deleting warning: " + wrapper);
                                 iter.remove();
                             }
                         }
-                        for (Iterator iter = errors.iterator();iter.hasNext();) {
+                        for (Iterator iter = all.iterator();iter.hasNext();) {
                             EventWrapper wrapper = (EventWrapper)iter.next();
                             if ((wrapper.rowNum >= firstRow) && (wrapper.rowNum <= lastRow)) {
 //                                System.out.println("update - deleting error: " + wrapper);
@@ -3168,41 +3180,35 @@ public class LogPanel extends DockablePa
 //                        System.out.println("update - after deleting old warnings in range: " + firstRow + " to " + lastRow + ", new warnings: " + warnings.size() + ", errors: " + errors.size());
                         //NOTE: for update, we need to do i<= lastRow
                         for (int i=firstRow;i<=lastRow;i++) {
-                            LoggingEvent event = (LoggingEvent)displayedEvents.get(i);
-                            if (isWarningEvent(event)) {
-//                                System.out.println("update - adding warning: " + i + ", event: " + event.getMessage());
-                                warnings.add(new EventWrapper(i, event));
-                            }
-                            if (isErrorOrFatalEvent(event)) {
+                            ExtendedLoggingEvent event = (ExtendedLoggingEvent)displayedEvents.get(i);
+                            EventWrapper wrapper = new EventWrapper(i, event);
 //                                System.out.println("update - adding error: " + i + ", event: " + event.getMessage());
-                                errors.add(new EventWrapper(i, event));
+                            //only add event to thumbnail if there is a color
+                            if (!wrapper.loggingEvent.getColorRuleBackground().equals(ChainsawConstants.COLOR_DEFAULT_BACKGROUND)) {
+                                all.add(wrapper);
+                            }
+
+                            if (event.isSearchMatch()) {
+//                                System.out.println("update - adding marker: " + i + ", event: " + event.getMessage());
+                                findMatches.add(wrapper);
                             }
                         }
                         //clear everything if we got an event w/-1
                         if (firstRow < 0 || lastRow < 0) {
-                            errors.clear();
-                            warnings.clear();
+                            all.clear();
+                            findMatches.clear();
                         }
 //                        System.out.println("update - new warnings: " + warnings.size() + ", errors: " + errors.size());
                     }
                     repaint();
                 }
-
-                private boolean isWarningEvent(LoggingEvent e) {
-                    return e.getLevel().equals(Level.WARN);
-                }
-
-                private boolean isErrorOrFatalEvent(LoggingEvent e) {
-                    return e.getLevel().equals(Level.ERROR) || e.getLevel().equals(Level.FATAL);
-                }
             });
         }
 
         private EventWrapper getClosestRow(int rowToSelect) {
-            //now we need to find the closest row
             EventWrapper closestRow = null;
             int rowDelta = Integer.MAX_VALUE;
-            for (Iterator iter = errors.iterator();iter.hasNext();) {
+            for (Iterator iter = findMatches.iterator();iter.hasNext();) {
                 EventWrapper event = (EventWrapper) iter.next();
                 int newRowDelta = Math.abs(rowToSelect - event.rowNum);
                 if (newRowDelta < rowDelta) {
@@ -3210,7 +3216,7 @@ public class LogPanel extends DockablePa
                     rowDelta = newRowDelta;
                 }
             }
-            for (Iterator iter = warnings.iterator();iter.hasNext();) {
+            for (Iterator iter = all.iterator();iter.hasNext();) {
                 EventWrapper event = (EventWrapper) iter.next();
                 int newRowDelta = Math.abs(rowToSelect - event.rowNum);
                 if (newRowDelta < rowDelta) {
@@ -3222,15 +3228,21 @@ public class LogPanel extends DockablePa
         }
 
         private void configureColors() {
-            List colorRules = colorizer.getCurrentRules();
-            for (Iterator iter = colorRules.iterator();iter.hasNext();) {
-                ColorRule rule = (ColorRule)iter.next();
-                String expression = rule.getExpression().toLowerCase().trim();
-                if (expression.equalsIgnoreCase(colorizer.getDefaultWarnExpression())) {
-                    WARNING_COLOR = rule.getBackgroundColor();
-                }
-                if (expression.equalsIgnoreCase(colorizer.getDefaultErrorOrFatalExpression())) {
-                    ERROR_OR_FATAL_COLOR = rule.getBackgroundColor();
+            findMatches.clear();
+            all.clear();
+
+            int i=0;
+            for (Iterator iter = tableModel.getFilteredEvents().iterator();iter.hasNext();) {
+                ExtendedLoggingEvent extendedLoggingEvent = (ExtendedLoggingEvent) iter.next();
+                extendedLoggingEvent.updateColorRuleColors(colorizer.getBackgroundColor(extendedLoggingEvent), colorizer.getForegroundColor(extendedLoggingEvent));
+                EventWrapper wrapper = new EventWrapper(i, extendedLoggingEvent);
+                if (extendedLoggingEvent.isSearchMatch()) {
+                    findMatches.add(wrapper);
+                }
+                i++;
+                //only add if there is a color defined
+                if (!wrapper.loggingEvent.getColorRuleBackground().equals(ChainsawConstants.COLOR_DEFAULT_BACKGROUND)) {
+                    all.add(wrapper);
                 }
             }
             repaint();
@@ -3261,6 +3273,7 @@ public class LogPanel extends DockablePa
         public void paintComponent(Graphics g)
         {
             super.paintComponent(g);
+
             Point topAndBottomOffset = getScrollBarOffsets();
             int topOffset = topAndBottomOffset.x;
             int bottomOffset = topAndBottomOffset.y;
@@ -3271,41 +3284,56 @@ public class LogPanel extends DockablePa
             }
             //use event pane height as reference height - max component height will be extended by event height if
             // last row is rendered, so subtract here
-            int componentHeight = eventsPane.getHeight() - topOffset - bottomOffset - eventHeight;
+            int height = eventsPane.getHeight() - topOffset - bottomOffset;
+            int maxHeight = Math.min(maxEventHeight, (height / rowCount));
+            int minHeight = Math.max(1, maxHeight);
+            int componentHeight = height - minHeight;
+            int eventHeight = minHeight;
 
-            for (Iterator iter = warnings.iterator();iter.hasNext();) {
+            for (Iterator iter = all.iterator();iter.hasNext();) {
                 EventWrapper wrapper = (EventWrapper)iter.next();
-                float ratio = (wrapper.rowNum / (float)rowCount);
-//                System.out.println("warning - ratio: " + ratio + ", component height: " + componentHeight);
-                int verticalLocation = (int) (componentHeight * ratio) + topOffset;
-                drawEvent(WARNING_COLOR, verticalLocation, eventHeight, g);
-//                System.out.println("painting warning - rownum: " + wrapper.rowNum + ", location: " + verticalLocation + ", height: " + eventHeight + ", component height: " + componentHeight + ", row count: " + rowCount);
+                if (!wrapper.loggingEvent.getColorRuleBackground().equals(ChainsawConstants.COLOR_DEFAULT_BACKGROUND)) {
+                    float ratio = (wrapper.rowNum / (float)rowCount);
+    //                System.out.println("error - ratio: " + ratio + ", component height: " + componentHeight);
+                    int verticalLocation = (int) (componentHeight * ratio) + topOffset;
+                    drawEvent(wrapper.loggingEvent.getColorRuleBackground(), verticalLocation, eventHeight, g, false);
+    //                System.out.println("painting error - rownum: " + wrapper.rowNum + ", location: " + verticalLocation + ", height: " + eventHeight + ", component height: " + componentHeight + ", row count: " + rowCount);
+                }
             }
 
-            for (Iterator iter = errors.iterator();iter.hasNext();) {
+            for (Iterator iter = findMatches.iterator();iter.hasNext();) {
                 EventWrapper wrapper = (EventWrapper)iter.next();
                 float ratio = (wrapper.rowNum / (float)rowCount);
-//                System.out.println("error - ratio: " + ratio + ", component height: " + componentHeight);
+//                System.out.println("warning - ratio: " + ratio + ", component height: " + componentHeight);
                 int verticalLocation = (int) (componentHeight * ratio) + topOffset;
-                drawEvent(ERROR_OR_FATAL_COLOR, verticalLocation, eventHeight, g);
-//                System.out.println("painting error - rownum: " + wrapper.rowNum + ", location: " + verticalLocation + ", height: " + eventHeight + ", component height: " + componentHeight + ", row count: " + rowCount);
+                drawEvent(wrapper.loggingEvent.getBackground(), verticalLocation, eventHeight, g, true);
+//                System.out.println("painting warning - rownum: " + wrapper.rowNum + ", location: " + verticalLocation + ", height: " + eventHeight + ", component height: " + componentHeight + ", row count: " + rowCount);
             }
         }
 
-        private void drawEvent(Color newColor, int verticalLocation, int eventHeight, Graphics g) {
+        private void drawEvent(Color newColor, int verticalLocation, int eventHeight, Graphics g, boolean drawHalfWidth) {
 //            System.out.println("painting: - color: " + newColor + ", verticalLocation: " + verticalLocation + ", eventHeight: " + eventHeight);
+            int x = 1;
+            int width = getWidth() - (x * 2);
+            if (drawHalfWidth) {
+                width = (width/2);
+            }
+            //center drawing at vertical location 
+            int y = verticalLocation + (eventHeight / 2);
             Color oldColor = g.getColor();
             g.setColor(newColor);
-            g.fillRect(0, verticalLocation, getWidth(), eventHeight);
-            g.setColor(newColor.darker());
-            g.drawRect(0, verticalLocation, getWidth(), eventHeight);
+            g.fillRect(x, y, width, eventHeight);
+            if (eventHeight >= 3) {
+                g.setColor(newColor.darker());
+                g.drawRect(x, y, width, eventHeight);
+            }
             g.setColor(oldColor);
         }
 
         class EventWrapper {
             int rowNum;
-            LoggingEvent loggingEvent;
-            public EventWrapper(int rowNum, LoggingEvent loggingEvent) {
+            ExtendedLoggingEvent loggingEvent;
+            public EventWrapper(int rowNum, ExtendedLoggingEvent loggingEvent) {
                 this.rowNum = rowNum;
                 this.loggingEvent = loggingEvent;
             }

Modified: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/TableColorizingRenderer.java
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/TableColorizingRenderer.java?rev=930171&r1=930170&r2=930171&view=diff
==============================================================================
--- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/TableColorizingRenderer.java (original)
+++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/TableColorizingRenderer.java Fri Apr  2 06:03:00 2010
@@ -29,18 +29,16 @@ import java.util.TimeZone;
 
 import javax.swing.BorderFactory;
 import javax.swing.Icon;
-import javax.swing.ImageIcon;
 import javax.swing.JLabel;
 import javax.swing.JTable;
 import javax.swing.SwingConstants;
 import javax.swing.table.DefaultTableCellRenderer;
 import javax.swing.table.TableColumn;
 
-import org.apache.log4j.chainsaw.color.Colorizer;
-import org.apache.log4j.chainsaw.icons.ChainsawIcons;
+import org.apache.log4j.chainsaw.color.RuleColorizer;
 import org.apache.log4j.chainsaw.icons.LevelIconFactory;
 import org.apache.log4j.helpers.Constants;
-import org.apache.log4j.spi.LoggingEvent;
+import org.apache.log4j.rule.Rule;
 
 
 /**
@@ -53,11 +51,9 @@ import org.apache.log4j.spi.LoggingEvent
  *
  */
 public class TableColorizingRenderer extends DefaultTableCellRenderer {
-  private static final DateFormat DATE_FORMATTER =
-    new SimpleDateFormat(Constants.SIMPLE_TIME_PATTERN);
-  private static final Map iconMap =
-    LevelIconFactory.getInstance().getLevelToIconMap();
-  private Colorizer colorizer;
+  private static final DateFormat DATE_FORMATTER = new SimpleDateFormat(Constants.SIMPLE_TIME_PATTERN);
+  private static final Map iconMap = LevelIconFactory.getInstance().getLevelToIconMap();
+  private RuleColorizer colorizer;
   private final JLabel idComponent = new JLabel();
   private final JLabel levelComponent = new JLabel();
   private boolean levelUseIcons = false;
@@ -65,14 +61,13 @@ public class TableColorizingRenderer ext
   private int loggerPrecision = 0;
   private boolean toolTipsVisible;
   private String dateFormatTZ;
-  private final Icon markerIcon = new ImageIcon(ChainsawIcons.MARKER);
   private boolean useRelativeTimes = false;
   private long relativeTimestampBase;
 
     /**
    * Creates a new TableColorizingRenderer object.
    */
-  public TableColorizingRenderer(Colorizer colorizer) {
+  public TableColorizingRenderer(RuleColorizer colorizer) {
     this.colorizer = colorizer;
     idComponent.setBorder(BorderFactory.createRaisedBevelBorder());
     idComponent.setBackground(Color.gray);
@@ -101,7 +96,7 @@ public class TableColorizingRenderer ext
     int colIndex = tableColumn.getModelIndex() + 1;
 
     EventContainer container = (EventContainer) table.getModel();
-    LoggingEvent event = container.getRow(row);
+    ExtendedLoggingEvent event = container.getRow(row);
     //no event, use default renderer
     if (event == null) {
         return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
@@ -193,39 +188,26 @@ public class TableColorizingRenderer ext
         }
         break;
     }
-    //set the 'marker' icon next to the zeroth column if marker is set
-    if (col == 0) {
-      if (event.getProperty(ChainsawConstants.LOG4J_MARKER_COL_NAME_LOWERCASE) != null) {
-        c.setIcon(markerIcon);
-      } else {
-        //only null out the column if it's not the level field
-        if (colIndex != ChainsawColumns.INDEX_LEVEL_COL_NAME) {
-            c.setIcon(null);
-        }
-      }
-    }
-
     if (isSelected) {
       return c;
     }
 
-    Color background = null;
-    Color foreground = null;
-
-    if (colorizer != null) {
-
-      if (event == null) {
-        //ignore...probably changed displayed cols
-        return c;
-      }
-      background = colorizer.getBackgroundColor(event);
-      foreground = colorizer.getForegroundColor(event);
+    Color background;
+    Color foreground;
+    Rule loggerRule = colorizer.getLoggerRule();
+    //use logger colors in table instead of event colors if event passes logger rule
+    if (loggerRule != null && loggerRule.evaluate(event)) {
+        background = ChainsawConstants.FIND_LOGGER_BACKGROUND;
+        foreground = ChainsawConstants.FIND_LOGGER_FOREGROUND;
+    } else {
+        background = event.getBackground();
+        foreground = event.getForeground();
     }
 
     /**
-     * Colourize based on row striping
+     * Colourize background based on row striping if the event still has a background color
      */
-    if (background == null) {
+    if (background.equals(ChainsawConstants.COLOR_DEFAULT_BACKGROUND)) {
       if ((row % 2) != 0) {
         background = ChainsawConstants.COLOR_ODD_ROW;
       } else {
@@ -233,13 +215,9 @@ public class TableColorizingRenderer ext
       }
     }
 
-    if (foreground == null) {
-      foreground = Color.black;
-    }
-    
     c.setBackground(background);
     c.setForeground(foreground);
-    
+
     return c;
   }
 
@@ -289,13 +267,6 @@ public class TableColorizingRenderer ext
     return dateFormatInUse.format((Date) o);
   }
 
-  /**
-   * @param colorizer
-   */
-  public void setColorizer(Colorizer colorizer) {
-    this.colorizer = colorizer;
-  }
-
    /**
    * Sets the property which determines whether to use Icons or text
    * for the Level column

Modified: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/color/RuleColorizer.java
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/color/RuleColorizer.java?rev=930171&r1=930170&r2=930171&view=diff
==============================================================================
--- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/color/RuleColorizer.java (original)
+++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/color/RuleColorizer.java Fri Apr  2 06:03:00 2010
@@ -47,14 +47,14 @@ public class RuleColorizer implements Co
   private String currentRuleSet = DEFAULT_NAME;
   private Rule findRule;
   private Rule loggerRule;
-  private final Color FIND_FOREGROUND = Color.white;
-  private final Color FIND_BACKGROUND = new Color(40, 40, 40);
-  private final Color LOGGER_FOREGROUND = Color.white;
-  private final Color LOGGER_BACKGROUND = new Color(40, 40, 40);
+
   private final Color WARN_DEFAULT_COLOR = new Color(255, 255, 153);
   private final Color ERROR_OR_FATAL_DEFAULT_COLOR = new Color(255, 153, 153);
-  private final String DEFAULT_ERROR_FATAL_EXPRESSION = "level == FATAL || level == ERROR";
+  private final Color MARKER_DEFAULT_COLOR = new Color(153, 255, 153);
+
   private final String DEFAULT_WARN_EXPRESSION = "level == WARN";
+  private final String DEFAULT_ERROR_FATAL_EXPRESSION = "level == FATAL || level == ERROR";
+  private final String DEFAULT_MARKER_EXPRESSION = "prop.log4j.marker exists";
 
   public RuleColorizer() {
     List rulesList = new ArrayList();
@@ -70,42 +70,34 @@ public class RuleColorizer implements Co
         expression, ExpressionRule.getRule(expression), WARN_DEFAULT_COLOR,
         Color.black));
 
-      expression = "prop.log4j.marker exists";
+      expression = DEFAULT_MARKER_EXPRESSION;
       rulesList.add(
         new ColorRule(
-          expression, ExpressionRule.getRule(expression), new Color(153, 255, 153),
+          expression, ExpressionRule.getRule(expression), MARKER_DEFAULT_COLOR,
           Color.black));
 
     defaultRules.put(DEFAULT_NAME, rulesList);
     setRules(defaultRules);
   }
 
-  public String getDefaultWarnExpression() {
-      return DEFAULT_WARN_EXPRESSION;
-  }
-
-  public String getDefaultErrorOrFatalExpression() {
-      return DEFAULT_ERROR_FATAL_EXPRESSION;
-  }
-    
-  public Color getDefaultWarnColor() {
-      return WARN_DEFAULT_COLOR;
-  }
-
-  public Color getDefaultErrorOrFatalColor() {
-      return ERROR_OR_FATAL_DEFAULT_COLOR;
-  }
-  
   public void setLoggerRule(Rule loggerRule) {
     this.loggerRule = loggerRule;
     colorChangeSupport.firePropertyChange("colorrule", false, true);
   }
-  
+
   public void setFindRule(Rule findRule) {
     this.findRule = findRule;
     colorChangeSupport.firePropertyChange("colorrule", false, true);
   }
 
+  public Rule getFindRule() {
+    return findRule;
+  }
+
+  public Rule getLoggerRule() {
+    return loggerRule;
+  }
+
   public void setRules(Map rules) {
     this.rules = rules;
     colorChangeSupport.firePropertyChange("colorrule", false, true);
@@ -168,14 +160,6 @@ public class RuleColorizer implements Co
   }
 
   public Color getBackgroundColor(LoggingEvent event) {
-    if ((findRule != null) && findRule.evaluate(event)) {
-      return FIND_BACKGROUND;
-    }
-
-    if ((loggerRule != null) && loggerRule.evaluate(event)) {
-        return LOGGER_BACKGROUND;
-    }
-
     if (rules.containsKey(currentRuleSet)) {
       List list = (List) rules.get(currentRuleSet);
       Iterator iter = list.iterator();
@@ -193,14 +177,6 @@ public class RuleColorizer implements Co
   }
 
   public Color getForegroundColor(LoggingEvent event) {
-    if ((findRule != null) && findRule.evaluate(event)) {
-      return FIND_FOREGROUND;
-    }
-
-    if ((loggerRule != null) && loggerRule.evaluate(event)) {
-      return LOGGER_FOREGROUND;
-    }
-
     if (rules.containsKey(currentRuleSet)) {
       List list = (List) rules.get(currentRuleSet);
       Iterator iter = list.iterator();

Modified: logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/icons/ChainsawIcons.java
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/icons/ChainsawIcons.java?rev=930171&r1=930170&r2=930171&view=diff
==============================================================================
--- logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/icons/ChainsawIcons.java (original)
+++ logging/chainsaw/trunk/src/main/java/org/apache/log4j/chainsaw/icons/ChainsawIcons.java Fri Apr  2 06:03:00 2010
@@ -85,9 +85,6 @@ public class ChainsawIcons {
   public static final URL HELP =
     ChainsawIcons.class.getClassLoader().getResource(
       BASE_ICON_PATH + "Help16.gif");
-  public static final URL MARKER =
-    ChainsawIcons.class.getClassLoader().getResource(
-      BASE_ICON_PATH + "About16.gif");
   public static final Icon ICON_UP = new ImageIcon(UP);
   public static final Icon ICON_DOWN = new ImageIcon(DOWN);
   public static final Icon ICON_HELP = new ImageIcon(HELP);

Modified: logging/chainsaw/trunk/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html
URL: http://svn.apache.org/viewvc/logging/chainsaw/trunk/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html?rev=930171&r1=930170&r2=930171&view=diff
==============================================================================
--- logging/chainsaw/trunk/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html (original)
+++ logging/chainsaw/trunk/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html Fri Apr  2 06:03:00 2010
@@ -10,6 +10,15 @@
 <b>NOTE:</b> The mechanism and format used to persist settings in Chainsaw is subject to change.  If you are experiencing problems displaying events in Chainsaw, please delete everything in the $user.dir/.chainsaw directory and restart Chainsaw.
 <br>
 <h1>1.99.99</h1>
+<h2>1 Apr 2010</h2>
+<ul>
+<li>
+Updated thumbnail bar to display all events with a defined color (will include the default color rules for marker, warning, error & fatal events).
+Added search matches to thumbnail bar (will display black in the left half of the row if the row matches the search expression.
+Added ctrl-n to go to next colorized event, ctrl-p to go to previous colorized event.
+
+</li>
+</ul>
 <h2>27 Mar 2010</h2>
 <ul>
 <li>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.