1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.log4j.chainsaw.messages;
19
20 import java.awt.BorderLayout;
21 import java.awt.Component;
22 import java.awt.event.ActionEvent;
23 import java.beans.PropertyChangeEvent;
24 import java.beans.PropertyChangeListener;
25 import java.beans.PropertyChangeSupport;
26
27 import javax.swing.AbstractAction;
28 import javax.swing.Action;
29 import javax.swing.DefaultListCellRenderer;
30 import javax.swing.ImageIcon;
31 import javax.swing.JButton;
32 import javax.swing.JComponent;
33 import javax.swing.JList;
34 import javax.swing.JPanel;
35 import javax.swing.JPopupMenu;
36 import javax.swing.JScrollPane;
37 import javax.swing.JToolBar;
38 import javax.swing.ListCellRenderer;
39 import javax.swing.ListModel;
40 import javax.swing.event.ListDataEvent;
41 import javax.swing.event.ListDataListener;
42
43 import org.apache.log4j.Layout;
44 import org.apache.log4j.Level;
45 import org.apache.log4j.Logger;
46 import org.apache.log4j.TTCCLayout;
47 import org.apache.log4j.chainsaw.ChainsawConstants;
48 import org.apache.log4j.chainsaw.LoggingEventWrapper;
49 import org.apache.log4j.chainsaw.PopupListener;
50 import org.apache.log4j.chainsaw.SmallButton;
51 import org.apache.log4j.chainsaw.icons.ChainsawIcons;
52 import org.apache.log4j.varia.ListModelAppender;
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 public class MessageCenter {
75 private static final MessageCenter instance = new MessageCenter();
76 private final Logger logger = Logger.getLogger(MessageCenter.class);
77 private Layout layout = new TTCCLayout();
78 private final JList messageList = new JList();
79 private final ListModelAppender appender = new ListModelAppender();
80 private ListCellRenderer listCellRenderer =
81 new LayoutListCellRenderer(layout);
82 private PropertyChangeSupport propertySupport =
83 new PropertyChangeSupport(this);
84 private JScrollPane pane = new JScrollPane(messageList);
85 private final JToolBar toolbar = new JToolBar();
86 private JPopupMenu popupMenu = new JPopupMenu();
87 private PopupListener popupListener = new PopupListener(popupMenu);
88 private Action clearAction;
89 private final JPanel componentPanel = new JPanel(new BorderLayout());
90
91 private MessageCenter() {
92 setupActions();
93 setupComponentPanel();
94 setupLogger();
95 setupListeners();
96 setupPopMenu();
97 setupToolbar();
98 }
99
100
101
102
103 private void setupPopMenu() {
104 popupMenu.add(clearAction);
105 }
106
107
108
109
110 private void setupToolbar() {
111 JButton clearButton = new SmallButton(clearAction);
112 clearButton.setText(null);
113 toolbar.add(clearButton);
114
115 toolbar.setFloatable(false);
116 }
117
118 private void setupActions() {
119 clearAction =
120 new AbstractAction("Clear") {
121 public void actionPerformed(ActionEvent e) {
122 appender.clearModel();
123 }
124 };
125 clearAction.putValue(
126 Action.SMALL_ICON, new ImageIcon(ChainsawIcons.DELETE));
127 }
128
129 private void setupListeners() {
130 propertySupport.addPropertyChangeListener(
131 "layout",
132 new PropertyChangeListener() {
133 public void propertyChange(PropertyChangeEvent evt) {
134 Layout newLayout = (Layout) evt.getNewValue();
135 messageList.setCellRenderer(new LayoutListCellRenderer(newLayout));
136 }
137 });
138 messageList.addMouseListener(popupListener);
139
140 appender.getModel().addListDataListener(
141 new ListDataListener() {
142 public void contentsChanged(ListDataEvent e) {
143 updateActions();
144 }
145
146 public void intervalAdded(ListDataEvent e) {
147 updateActions();
148 }
149
150 public void intervalRemoved(ListDataEvent e) {
151 updateActions();
152 }
153 });
154 }
155
156
157
158
159 private void updateActions() {
160 clearAction.putValue(
161 "enabled",
162 (appender.getModel().getSize() > 0) ? Boolean.TRUE : Boolean.FALSE);
163 }
164
165 private void setupLogger() {
166 logger.addAppender(appender);
167 logger.setAdditivity(true);
168 logger.setLevel(Boolean.getBoolean("log4j.debug")?Level.DEBUG:Level.INFO);
169 }
170
171 private void setupComponentPanel() {
172 messageList.setModel(appender.getModel());
173 messageList.setCellRenderer(listCellRenderer);
174
175 componentPanel.add(this.toolbar, BorderLayout.NORTH);
176 componentPanel.add(this.pane, BorderLayout.CENTER);
177 }
178
179 public final JComponent getGUIComponent() {
180 return componentPanel;
181 }
182
183 public ListModel getModel() {
184 return messageList.getModel();
185 }
186
187 public static MessageCenter getInstance() {
188 return instance;
189 }
190
191 public void addMessage(String message) {
192 logger.info(message);
193 }
194
195
196
197
198
199 public final Layout getLayout() {
200 return layout;
201 }
202
203
204
205
206 public final void setLayout(Layout layout) {
207 Layout oldValue = this.layout;
208 this.layout = layout;
209 propertySupport.firePropertyChange("layout", oldValue, this.layout);
210 }
211
212
213
214
215
216
217 public final Logger getLogger() {
218 return this.logger;
219 }
220
221
222
223
224
225
226
227 private static class LayoutListCellRenderer extends DefaultListCellRenderer {
228 private Layout layout;
229
230
231
232
233 public LayoutListCellRenderer(Layout layout) {
234 super();
235 this.layout = layout;
236 }
237
238
239
240
241 public Component getListCellRendererComponent(
242 JList list, Object value, int index, boolean isSelected,
243 boolean cellHasFocus) {
244 value = layout.format(((LoggingEventWrapper) value).getLoggingEvent());
245
246 Component c =
247 super.getListCellRendererComponent(
248 list, value, index, isSelected, cellHasFocus);
249 c.setBackground(
250 ((index % 2) == 0) ? ChainsawConstants.COLOR_EVEN_ROW_BACKGROUND
251 : ChainsawConstants.COLOR_ODD_ROW_BACKGROUND);
252
253 return c;
254 }
255 }
256 }