1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.log4j.chainsaw;
18
19 import java.awt.Component;
20 import java.awt.Dimension;
21 import java.awt.FlowLayout;
22 import java.awt.event.ActionEvent;
23 import java.awt.event.ActionListener;
24 import java.awt.event.InputEvent;
25 import java.awt.event.MouseAdapter;
26 import java.awt.event.MouseEvent;
27 import java.beans.PropertyChangeEvent;
28 import java.beans.PropertyChangeListener;
29 import java.util.Iterator;
30 import java.util.List;
31
32 import javax.swing.BorderFactory;
33 import javax.swing.Box;
34 import javax.swing.BoxLayout;
35 import javax.swing.ButtonGroup;
36 import javax.swing.JCheckBox;
37 import javax.swing.JFrame;
38 import javax.swing.JLabel;
39 import javax.swing.JList;
40 import javax.swing.JPanel;
41 import javax.swing.JRadioButton;
42 import javax.swing.JScrollPane;
43 import javax.swing.JTextField;
44 import javax.swing.table.TableColumn;
45 import javax.swing.tree.DefaultMutableTreeNode;
46 import javax.swing.tree.DefaultTreeModel;
47 import javax.swing.tree.TreeModel;
48
49 import org.apache.log4j.LogManager;
50 import org.apache.log4j.Logger;
51
52
53 /***
54 * GUI panel used to manipulate the PreferenceModel for a Log Panel
55 *
56 * @author Paul Smith
57 */
58 public class LogPanelPreferencePanel extends AbstractPreferencePanel
59 {
60
61
62 private final LogPanelPreferenceModel preferenceModel;
63 private final ModifiableListModel columnListModel = new ModifiableListModel();
64 private static final Logger logger = LogManager.getLogger(LogPanelPreferencePanel.class);
65
66
67
68 public LogPanelPreferencePanel(LogPanelPreferenceModel model)
69 {
70 preferenceModel = model;
71 initComponents();
72
73 getOkButton().addActionListener(new ActionListener()
74 {
75 public void actionPerformed(ActionEvent e)
76 {
77 hidePanel();
78 }
79 });
80
81 getCancelButton().addActionListener(new ActionListener()
82 {
83 public void actionPerformed(ActionEvent e)
84 {
85 hidePanel();
86 }
87 });
88 }
89
90
91
92 /***
93 * DOCUMENT ME!
94 *
95 * @param args DOCUMENT ME!
96 */
97 public static void main(String[] args)
98 {
99 JFrame f = new JFrame("Preferences Panel Test Bed");
100 LogPanelPreferenceModel model = new LogPanelPreferenceModel();
101 LogPanelPreferencePanel panel = new LogPanelPreferencePanel(model);
102 f.getContentPane().add(panel);
103
104 model.addPropertyChangeListener(new PropertyChangeListener()
105 {
106 public void propertyChange(PropertyChangeEvent evt)
107 {
108 logger.warn(evt.toString());
109 }
110 });
111 panel.setOkCancelActionListener(new ActionListener()
112 {
113 public void actionPerformed(ActionEvent e)
114 {
115 System.exit(1);
116 }
117 });
118
119 f.setSize(640, 480);
120 f.setVisible(true);
121 }
122
123 protected TreeModel createTreeModel()
124 {
125 final DefaultMutableTreeNode rootNode =
126 new DefaultMutableTreeNode("Preferences");
127 DefaultTreeModel model = new DefaultTreeModel(rootNode);
128
129 DefaultMutableTreeNode visuals =
130 new DefaultMutableTreeNode(new VisualsPrefPanel());
131 DefaultMutableTreeNode formatting =
132 new DefaultMutableTreeNode(new FormattingPanel());
133 DefaultMutableTreeNode columns =
134 new DefaultMutableTreeNode(new ColumnSelectorPanel());
135
136 rootNode.add(visuals);
137 rootNode.add(formatting);
138 rootNode.add(columns);
139
140 return model;
141 }
142
143
144
145 /***
146 * Allows the user to choose which columns to display.
147 *
148 * @author Paul Smith
149 *
150 */
151 public class ColumnSelectorPanel extends BasicPrefPanel
152 {
153
154
155 ColumnSelectorPanel()
156 {
157 super("Columns");
158 initComponents();
159 }
160
161
162
163 private void initComponents()
164 {
165 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
166
167 Box columnBox = new Box(BoxLayout.Y_AXIS);
168
169
170 final JList columnList = new JList();
171 columnList.setVisibleRowCount(10);
172
173 for (
174 Iterator iter = preferenceModel.getColumns().iterator();
175 iter.hasNext();)
176 {
177 columnListModel.addElement(iter.next());
178 }
179
180 columnList.setModel(columnListModel);
181
182 CheckListCellRenderer cellRenderer = new CheckListCellRenderer()
183 {
184 protected boolean isSelected(Object value)
185 {
186 return LogPanelPreferencePanel.this.preferenceModel.isColumnVisible((TableColumn)
187 value);
188 }
189 };
190
191 columnList.addMouseListener(new MouseAdapter()
192 {
193 public void mouseClicked(MouseEvent e)
194 {
195 if (
196 (e.getClickCount() > 1)
197 && ((e.getModifiers() & InputEvent.BUTTON1_MASK) > 0))
198 {
199 int i = columnList.locationToIndex(e.getPoint());
200
201 if (i >= 0)
202 {
203 Object column = columnListModel.get(i);
204 preferenceModel.toggleColumn(((TableColumn)column));
205 }
206 }
207 }
208 });
209 columnList.setCellRenderer(cellRenderer);
210 columnBox.add(new JScrollPane(columnList));
211
212 add(columnBox);
213 add(Box.createVerticalGlue());
214 }
215 }
216
217 /***
218 * Provides preference gui's for all the Formatting options
219 * available for the columns etc.
220 */
221 private class FormattingPanel extends BasicPrefPanel
222 {
223
224
225 private JTextField customFormatText = new JTextField("", 10);
226 private JTextField loggerPrecision = new JTextField(5);
227 private JRadioButton rdCustom = new JRadioButton("Custom Format");
228 private final JRadioButton rdISO =
229 new JRadioButton(
230 "<html><b>Fast</b> ISO 8601 format (yyyy-MM-dd HH:mm:ss)</html>");
231 private final JRadioButton rdLevelIcons = new JRadioButton("Icons");
232 private final JRadioButton rdLevelText = new JRadioButton("Text");
233 private JRadioButton rdLast;
234
235
236
237 private FormattingPanel()
238 {
239 super("Formatting");
240 this.initComponents();
241 setupListeners();
242 }
243
244
245
246 private void initComponents()
247 {
248 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
249
250 JPanel dateFormatPanel = new JPanel();
251 dateFormatPanel.setBorder(
252 BorderFactory.createTitledBorder(
253 BorderFactory.createEtchedBorder(), "Timestamp"));
254 dateFormatPanel.setLayout(
255 new BoxLayout(dateFormatPanel, BoxLayout.Y_AXIS));
256 dateFormatPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
257
258 customFormatText.setPreferredSize(new Dimension(100, 20));
259 customFormatText.setMaximumSize(customFormatText.getPreferredSize());
260 customFormatText.setMinimumSize(customFormatText.getPreferredSize());
261 customFormatText.setEnabled(false);
262
263 rdCustom.setSelected(preferenceModel.isCustomDateFormat());
264
265 ButtonGroup bgDateFormat = new ButtonGroup();
266
267 rdISO.setAlignmentX(0);
268 rdISO.setSelected(preferenceModel.isUseISO8601Format());
269
270 bgDateFormat.add(rdISO);
271 dateFormatPanel.add(rdISO);
272
273 for (
274 Iterator iter = LogPanelPreferenceModel.DATE_FORMATS.iterator();
275 iter.hasNext();)
276 {
277 final String format = (String) iter.next();
278 final JRadioButton rdFormat = new JRadioButton(format);
279 rdFormat.setAlignmentX(0);
280
281 bgDateFormat.add(rdFormat);
282 rdFormat.addActionListener(new ActionListener()
283 {
284 public void actionPerformed(ActionEvent e)
285 {
286 preferenceModel.setDateFormatPattern(format);
287 customFormatText.setEnabled(rdCustom.isSelected());
288 rdLast = rdFormat;
289 }
290 });
291
292
293 preferenceModel.addPropertyChangeListener(
294 "dateFormatPattern", new PropertyChangeListener()
295 {
296 public void propertyChange(PropertyChangeEvent evt)
297 {
298 rdFormat.setSelected(
299 preferenceModel.getDateFormatPattern().equals(format));
300 rdLast = rdFormat;
301 }
302 });
303
304 dateFormatPanel.add(rdFormat);
305 }
306
307
308 if (preferenceModel.isCustomDateFormat())
309 {
310 customFormatText.setText(preferenceModel.getDateFormatPattern());
311 customFormatText.setEnabled(true);
312 }
313
314 rdCustom.setAlignmentX(0);
315 bgDateFormat.add(rdCustom);
316
317 Box customBox = Box.createHorizontalBox();
318
319
320
321 customBox.add(rdCustom);
322 customBox.add(customFormatText);
323 customBox.add(Box.createHorizontalGlue());
324 dateFormatPanel.add(customBox);
325
326
327 add(dateFormatPanel);
328
329 JPanel levelFormatPanel = new JPanel();
330 levelFormatPanel.setLayout(
331 new BoxLayout(levelFormatPanel, BoxLayout.Y_AXIS));
332 levelFormatPanel.setBorder(
333 BorderFactory.createTitledBorder(
334 BorderFactory.createEtchedBorder(), "Level"));
335 levelFormatPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
336
337 ButtonGroup bgLevel = new ButtonGroup();
338 bgLevel.add(rdLevelIcons);
339 bgLevel.add(rdLevelText);
340
341 rdLevelIcons.setSelected(preferenceModel.isLevelIcons());
342
343 levelFormatPanel.add(rdLevelIcons);
344 levelFormatPanel.add(rdLevelText);
345
346 add(levelFormatPanel);
347
348 JPanel loggerFormatPanel = new JPanel();
349 loggerFormatPanel.setLayout(
350 new BoxLayout(loggerFormatPanel, BoxLayout.Y_AXIS));
351 loggerFormatPanel.setBorder(
352 BorderFactory.createTitledBorder(
353 BorderFactory.createEtchedBorder(), "Logger"));
354 loggerFormatPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
355
356 final JLabel precisionLabel =
357 new JLabel("Number of package levels to hide)");
358 final JLabel precisionLabel2 =
359 new JLabel("leave blank to display full logger");
360
361 loggerFormatPanel.add(precisionLabel);
362 loggerFormatPanel.add(precisionLabel2);
363
364 JPanel p = new JPanel(new FlowLayout(FlowLayout.LEFT));
365
366 p.add(loggerPrecision);
367 loggerFormatPanel.add(p);
368
369 add(loggerFormatPanel);
370
371 add(Box.createVerticalGlue());
372 }
373
374
375
376
377 private void reset() {
378
379 if (preferenceModel.isCustomDateFormat()) {
380 customFormatText.setText(preferenceModel.getDateFormatPattern());
381 } else {
382 if (rdLast != null) {
383 rdLast.setSelected(true);
384 }
385 customFormatText.setEnabled(false);
386 }
387
388 loggerPrecision.setText(preferenceModel.getLoggerPrecision());
389 }
390
391
392
393
394 private void commit() {
395 if (rdCustom.isSelected()) {
396 preferenceModel.setDateFormatPattern(customFormatText.getText());
397 }
398 preferenceModel.setLoggerPrecision(loggerPrecision.getText());
399 }
400
401 /***
402 * DOCUMENT ME!
403 */
404 private void setupListeners()
405 {
406 getOkButton().addActionListener(new ActionListener() {
407 public void actionPerformed(ActionEvent evt) {
408 commit();
409 }
410 });
411
412 getCancelButton().addActionListener(new ActionListener() {
413 public void actionPerformed(ActionEvent evt) {
414 reset();
415 }
416 });
417
418 rdCustom.addActionListener(new ActionListener()
419 {
420 public void actionPerformed(ActionEvent e)
421 {
422 customFormatText.setEnabled(rdCustom.isSelected());
423 customFormatText.grabFocus();
424 }
425 });
426
427
428 preferenceModel.addPropertyChangeListener(
429 "dateFormatPattern", new PropertyChangeListener()
430 {
431 public void propertyChange(PropertyChangeEvent evt)
432 {
433 /***
434 * we need to make sure we are not reacting to the user typing, so only do this
435 * if the text box is not the same as the model
436 */
437 if (
438 preferenceModel.isCustomDateFormat()
439 && !customFormatText.getText().equals(
440 evt.getNewValue().toString()))
441 {
442 customFormatText.setText(preferenceModel.getDateFormatPattern());
443 rdCustom.setSelected(true);
444 customFormatText.setEnabled(true);
445 }
446 else
447 {
448 rdCustom.setSelected(false);
449 }
450 }
451 });
452
453 rdISO.addActionListener(new ActionListener()
454 {
455 public void actionPerformed(ActionEvent e)
456 {
457 preferenceModel.setDateFormatPattern("ISO8601");
458 customFormatText.setEnabled(rdCustom.isSelected());
459 rdLast = rdISO;
460 }
461 });
462 preferenceModel.addPropertyChangeListener(
463 "dateFormatPattern", new PropertyChangeListener()
464 {
465 public void propertyChange(PropertyChangeEvent evt)
466 {
467 rdISO.setSelected(preferenceModel.isUseISO8601Format());
468 rdLast = rdISO;
469 }
470 });
471
472 ActionListener levelIconListener = new ActionListener()
473 {
474 public void actionPerformed(ActionEvent e)
475 {
476 preferenceModel.setLevelIcons(rdLevelIcons.isSelected());
477 }
478 };
479
480 rdLevelIcons.addActionListener(levelIconListener);
481 rdLevelText.addActionListener(levelIconListener);
482
483 preferenceModel.addPropertyChangeListener(
484 "levelIcons", new PropertyChangeListener()
485 {
486 public void propertyChange(PropertyChangeEvent evt)
487 {
488 boolean value = ((Boolean) evt.getNewValue()).booleanValue();
489 rdLevelIcons.setSelected(value);
490 rdLevelText.setSelected(!value);
491 }
492 });
493 }
494 }
495
496 /***
497 * DOCUMENT ME!
498 *
499 * @author $author$
500 * @version $Revision: 529672 $, $Date: 2007-04-17 11:59:53 -0500 (Tue, 17 Apr 2007) $
501 *
502 * @author psmith
503 *
504 */
505 private class VisualsPrefPanel extends BasicPrefPanel
506 {
507
508
509 private final JCheckBox detailPanelVisible =
510 new JCheckBox("Show Event Detail panel");
511
512 private final JCheckBox loggerTreePanel =
513 new JCheckBox("Show Logger Tree panel");
514 private final JCheckBox scrollToBottom =
515 new JCheckBox("Scroll to bottom (view tracks with new events)");
516 private final JCheckBox toolTips =
517 new JCheckBox("Show Event Detail Tooltips");
518
519
520
521 /***
522 * Creates a new VisualsPrefPanel object.
523 */
524 private VisualsPrefPanel()
525 {
526 super("Visuals");
527 initPanelComponents();
528 setupListeners();
529 }
530
531
532
533 /***
534 * DOCUMENT ME!
535 */
536 private void initPanelComponents()
537 {
538 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
539
540 add(toolTips);
541 add(detailPanelVisible);
542 add(loggerTreePanel);
543 add(scrollToBottom);
544
545 toolTips.setSelected(preferenceModel.isToolTips());
546 detailPanelVisible.setSelected(preferenceModel.isDetailPaneVisible());
547 loggerTreePanel.setSelected(preferenceModel.isLogTreePanelVisible());
548 }
549
550 /***
551 * DOCUMENT ME!
552 */
553 private void setupListeners()
554 {
555 toolTips.addActionListener(new ActionListener()
556 {
557 public void actionPerformed(ActionEvent e)
558 {
559 preferenceModel.setToolTips(toolTips.isSelected());
560 }
561 });
562 preferenceModel.addPropertyChangeListener(
563 "toolTips", new PropertyChangeListener()
564 {
565 public void propertyChange(PropertyChangeEvent evt)
566 {
567 boolean value = ((Boolean) evt.getNewValue()).booleanValue();
568 toolTips.setSelected(value);
569 }
570 });
571
572 detailPanelVisible.addActionListener(new ActionListener()
573 {
574 public void actionPerformed(ActionEvent e)
575 {
576 preferenceModel.setDetailPaneVisible(detailPanelVisible.isSelected());
577 }
578 });
579
580 preferenceModel.addPropertyChangeListener(
581 "detailPaneVisible", new PropertyChangeListener()
582 {
583 public void propertyChange(PropertyChangeEvent evt)
584 {
585 boolean value = ((Boolean) evt.getNewValue()).booleanValue();
586 detailPanelVisible.setSelected(value);
587 }
588 });
589
590 scrollToBottom.addActionListener(new ActionListener()
591 {
592 public void actionPerformed(ActionEvent e)
593 {
594 preferenceModel.setScrollToBottom(scrollToBottom.isSelected());
595 }
596 });
597
598 preferenceModel.addPropertyChangeListener(
599 "scrollToBottom", new PropertyChangeListener()
600 {
601 public void propertyChange(PropertyChangeEvent evt)
602 {
603 boolean value = ((Boolean) evt.getNewValue()).booleanValue();
604 scrollToBottom.setSelected(value);
605 }
606 });
607
608 loggerTreePanel.addActionListener(new ActionListener()
609 {
610 public void actionPerformed(ActionEvent e)
611 {
612 preferenceModel.setLogTreePanelVisible(loggerTreePanel.isSelected());
613 }
614 });
615
616 preferenceModel.addPropertyChangeListener(
617 "logTreePanelVisible", new PropertyChangeListener()
618 {
619 public void propertyChange(PropertyChangeEvent evt)
620 {
621 boolean value = ((Boolean) evt.getNewValue()).booleanValue();
622 loggerTreePanel.setSelected(value);
623 }
624 });
625
626 preferenceModel.addPropertyChangeListener("columns", new PropertyChangeListener() {
627 public void propertyChange(PropertyChangeEvent evt) {
628 List cols = (List)evt.getNewValue();
629 for (
630 Iterator iter = cols.iterator();
631 iter.hasNext();)
632 {
633 TableColumn col = (TableColumn) iter.next();
634 if (!columnListModel.contains(col)) {
635 columnListModel.addElement(col);
636 columnListModel.fireContentsChanged();
637 }
638 }
639 }});
640
641 preferenceModel.addPropertyChangeListener(
642 "visibleColumns", new PropertyChangeListener()
643 {
644 public void propertyChange(PropertyChangeEvent evt)
645 {
646 columnListModel.fireContentsChanged();
647 }
648 });
649
650 }
651 }
652 }