1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.log4j.chainsaw;
19
20 import java.awt.FlowLayout;
21 import java.awt.event.ActionEvent;
22 import java.awt.event.ActionListener;
23 import java.beans.PropertyChangeEvent;
24 import java.beans.PropertyChangeListener;
25 import java.net.URL;
26 import java.util.Dictionary;
27 import java.util.Enumeration;
28 import java.util.Hashtable;
29
30 import javax.swing.BorderFactory;
31 import javax.swing.Box;
32 import javax.swing.BoxLayout;
33 import javax.swing.ButtonGroup;
34 import javax.swing.InputVerifier;
35 import javax.swing.JCheckBox;
36 import javax.swing.JComponent;
37 import javax.swing.JFrame;
38 import javax.swing.JLabel;
39 import javax.swing.JOptionPane;
40 import javax.swing.JPanel;
41 import javax.swing.JRadioButton;
42 import javax.swing.JSlider;
43 import javax.swing.JTextField;
44 import javax.swing.SwingConstants;
45 import javax.swing.UIManager;
46 import javax.swing.event.ChangeEvent;
47 import javax.swing.event.ChangeListener;
48 import javax.swing.tree.DefaultMutableTreeNode;
49 import javax.swing.tree.DefaultTreeModel;
50 import javax.swing.tree.TreeModel;
51
52 import org.apache.log4j.LogManager;
53 import org.apache.log4j.Logger;
54 import org.apache.log4j.chainsaw.osx.OSXIntegration;
55
56
57 /***
58 * A panel used by the user to modify any application-wide preferences.
59 *
60 * @author Paul Smith <psmith@apache.org>
61 *
62 */
63 public class ApplicationPreferenceModelPanel extends AbstractPreferencePanel {
64 private ApplicationPreferenceModel committedPreferenceModel;
65 private ApplicationPreferenceModel uncommittedPreferenceModel =
66 new ApplicationPreferenceModel();
67 private JTextField identifierExpression;
68 private JTextField toolTipDisplayMillis;
69 private JTextField cyclicBufferSize;
70 private final JTextField configurationURL = new JTextField(35);
71 private final Logger logger;
72
73 ApplicationPreferenceModelPanel(ApplicationPreferenceModel model) {
74 this.committedPreferenceModel = model;
75 logger = LogManager.getLogger(ApplicationPreferenceModelPanel.class);
76 initComponents();
77 getOkButton().addActionListener(
78 new ActionListener() {
79 public void actionPerformed(ActionEvent e) {
80 uncommittedPreferenceModel.setConfigurationURL(configurationURL.getText());
81 uncommittedPreferenceModel.setIdentifierExpression(
82 identifierExpression.getText());
83 try {
84 int millis = Integer.parseInt(toolTipDisplayMillis.getText());
85 if (millis >= 0) {
86 uncommittedPreferenceModel.setToolTipDisplayMillis(millis);
87 }
88 } catch (NumberFormatException nfe) {}
89 try {
90 int bufferSize = Integer.parseInt(cyclicBufferSize.getText());
91 if (bufferSize >= 0) {
92 uncommittedPreferenceModel.setCyclicBufferSize(bufferSize);
93 }
94 } catch (NumberFormatException nfe) {}
95 committedPreferenceModel.apply(uncommittedPreferenceModel);
96 hidePanel();
97 }
98 });
99
100 getCancelButton().addActionListener(
101 new ActionListener() {
102 public void actionPerformed(ActionEvent e) {
103 uncommittedPreferenceModel.apply(committedPreferenceModel);
104 hidePanel();
105 }
106 });
107 }
108
109
110 public static void main(String[] args) {
111 JFrame f = new JFrame("App Preferences Panel Test Bed");
112 ApplicationPreferenceModel model = new ApplicationPreferenceModel();
113 ApplicationPreferenceModelPanel panel =
114 new ApplicationPreferenceModelPanel(model);
115 f.getContentPane().add(panel);
116
117 model.addPropertyChangeListener(
118 new PropertyChangeListener() {
119 public void propertyChange(PropertyChangeEvent evt) {
120 System.out.println(evt);
121 }
122 });
123 panel.setOkCancelActionListener(
124 new ActionListener() {
125 public void actionPerformed(ActionEvent e) {
126 System.exit(1);
127 }
128 });
129
130 f.setSize(640, 480);
131 f.setVisible(true);
132 }
133
134 /***
135 * Ensures this panels DISPLAYED model is in sync with
136 * the model initially passed to the constructor.
137 *
138 */
139 public void updateModel() {
140 this.uncommittedPreferenceModel.apply(committedPreferenceModel);
141 }
142
143
144
145
146 protected TreeModel createTreeModel() {
147 final DefaultMutableTreeNode rootNode =
148 new DefaultMutableTreeNode("Preferences");
149 DefaultTreeModel model = new DefaultTreeModel(rootNode);
150
151 DefaultMutableTreeNode general =
152 new DefaultMutableTreeNode(new GeneralAllPrefPanel());
153
154 DefaultMutableTreeNode visuals =
155 new DefaultMutableTreeNode(new VisualsPrefPanel());
156
157 rootNode.add(general);
158 rootNode.add(visuals);
159
160 return model;
161 }
162
163 public class VisualsPrefPanel extends BasicPrefPanel {
164 private final JRadioButton topPlacement = new JRadioButton("Top");
165 private final JRadioButton bottomPlacement = new JRadioButton("Bottom");
166 private final JCheckBox statusBar = new JCheckBox("Show Status bar");
167 private final JCheckBox toolBar = new JCheckBox("Show Toolbar");
168 private final JCheckBox receivers = new JCheckBox("Show Receivers");
169 private UIManager.LookAndFeelInfo[] lookAndFeels =
170 UIManager.getInstalledLookAndFeels();
171 private final ButtonGroup lookAndFeelGroup = new ButtonGroup();
172
173 private VisualsPrefPanel() {
174 super("Visuals");
175 setupComponents();
176 setupListeners();
177 setupInitialValues();
178 }
179
180 /***
181 *
182 */
183 private void setupListeners() {
184 topPlacement.addActionListener(
185 new ActionListener() {
186 public void actionPerformed(ActionEvent e) {
187 uncommittedPreferenceModel.setTabPlacement(SwingConstants.TOP);
188 }
189 });
190 bottomPlacement.addActionListener(
191 new ActionListener() {
192 public void actionPerformed(ActionEvent e) {
193 uncommittedPreferenceModel.setTabPlacement(SwingConstants.BOTTOM);
194 }
195 });
196
197 statusBar.addActionListener(
198 new ActionListener() {
199 public void actionPerformed(ActionEvent e) {
200 uncommittedPreferenceModel.setStatusBar(statusBar.isSelected());
201 }
202 });
203
204 toolBar.addActionListener(
205 new ActionListener() {
206 public void actionPerformed(ActionEvent e) {
207 uncommittedPreferenceModel.setToolbar(toolBar.isSelected());
208 }
209 });
210
211 receivers.addActionListener(
212 new ActionListener() {
213 public void actionPerformed(ActionEvent e) {
214 uncommittedPreferenceModel.setReceivers(receivers.isSelected());
215 }
216 });
217
218 uncommittedPreferenceModel.addPropertyChangeListener(
219 "tabPlacement",
220 new PropertyChangeListener() {
221 public void propertyChange(PropertyChangeEvent evt) {
222 int value = ((Integer) evt.getNewValue()).intValue();
223
224 configureTabPlacement(value);
225 }
226 });
227
228 uncommittedPreferenceModel.addPropertyChangeListener(
229 "statusBar",
230 new PropertyChangeListener() {
231 public void propertyChange(PropertyChangeEvent evt) {
232 statusBar.setSelected(
233 ((Boolean) evt.getNewValue()).booleanValue());
234 }
235 });
236
237 uncommittedPreferenceModel.addPropertyChangeListener(
238 "toolbar",
239 new PropertyChangeListener() {
240 public void propertyChange(PropertyChangeEvent evt) {
241 toolBar.setSelected(((Boolean) evt.getNewValue()).booleanValue());
242 }
243 });
244
245 uncommittedPreferenceModel.addPropertyChangeListener(
246 "receivers",
247 new PropertyChangeListener() {
248 public void propertyChange(PropertyChangeEvent evt) {
249 receivers.setSelected(
250 ((Boolean) evt.getNewValue()).booleanValue());
251 }
252 });
253
254 uncommittedPreferenceModel.addPropertyChangeListener(
255 "lookAndFeelClassName",
256 new PropertyChangeListener() {
257 public void propertyChange(PropertyChangeEvent evt) {
258 String lf = evt.getNewValue().toString();
259
260 Enumeration enumeration = lookAndFeelGroup.getElements();
261
262 while (enumeration.hasMoreElements()) {
263 JRadioButton button = (JRadioButton) enumeration.nextElement();
264
265 if (button.getName()!=null && button.getName().equals(lf)) {
266 button.setSelected(true);
267
268 break;
269 }
270 }
271 }
272 });
273 }
274
275 /***
276 *
277 */
278 private void setupComponents() {
279 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
280
281 JPanel tabPlacementBox = new JPanel();
282 tabPlacementBox.setLayout(
283 new BoxLayout(tabPlacementBox, BoxLayout.Y_AXIS));
284
285 tabPlacementBox.setBorder(
286 BorderFactory.createTitledBorder(
287 BorderFactory.createEtchedBorder(), "Tab Placement"));
288
289 ButtonGroup tabPlacementGroup = new ButtonGroup();
290
291 tabPlacementGroup.add(topPlacement);
292 tabPlacementGroup.add(bottomPlacement);
293
294 tabPlacementBox.add(topPlacement);
295 tabPlacementBox.add(bottomPlacement);
296
297 /***
298 * If we're OSX, we're 'not allowed' to change the tab placement...
299 */
300 if(OSXIntegration.IS_OSX) {
301 tabPlacementBox.setEnabled(false);
302 topPlacement.setEnabled(false);
303 bottomPlacement.setEnabled(false);
304 }
305
306 add(tabPlacementBox);
307 add(statusBar);
308 add(receivers);
309 add(toolBar);
310
311 JPanel lfPanel = new JPanel();
312 lfPanel.setLayout(new BoxLayout(lfPanel, BoxLayout.Y_AXIS));
313 lfPanel.setBorder(
314 BorderFactory.createTitledBorder(
315 BorderFactory.createEtchedBorder(), "Look & Feel"));
316
317 for (int i = 0; i < lookAndFeels.length; i++) {
318 final UIManager.LookAndFeelInfo lfInfo = lookAndFeels[i];
319 final JRadioButton lfItem = new JRadioButton(lfInfo.getName());
320 lfItem.setName(lfInfo.getClassName());
321 lfItem.addActionListener(
322 new ActionListener() {
323 public void actionPerformed(ActionEvent e) {
324 uncommittedPreferenceModel.setLookAndFeelClassName(
325 lfInfo.getClassName());
326 }
327 });
328 lookAndFeelGroup.add(lfItem);
329 lfPanel.add(lfItem);
330 }
331
332 try {
333 final Class gtkLF =
334 Class.forName("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
335 final JRadioButton lfIGTK = new JRadioButton("GTK+ 2.0");
336 lfIGTK.addActionListener(
337 new ActionListener() {
338 public void actionPerformed(ActionEvent e) {
339 uncommittedPreferenceModel.setLookAndFeelClassName(
340 gtkLF.getName());
341 }
342 });
343 lookAndFeelGroup.add(lfIGTK);
344 lfPanel.add(lfIGTK);
345 } catch (Exception e) {
346 logger.debug("Can't find new GTK L&F, might be Windows, or <JDK1.4.2");
347 }
348
349 add(lfPanel);
350
351 add(
352 new JLabel(
353 "<html>Look and Feel change will apply the next time you start Chainsaw.<br>" +
354 "If this value is not set, the default L&F of your system is used.</html>"));
355 }
356 private void configureTabPlacement(int value) {
357 switch (value) {
358 case SwingConstants.TOP:
359 topPlacement.setSelected(true);
360
361 break;
362
363 case SwingConstants.BOTTOM:
364 bottomPlacement.setSelected(true);
365
366 break;
367
368 default:
369 break;
370 }
371 }
372 private void setupInitialValues() {
373 statusBar.setSelected(uncommittedPreferenceModel.isStatusBar());
374 receivers.setSelected(uncommittedPreferenceModel.isReceivers());
375 toolBar.setSelected(uncommittedPreferenceModel.isToolbar());
376 configureTabPlacement(uncommittedPreferenceModel.getTabPlacement());
377 Enumeration e = lookAndFeelGroup.getElements();
378 while(e.hasMoreElements()) {
379 JRadioButton radioButton = (JRadioButton)e.nextElement();
380 if(radioButton.getText().equals(uncommittedPreferenceModel.getLookAndFeelClassName())) {
381 radioButton.setSelected(true);
382 break;
383 }
384 }
385 }
386 }
387
388 /***
389 * @author psmith
390 *
391 */
392 public class GeneralAllPrefPanel extends BasicPrefPanel {
393 private final JCheckBox showNoReceiverWarning =
394 new JCheckBox("Prompt me on startup if there are no Receivers defined");
395 private final JCheckBox showSplash = new JCheckBox("Show Splash screen at startup");
396 private final JSlider responsiveSlider =
397 new JSlider(SwingConstants.HORIZONTAL, 1, 4, 2);
398 private final JCheckBox confirmExit = new JCheckBox("Confirm Exit");
399 Dictionary sliderLabelMap = new Hashtable();
400
401 private final JCheckBox okToRemoveSecurityManager = new JCheckBox("Ok to remove SecurityManager");
402
403 public GeneralAllPrefPanel() {
404 super("General");
405
406 GeneralAllPrefPanel.this.initComponents();
407 }
408
409 private void initComponents() {
410 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
411
412 identifierExpression = new JTextField(20);
413 toolTipDisplayMillis = new JTextField(8);
414 cyclicBufferSize = new JTextField(8);
415 Box p = new Box(BoxLayout.X_AXIS);
416
417 p.add(showNoReceiverWarning);
418 p.add(Box.createHorizontalGlue());
419
420 confirmExit.setToolTipText("Is set, you will be prompted to confirm the exit Chainsaw");
421 okToRemoveSecurityManager.setToolTipText("You will need to tick this to be able to load Receivers/Plugins that require external dependancies.");
422 setupInitialValues();
423 setupListeners();
424
425 initSliderComponent();
426 add(responsiveSlider);
427
428 JPanel p1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
429
430 p1.add(new JLabel("Tab identifier"));
431 p1.add(Box.createHorizontalStrut(5));
432 p1.add(identifierExpression);
433 add(p1);
434 add(p);
435
436 Box p2 = new Box(BoxLayout.X_AXIS);
437 p2.add(confirmExit);
438 p2.add(Box.createHorizontalGlue());
439
440 Box p3 = new Box(BoxLayout.X_AXIS);
441 p3.add(showSplash);
442 p3.add(Box.createHorizontalGlue());
443
444 Box ok4 = new Box(BoxLayout.X_AXIS);
445 ok4.add(okToRemoveSecurityManager);
446 ok4.add(Box.createHorizontalGlue());
447
448 add(p2);
449 add(p3);
450 add(ok4);
451
452 JPanel p4 = new JPanel(new FlowLayout(FlowLayout.LEFT));
453
454 p4.add(new JLabel("ToolTip Display (millis)"));
455 p4.add(Box.createHorizontalStrut(5));
456 p4.add(toolTipDisplayMillis);
457 add(p4);
458
459 JPanel p5 = new JPanel(new FlowLayout(FlowLayout.LEFT));
460
461 p5.add(new JLabel("Cyclic buffer size"));
462 p5.add(Box.createHorizontalStrut(5));
463 p5.add(cyclicBufferSize);
464 add(p5);
465
466 JPanel p6 = new JPanel(new FlowLayout(FlowLayout.LEFT));
467
468 p6.add(new JLabel("Automatic Configuration URL"));
469 p6.add(Box.createHorizontalStrut(5));
470 p6.add(configurationURL);
471 add(p6);
472
473 JPanel p7 = new JPanel(new FlowLayout(FlowLayout.LEFT));
474 p7.add(
475 new JLabel(
476 "Cyclic buffer size change will apply the next time you start Chainsaw"));
477 add(p7);
478
479 add(Box.createVerticalGlue());
480
481 configurationURL.setToolTipText("A complete and valid URL identifying the location of a valid log4 xml configuration file to auto-configure Receivers and other Plugins");
482 configurationURL.setInputVerifier(new InputVerifier() {
483
484 public boolean verify(JComponent input)
485 {
486 try {
487 new URL(configurationURL.getText());
488 } catch (Exception e) {
489 return false;
490 }
491 return true;
492 }});
493 }
494
495 private void initSliderComponent() {
496 responsiveSlider.setToolTipText(
497 "Adjust to set the responsiveness of the app. How often the view is updated.");
498 responsiveSlider.setSnapToTicks(true);
499 responsiveSlider.setLabelTable(sliderLabelMap);
500 responsiveSlider.setPaintLabels(true);
501 responsiveSlider.setPaintTrack(true);
502
503 responsiveSlider.setBorder(
504 BorderFactory.createTitledBorder(
505 BorderFactory.createEtchedBorder(), "Responsiveness"));
506
507
508
509 }
510
511 private void setupListeners() {
512 uncommittedPreferenceModel.addPropertyChangeListener(
513 "showNoReceiverWarning",
514 new PropertyChangeListener() {
515 public void propertyChange(PropertyChangeEvent evt) {
516 showNoReceiverWarning.setSelected(
517 ((Boolean) evt.getNewValue()).booleanValue());
518 }
519 });
520
521 uncommittedPreferenceModel.addPropertyChangeListener("showSplash", new PropertyChangeListener() {
522
523 public void propertyChange(PropertyChangeEvent evt) {
524 boolean value = ((Boolean)evt.getNewValue()).booleanValue();
525 showSplash.setSelected(value);
526 }});
527
528 uncommittedPreferenceModel.addPropertyChangeListener("okToRemoveSecurityManager", new PropertyChangeListener() {
529
530 public void propertyChange(PropertyChangeEvent evt) {
531 boolean newValue = ((Boolean) evt.getNewValue()).booleanValue();
532 if(newValue) {
533 okToRemoveSecurityManager.setSelected(newValue);
534 }else {
535 okToRemoveSecurityManager.setSelected(false);
536 }
537
538 }});
539
540
541 uncommittedPreferenceModel.addPropertyChangeListener(
542 "identifierExpression",
543 new PropertyChangeListener() {
544 public void propertyChange(PropertyChangeEvent evt) {
545 identifierExpression.setText(evt.getNewValue().toString());
546 }
547 });
548
549 uncommittedPreferenceModel.addPropertyChangeListener(
550 "responsiveness",
551 new PropertyChangeListener() {
552 public void propertyChange(PropertyChangeEvent evt) {
553 int value = ((Integer) evt.getNewValue()).intValue();
554
555 if (value >= 1000) {
556 int newValue = (value - 750) / 1000;
557 logger.debug(
558 "Adjusting old Responsiveness value from " + value + " to "
559 + newValue);
560 value = newValue;
561 }
562
563 responsiveSlider.setValue(value);
564 }
565 });
566
567 uncommittedPreferenceModel.addPropertyChangeListener(
568 "toolTipDisplayMillis",
569 new PropertyChangeListener() {
570 public void propertyChange(PropertyChangeEvent evt) {
571 toolTipDisplayMillis.setText(evt.getNewValue().toString());
572 }
573 });
574
575 uncommittedPreferenceModel.addPropertyChangeListener(
576 "cyclicBufferSize",
577 new PropertyChangeListener() {
578 public void propertyChange(PropertyChangeEvent evt) {
579 cyclicBufferSize.setText(evt.getNewValue().toString());
580 }
581 });
582
583 showNoReceiverWarning.addActionListener(
584 new ActionListener() {
585 public void actionPerformed(ActionEvent e) {
586 uncommittedPreferenceModel.setShowNoReceiverWarning(
587 showNoReceiverWarning.isSelected());
588 }
589 });
590
591 showSplash.addActionListener(new ActionListener() {
592
593 public void actionPerformed(ActionEvent e) {
594 uncommittedPreferenceModel.setShowSplash(showSplash.isSelected());
595 }});
596
597 okToRemoveSecurityManager.addActionListener(new ActionListener() {
598
599 public void actionPerformed(ActionEvent e) {
600
601 if(okToRemoveSecurityManager.isSelected() && JOptionPane.showConfirmDialog(okToRemoveSecurityManager, "By ticking this option, you are authorizing Chainsaw to remove Java's Security Manager.\n\n" +
602 "This is required under Java Web Start so that it can access Jars/classes locally. Without this, Receivers like JMSReceiver + DBReceiver that require" +
603 " specific driver jars will NOT be able to be run. \n\n" +
604 "By ticking this, you are saying that this is ok.", "Please Confirm", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
605 uncommittedPreferenceModel.setOkToRemoveSecurityManager(true);
606 }else {
607 uncommittedPreferenceModel.setOkToRemoveSecurityManager(false);
608 }
609
610 }});
611
612
613 responsiveSlider.getModel().addChangeListener(
614 new ChangeListener() {
615 public void stateChanged(ChangeEvent e) {
616 if (responsiveSlider.getValueIsAdjusting()) {
617 /***
618 * We'll wait until it stops.
619 */
620 } else {
621 int value = responsiveSlider.getValue();
622
623 if (value == 0) {
624 value = 1;
625 }
626
627 logger.debug("Adjust responsiveness to " + value);
628 uncommittedPreferenceModel.setResponsiveness(value);
629 }
630 }
631 });
632
633 uncommittedPreferenceModel.addPropertyChangeListener(
634 "confirmExit",
635 new PropertyChangeListener() {
636 public void propertyChange(PropertyChangeEvent evt) {
637 boolean value = ((Boolean) evt.getNewValue()).booleanValue();
638 confirmExit.setSelected(value);
639 }
640 });
641
642 uncommittedPreferenceModel.addPropertyChangeListener("configurationURL", new PropertyChangeListener() {
643
644 public void propertyChange(PropertyChangeEvent evt) {
645 String value = evt.getNewValue().toString();
646 configurationURL.setText(value);
647 }});
648 confirmExit.addActionListener(
649 new ActionListener() {
650 public void actionPerformed(ActionEvent e) {
651 uncommittedPreferenceModel.setConfirmExit(
652 confirmExit.isSelected());
653 }
654 });
655 }
656
657 private void setupInitialValues() {
658 sliderLabelMap.put(new Integer(1), new JLabel("Fastest"));
659 sliderLabelMap.put(new Integer(2), new JLabel("Fast"));
660 sliderLabelMap.put(new Integer(3), new JLabel("Medium"));
661 sliderLabelMap.put(new Integer(4), new JLabel("Slow"));
662
663
664 showNoReceiverWarning.setSelected(
665 uncommittedPreferenceModel.isShowNoReceiverWarning());
666 identifierExpression.setText(
667 uncommittedPreferenceModel.getIdentifierExpression());
668
669 confirmExit.setSelected(uncommittedPreferenceModel.isConfirmExit());
670 okToRemoveSecurityManager.setSelected(uncommittedPreferenceModel.isOkToRemoveSecurityManager());
671 showNoReceiverWarning.setSelected(uncommittedPreferenceModel.isShowNoReceiverWarning());
672 showSplash.setSelected(uncommittedPreferenceModel.isShowSplash());
673 identifierExpression.setText(uncommittedPreferenceModel.getIdentifierExpression());
674 toolTipDisplayMillis.setText(uncommittedPreferenceModel.getToolTipDisplayMillis()+"");
675 cyclicBufferSize.setText(uncommittedPreferenceModel.getCyclicBufferSize() + "");
676 configurationURL.setText(uncommittedPreferenceModel.getConfigurationURL());
677 }
678 }
679 }