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