View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.log4j.chainsaw;
19  
20  import org.apache.log4j.chainsaw.color.Colorizer;
21  import org.apache.log4j.chainsaw.icons.LevelIconFactory;
22  import org.apache.log4j.helpers.Constants;
23  import org.apache.log4j.spi.LoggingEvent;
24  
25  import java.awt.Color;
26  import java.awt.Component;
27  
28  import java.text.DateFormat;
29  import java.text.SimpleDateFormat;
30  
31  import java.util.Date;
32  import java.util.Map;
33  
34  import javax.swing.BorderFactory;
35  import javax.swing.Icon;
36  import javax.swing.JLabel;
37  import javax.swing.JTable;
38  import javax.swing.SwingConstants;
39  import javax.swing.table.DefaultTableCellRenderer;
40  
41  
42  /***
43   * A specific TableCellRenderer that colourizes a particular cell based on
44   * some ColourFilters that have been stored according to the value for the row
45   *
46   * @author Claude Duguay
47   * @author Scott Deboy <sdeboy@apache.org>
48   * @author Paul Smith <psmith@apache.org>
49   *
50   */
51  public class TableColorizingRenderer extends DefaultTableCellRenderer {
52    private static final DateFormat DATE_FORMATTER =
53      new SimpleDateFormat(Constants.ISO8601_PATTERN);
54    private static final Map iconMap =
55      LevelIconFactory.getInstance().getLevelToIconMap();
56    private Colorizer colorizer;
57    private final JLabel idComponent = new JLabel();
58    private final JLabel levelComponent = new JLabel();
59    private boolean levelUseIcons = true;
60    private DateFormat dateFormatInUse = DATE_FORMATTER;
61    private int loggerPrecision = 0;
62    private boolean toolTipsVisible;
63  
64    /***
65     * Creates a new TableColorizingRenderer object.
66     */
67    public TableColorizingRenderer(Colorizer colorizer) {
68      this.colorizer = colorizer;
69      idComponent.setBorder(BorderFactory.createRaisedBevelBorder());
70      idComponent.setBackground(Color.gray);
71      idComponent.setHorizontalAlignment(SwingConstants.CENTER);
72      idComponent.setOpaque(true);
73  
74      levelComponent.setOpaque(true);
75      levelComponent.setHorizontalAlignment(SwingConstants.CENTER);
76  
77      levelComponent.setText("");
78    }
79    
80    public void setToolTipsVisible(boolean toolTipsVisible) {
81        this.toolTipsVisible = toolTipsVisible;
82    }
83  
84    public Component getTableCellRendererComponent(
85      final JTable table, Object value, boolean isSelected, boolean hasFocus,
86      int row, int col) {
87      value = formatField(value);
88  
89      JLabel c = (JLabel)super.getTableCellRendererComponent(table, value, 
90          isSelected, hasFocus, row, col);
91      int colIndex = table.getColumnModel().getColumn(col).getModelIndex() + 1;
92  
93      switch (colIndex) {
94      case ChainsawColumns.INDEX_ID_COL_NAME:
95        idComponent.setText(value.toString());
96        idComponent.setForeground(c.getForeground());
97        idComponent.setBackground(c.getBackground());
98        c = idComponent;
99        break;
100 
101     case ChainsawColumns.INDEX_THROWABLE_COL_NAME:
102       if (value instanceof String[]) {
103         c.setText(((String[]) value)[0]);
104       }
105       break;
106 
107     case ChainsawColumns.INDEX_LOGGER_COL_NAME:
108       if (loggerPrecision == 0) {
109         break;
110       }
111       String logger = value.toString();
112       int startPos = -1;
113 
114       for (int i = 0; i < loggerPrecision; i++) {
115         startPos = logger.indexOf(".", startPos + 1);
116         if (startPos < 0) {
117           break;
118         }
119       }
120 
121     c.setText(logger.substring(startPos + 1));
122       break;
123 
124     case ChainsawColumns.INDEX_LEVEL_COL_NAME:
125       if (levelUseIcons) {
126         levelComponent.setIcon((Icon) iconMap.get(value.toString()));
127 
128         if (levelComponent.getIcon() != null) {
129           levelComponent.setText("");
130         }
131         if (!toolTipsVisible) {
132           levelComponent.setToolTipText(value.toString());
133         }
134       } else {
135         levelComponent.setIcon(null);
136         levelComponent.setText(value.toString());
137         if (!toolTipsVisible) {
138             levelComponent.setToolTipText(null);
139         }
140       }
141       if (toolTipsVisible) {
142           levelComponent.setToolTipText(c.getToolTipText());
143       }
144       levelComponent.setForeground(c.getForeground());
145       levelComponent.setBackground(c.getBackground());
146 
147       c = levelComponent;
148       break;
149 
150     default:
151       break;
152     }
153 
154     if (isSelected) {
155       return c;
156     }
157 
158     Color background = null;
159     Color foreground = null;
160 
161     if (colorizer != null) {
162       EventContainer container = (EventContainer) table.getModel();
163       LoggingEvent event = container.getRow(row);
164 
165       if (event == null) {
166         //ignore...probably changed displayed cols
167         return c;
168       }
169       background = colorizer.getBackgroundColor(event);
170       foreground = colorizer.getForegroundColor(event);
171     }
172 
173     /***
174      * Colourize based on row striping
175      */
176     if (background == null) {
177       if ((row % 2) != 0) {
178         background = ChainsawConstants.COLOR_ODD_ROW;
179       } else {
180         background = ChainsawConstants.COLOR_EVEN_ROW;
181       }
182     }
183 
184     if (foreground == null) {
185       foreground = Color.black;
186     }
187     
188     c.setBackground(background);
189     c.setForeground(foreground);
190     
191     return c;
192   }
193 
194   /***
195    * Changes the Date Formatting object to be used for rendering dates.
196    * @param formatter
197    */
198   void setDateFormatter(DateFormat formatter) {
199     this.dateFormatInUse = formatter;
200   }
201 
202   /***
203    * Changes the Logger precision.
204    * @param precision
205    */
206   void setLoggerPrecision(String loggerPrecisionText) {
207     try {
208       loggerPrecision = Integer.parseInt(loggerPrecisionText);
209     } catch (NumberFormatException nfe) {
210         loggerPrecision = 0;
211     }
212   }
213 
214   /***
215    *Format date field
216    *
217    * @param o object
218    *
219    * @return formatted object
220    */
221   private Object formatField(Object o) {
222     if (!(o instanceof Date)) {
223       return (o == null ? "" : o);
224     }
225     return dateFormatInUse.format((Date) o);
226   }
227 
228   /***
229    * @param colorizer
230    */
231   public void setColorizer(Colorizer colorizer) {
232     this.colorizer = colorizer;
233   }
234 
235    /***
236    * Sets the property which determines whether to use Icons or text
237    * for the Level column
238    * @param levelUseIcons
239    */
240   public void setLevelUseIcons(boolean levelUseIcons) {
241     this.levelUseIcons = levelUseIcons;
242   }
243 }