1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.fourthline.cling.support.shared.log.impl;
17
18 import org.fourthline.cling.support.shared.CenterWindow;
19 import org.fourthline.cling.support.shared.log.LogView;
20 import org.seamless.swing.Application;
21 import org.seamless.swing.logging.LogCategorySelector;
22 import org.seamless.swing.logging.LogController;
23 import org.seamless.swing.logging.LogMessage;
24 import org.seamless.swing.logging.LogTableCellRenderer;
25 import org.seamless.swing.logging.LogTableModel;
26
27 import javax.annotation.PostConstruct;
28 import javax.enterprise.event.Event;
29 import javax.inject.Inject;
30 import javax.inject.Singleton;
31 import javax.swing.BorderFactory;
32 import javax.swing.Box;
33 import javax.swing.ImageIcon;
34 import javax.swing.JButton;
35 import javax.swing.JComboBox;
36 import javax.swing.JLabel;
37 import javax.swing.JPanel;
38 import javax.swing.JScrollPane;
39 import javax.swing.JTable;
40 import javax.swing.JToolBar;
41 import javax.swing.event.ListSelectionEvent;
42 import javax.swing.event.ListSelectionListener;
43 import java.awt.BorderLayout;
44 import java.awt.Component;
45 import java.awt.Dimension;
46 import java.awt.event.ActionEvent;
47 import java.awt.event.ActionListener;
48 import java.util.ArrayList;
49 import java.util.List;
50
51
52
53
54 @Singleton
55 public class LogViewImpl extends JPanel implements LogView {
56
57 @Inject
58 protected LogCategories logCategories;
59
60 @Inject
61 protected Event<CenterWindow> centerWindowEvent;
62
63 protected LogCategorySelector logCategorySelector;
64 protected JTable logTable;
65 protected LogTableModel logTableModel;
66
67 final protected JToolBar toolBar = new JToolBar();
68
69 final protected JButton configureButton =
70 new JButton("Options...", Application.createImageIcon(LogController.class, "img/configure.png"));
71
72 final protected JButton clearButton =
73 new JButton("Clear Log", Application.createImageIcon(LogController.class, "img/removetext.png"));
74
75 final protected JButton copyButton =
76 new JButton("Copy", Application.createImageIcon(LogController.class, "img/copyclipboard.png"));
77
78 final protected JButton expandButton =
79 new JButton("Expand", Application.createImageIcon(LogController.class, "img/viewtext.png"));
80
81 final protected JButton pauseButton =
82 new JButton("Pause/Continue Log", Application.createImageIcon(LogController.class, "img/pause.png"));
83
84 final protected JLabel pauseLabel = new JLabel(" (Active)");
85
86 final protected JComboBox expirationComboBox = new JComboBox(LogController.Expiration.values());
87
88 protected Presenter presenter;
89
90 @PostConstruct
91 public void init() {
92 setLayout(new BorderLayout());
93
94 LogController.Expiration defaultExpiration = getDefaultExpiration();
95
96 logCategorySelector = new LogCategorySelector(logCategories);
97
98 logTableModel = new LogTableModel(defaultExpiration.getSeconds());
99 logTable = new JTable(logTableModel);
100
101 logTable.setDefaultRenderer(
102 LogMessage.class,
103 new LogTableCellRenderer() {
104
105 protected ImageIcon getWarnErrorIcon() {
106 return LogViewImpl.this.getWarnErrorIcon();
107 }
108
109 protected ImageIcon getDebugIcon() {
110 return LogViewImpl.this.getDebugIcon();
111 }
112
113 protected ImageIcon getTraceIcon() {
114 return LogViewImpl.this.getTraceIcon();
115 }
116
117 protected ImageIcon getInfoIcon() {
118 return LogViewImpl.this.getInfoIcon();
119 }
120 });
121
122 logTable.setCellSelectionEnabled(false);
123 logTable.setRowSelectionAllowed(true);
124 logTable.getSelectionModel().addListSelectionListener(
125 new ListSelectionListener() {
126 public void valueChanged(ListSelectionEvent e) {
127
128 if (e.getValueIsAdjusting()) return;
129
130 if (e.getSource() == logTable.getSelectionModel()) {
131 int[] rows = logTable.getSelectedRows();
132
133 if (rows == null || rows.length == 0) {
134 copyButton.setEnabled(false);
135 expandButton.setEnabled(false);
136 } else if (rows.length == 1) {
137 copyButton.setEnabled(true);
138 LogMessage msg = (LogMessage) logTableModel.getValueAt(rows[0], 0);
139
140 if (msg.getMessage().length() > getExpandMessageCharacterLimit()) {
141 expandButton.setEnabled(true);
142 } else {
143 expandButton.setEnabled(false);
144 }
145 } else {
146 copyButton.setEnabled(true);
147 expandButton.setEnabled(false);
148 }
149 }
150 }
151 }
152 );
153
154 adjustTableUI();
155 initializeToolBar(defaultExpiration);
156
157 setPreferredSize(new Dimension(250, 100));
158 setMinimumSize(new Dimension(250, 50));
159 add(new JScrollPane(logTable), BorderLayout.CENTER);
160 add(toolBar, BorderLayout.SOUTH);
161 }
162
163 @Override
164 public Component asUIComponent() {
165 return this;
166 }
167
168 @Override
169 public void setPresenter(Presenter presenter) {
170 this.presenter = presenter;
171 }
172
173 @Override
174 public void pushMessage(LogMessage logMessage) {
175 logTableModel.pushMessage(logMessage);
176
177
178 if (!logTableModel.isPaused()) {
179 logTable.scrollRectToVisible(
180 logTable.getCellRect(logTableModel.getRowCount() - 1, 0, true)
181 );
182 }
183 }
184
185 @Override
186 public void dispose() {
187 logCategorySelector.dispose();
188 }
189
190 protected void adjustTableUI() {
191 logTable.setFocusable(false);
192 logTable.setRowHeight(18);
193 logTable.getTableHeader().setReorderingAllowed(false);
194 logTable.setBorder(BorderFactory.createEmptyBorder());
195
196 logTable.getColumnModel().getColumn(0).setMinWidth(30);
197 logTable.getColumnModel().getColumn(0).setMaxWidth(30);
198 logTable.getColumnModel().getColumn(0).setResizable(false);
199
200
201 logTable.getColumnModel().getColumn(1).setMinWidth(90);
202 logTable.getColumnModel().getColumn(1).setMaxWidth(90);
203 logTable.getColumnModel().getColumn(1).setResizable(false);
204
205 logTable.getColumnModel().getColumn(2).setMinWidth(110);
206 logTable.getColumnModel().getColumn(2).setMaxWidth(250);
207
208 logTable.getColumnModel().getColumn(3).setPreferredWidth(150);
209 logTable.getColumnModel().getColumn(3).setMaxWidth(400);
210
211 logTable.getColumnModel().getColumn(4).setPreferredWidth(600);
212 }
213
214 protected void initializeToolBar(LogController.Expiration expiration) {
215 configureButton.setFocusable(false);
216 configureButton.addActionListener(new ActionListener() {
217 public void actionPerformed(ActionEvent e) {
218 centerWindowEvent.fire(new CenterWindow(logCategorySelector));
219 logCategorySelector.setVisible(!logCategorySelector.isVisible());
220 }
221 });
222
223 clearButton.setFocusable(false);
224 clearButton.addActionListener(new ActionListener() {
225 public void actionPerformed(ActionEvent e) {
226 logTableModel.clearMessages();
227 }
228 });
229
230 copyButton.setFocusable(false);
231 copyButton.setEnabled(false);
232 copyButton.addActionListener(new ActionListener() {
233 public void actionPerformed(ActionEvent e) {
234 StringBuilder sb = new StringBuilder();
235 List<LogMessage> messages = getSelectedMessages();
236 for (LogMessage message : messages) {
237 sb.append(message.toString()).append("\n");
238 }
239 Application.copyToClipboard(sb.toString());
240 }
241 });
242
243 expandButton.setFocusable(false);
244 expandButton.setEnabled(false);
245 expandButton.addActionListener(new ActionListener() {
246 public void actionPerformed(ActionEvent e) {
247 List<LogMessage> messages = getSelectedMessages();
248 if (messages.size() != 1) return;
249 presenter.onExpand(messages.get(0));
250 }
251 });
252
253 pauseButton.setFocusable(false);
254 pauseButton.addActionListener(new ActionListener() {
255 public void actionPerformed(ActionEvent e) {
256 logTableModel.setPaused(!logTableModel.isPaused());
257 if (logTableModel.isPaused()) {
258 pauseLabel.setText(" (Paused)");
259 } else {
260 pauseLabel.setText(" (Active)");
261 }
262 }
263 });
264
265 expirationComboBox.setSelectedItem(expiration);
266 expirationComboBox.setMaximumSize(new Dimension(100, 32));
267 expirationComboBox.addActionListener(new ActionListener() {
268 public void actionPerformed(ActionEvent e) {
269 JComboBox cb = (JComboBox) e.getSource();
270 LogController.Expiration expiration = (LogController.Expiration) cb.getSelectedItem();
271 logTableModel.setMaxAgeSeconds(expiration.getSeconds());
272 }
273 });
274
275 toolBar.setFloatable(false);
276 toolBar.add(copyButton);
277 toolBar.add(expandButton);
278 toolBar.add(Box.createHorizontalGlue());
279 toolBar.add(configureButton);
280 toolBar.add(clearButton);
281 toolBar.add(pauseButton);
282 toolBar.add(pauseLabel);
283 toolBar.add(Box.createHorizontalGlue());
284 toolBar.add(new JLabel("Clear after:"));
285 toolBar.add(expirationComboBox);
286 }
287
288 protected LogController.Expiration getDefaultExpiration() {
289 return LogController.Expiration.SIXTY_SECONDS;
290 }
291
292 protected ImageIcon getWarnErrorIcon() {
293 return Application.createImageIcon(LogController.class, "img/warn.png");
294 }
295
296 protected ImageIcon getDebugIcon() {
297 return Application.createImageIcon(LogController.class, "img/debug.png");
298 }
299
300 protected ImageIcon getTraceIcon() {
301 return Application.createImageIcon(LogController.class, "img/trace.png");
302 }
303
304 protected ImageIcon getInfoIcon() {
305 return Application.createImageIcon(LogController.class, "img/info.png");
306 }
307
308 protected int getExpandMessageCharacterLimit() {
309 return 100;
310 }
311
312 protected List<LogMessage> getSelectedMessages() {
313 List<LogMessage> messages = new ArrayList<>();
314 for (int row : logTable.getSelectedRows()) {
315 messages.add((LogMessage) logTableModel.getValueAt(row, 0));
316 }
317 return messages;
318 }
319 }