KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > info > monitorenter > gui > chart > layout > LayoutFactory


1 /*
2  * LayoutFactory.java jchart2d
3  * Copyright (C) Achim Westermann, created on 19.05.2005, 20:26:00
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18  *
19  * If you modify or optimize the code in a useful way please let me know.
20  * Achim.Westermann@gmx.de
21  *
22  */

23 package info.monitorenter.gui.chart.layout;
24
25 import info.monitorenter.gui.chart.Chart2D;
26 import info.monitorenter.gui.chart.IAxis;
27 import info.monitorenter.gui.chart.ITrace2D;
28 import info.monitorenter.gui.chart.ITracePainter;
29 import info.monitorenter.gui.chart.axis.AxisLinear;
30 import info.monitorenter.gui.chart.axis.AxisLog10;
31 import info.monitorenter.gui.chart.axis.AxisLogE;
32 import info.monitorenter.gui.chart.events.AxisActionSetGrid;
33 import info.monitorenter.gui.chart.events.AxisActionSetRange;
34 import info.monitorenter.gui.chart.events.AxisActionSetRangePolicy;
35 import info.monitorenter.gui.chart.events.Chart2DActionSetAxis;
36 import info.monitorenter.gui.chart.events.Chart2DActionSetCustomGridColorSingleton;
37 import info.monitorenter.gui.chart.events.Chart2DActionSetGridColor;
38 import info.monitorenter.gui.chart.events.JComponentActionSetBackground;
39 import info.monitorenter.gui.chart.events.JComponentActionSetCustomBackgroundSingleton;
40 import info.monitorenter.gui.chart.events.JComponentActionSetCustomForegroundSingleton;
41 import info.monitorenter.gui.chart.events.JComponentActionSetForeground;
42 import info.monitorenter.gui.chart.events.PopupListener;
43 import info.monitorenter.gui.chart.events.Trace2DActionAddRemoveTracePainter;
44 import info.monitorenter.gui.chart.events.Trace2DActionSetColor;
45 import info.monitorenter.gui.chart.events.Trace2DActionSetCustomColor;
46 import info.monitorenter.gui.chart.events.Trace2DActionSetName;
47 import info.monitorenter.gui.chart.events.Trace2DActionSetStroke;
48 import info.monitorenter.gui.chart.events.Trace2DActionSetVisible;
49 import info.monitorenter.gui.chart.events.Trace2DActionSetZindex;
50 import info.monitorenter.gui.chart.events.Trace2DActionZindexDecrease;
51 import info.monitorenter.gui.chart.events.Trace2DActionZindexIncrease;
52 import info.monitorenter.gui.chart.rangepolicies.RangePolicyFixedViewport;
53 import info.monitorenter.gui.chart.rangepolicies.RangePolicyForcedPoint;
54 import info.monitorenter.gui.chart.rangepolicies.RangePolicyHighestValues;
55 import info.monitorenter.gui.chart.rangepolicies.RangePolicyMinimumViewport;
56 import info.monitorenter.gui.chart.rangepolicies.RangePolicyUnbounded;
57 import info.monitorenter.gui.chart.traces.painters.TracePainterDisc;
58 import info.monitorenter.gui.chart.traces.painters.TracePainterFill;
59 import info.monitorenter.gui.chart.traces.painters.TracePainterPolyline;
60 import info.monitorenter.util.Range;
61
62 import java.awt.BasicStroke JavaDoc;
63 import java.awt.Color JavaDoc;
64 import java.awt.Component JavaDoc;
65 import java.awt.Font JavaDoc;
66 import java.awt.Stroke JavaDoc;
67 import java.awt.event.ActionEvent JavaDoc;
68 import java.beans.PropertyChangeEvent JavaDoc;
69 import java.beans.PropertyChangeListener JavaDoc;
70 import java.lang.ref.WeakReference JavaDoc;
71
72 import javax.swing.AbstractAction JavaDoc;
73 import javax.swing.AbstractButton JavaDoc;
74 import javax.swing.Action JavaDoc;
75 import javax.swing.ButtonGroup JavaDoc;
76 import javax.swing.JCheckBoxMenuItem JavaDoc;
77 import javax.swing.JComponent JavaDoc;
78 import javax.swing.JLabel JavaDoc;
79 import javax.swing.JMenu JavaDoc;
80 import javax.swing.JMenuBar JavaDoc;
81 import javax.swing.JMenuItem JavaDoc;
82 import javax.swing.JPopupMenu JavaDoc;
83 import javax.swing.JRadioButtonMenuItem JavaDoc;
84
85 /**
86  * Factory that provides creational methods for adding popup menues to the
87  * {@link info.monitorenter.gui.chart.Chart2D} and obtaining popup menu
88  * decorated {@link javax.swing.JLabel} instances for
89  * {@link info.monitorenter.gui.chart.ITrace2D} instances.
90  * <p>
91  *
92  * @author <a HREF="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
93  *
94  * @version $Revision: 1.12 $
95  */

96 public final class LayoutFactory {
97
98   /**
99    * <p>
100    * Implementation for a <code>PropertyChangeListener</code> that adpapts a
101    * wrapped <code>JComponent</code> to the following properties.
102    * <p>
103    *
104    * <ul>
105    * <li>background color</li>
106    * <li>foreground color (text)</li>
107    * <li>font</li>
108    * </ul>
109    * <p>
110    *
111    * @author <a HREF="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
112    *
113    */

114   public static class BasicPropertyAdaptSupport implements PropertyChangeListener JavaDoc {
115
116     /**
117      * The component to whose properties the delegate adapts to.
118      * <p>
119      * This is not needed to read the properties of because the fired change
120      * events contain the re
121      *
122      */

123     private Component JavaDoc m_adaptee;
124
125     /** The weak reference to the component to adapt properties on. */
126     protected WeakReference JavaDoc m_delegate;
127
128     /**
129      *
130      * @param delegate
131      * The component to adapt the properties on.
132      * @param adaptee
133      * The peer component delegate will be adapted to.
134      */

135     public BasicPropertyAdaptSupport(final Component JavaDoc delegate, final Component JavaDoc adaptee) {
136       this.m_delegate = new WeakReference JavaDoc(delegate);
137       this.m_adaptee = adaptee;
138       delegate.setFont(adaptee.getFont());
139       delegate.setBackground(adaptee.getBackground());
140       delegate.setForeground(adaptee.getForeground());
141       adaptee.addPropertyChangeListener(this);
142     }
143
144     /**
145      * Removes the listener for basic property changes from the component to
146      * adapt to.
147      * <p>
148      *
149      * @see java.lang.Object#finalize()
150      *
151      * @throws Throwable
152      * if sth. goes wrong cleaning up.
153      */

154     public void finalize() throws Throwable JavaDoc {
155       super.finalize();
156       this.m_adaptee.removePropertyChangeListener(this);
157     }
158
159     /**
160      * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
161      */

162     public void propertyChange(final PropertyChangeEvent JavaDoc evt) {
163       String JavaDoc prop = evt.getPropertyName();
164       Object JavaDoc reference = this.m_delegate.get();
165       if (reference != null) {
166         Component JavaDoc component = (Component JavaDoc) reference;
167         if (prop.equals(Chart2D.PROPERTY_BACKGROUND_COLOR)) {
168           Color color = (Color) evt.getNewValue();
169           Color foreground = component.getForeground();
170           if (color.equals(foreground)) {
171             component.setForeground(component.getBackground());
172           }
173           component.setBackground(color);
174           component.repaint();
175         } else if (prop.equals(Chart2D.PROPERTY_FONT)) {
176           Font JavaDoc font = (Font JavaDoc) evt.getNewValue();
177           component.setFont(font);
178         } else if (prop.equals(Chart2D.PROPERTY_FOREGROUND_COLOR)) {
179           Color color = (Color) evt.getNewValue();
180           Color background = component.getBackground();
181           if (color.equals(background)) {
182             component.setBackground(component.getForeground());
183           }
184           component.setForeground(color);
185         }
186       } else {
187         // if no more components to adapt, remove myself as a listener
188
// to avoid mem-leak in listener list:
189
((Component JavaDoc) evt.getSource()).removePropertyChangeListener(this);
190       }
191     }
192   }
193
194   /**
195    * A checkbox menu item that will change it's order in the known {@link JMenu}
196    * it is contained in whenever it's state changes.
197    * <p>
198    *
199    * Whenever it is deselected it is put to the end, whenever it is selected it
200    * will put itself to the top. Not very perfomant but close to minimal code.
201    * <p>
202    */

203   private static class OrderingCheckBoxMenuItem
204       extends LayoutFactory.PropertyChangeCheckBoxMenuItem {
205
206     /**
207      * Enriches a wrapped {@link Action} by the service of ordering it's
208      * corresponding {@link JMenuItem} in it's {@link JMenu} according to the
209      * description of {@link LayoutFactory.OrderingCheckBoxMenuItem}.
210      * <p>
211      *
212      * @author <a HREF="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
213      *
214      *
215      * @version $Revision: 1.12 $
216      */

217     private final class JMenuOrderingAction
218         extends AbstractAction JavaDoc {
219
220       /**
221        * Generated <code>serialVersionUID</code>.
222        */

223       private static final long serialVersionUID = 3835159462649672505L;
224
225       /**
226        * The action that is enriched by the service of ordering it's
227        * corresponding {@link JMenuItem} in it's {@link JMenu} according to the
228        * description of {@link LayoutFactory.OrderingCheckBoxMenuItem}.
229        */

230       private Action JavaDoc m_action;
231
232       /**
233        * Creates an instance delegating to the given action and adding the
234        * ordering service described above.
235        * <p>
236        *
237        * @param delegate
238        * the action that is enriched by the service of ordering it's
239        * corresponding {@link JMenuItem} in it's {@link JMenu}
240        * according to the description of
241        * {@link LayoutFactory.OrderingCheckBoxMenuItem}.
242        *
243        */

244       private JMenuOrderingAction(final Action JavaDoc delegate) {
245         this.m_action = delegate;
246       }
247
248       /**
249        * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
250        */

251       public void actionPerformed(final ActionEvent JavaDoc e) {
252         this.m_action.actionPerformed(e);
253         // my service:
254
JCheckBoxMenuItem JavaDoc item = (JCheckBoxMenuItem JavaDoc) e.getSource();
255         boolean state = item.getState();
256         if (state) {
257           LayoutFactory.OrderingCheckBoxMenuItem.this.m_menu
258               .remove(LayoutFactory.OrderingCheckBoxMenuItem.this);
259           LayoutFactory.OrderingCheckBoxMenuItem.this.m_menu.add(
260               LayoutFactory.OrderingCheckBoxMenuItem.this, 0);
261         } else {
262           LayoutFactory.OrderingCheckBoxMenuItem.this.m_menu
263               .remove(LayoutFactory.OrderingCheckBoxMenuItem.this);
264           LayoutFactory.OrderingCheckBoxMenuItem.this.m_menu
265               .add(LayoutFactory.OrderingCheckBoxMenuItem.this);
266         }
267
268       }
269
270       /**
271        * @see javax.swing.AbstractAction#addPropertyChangeListener(java.beans.PropertyChangeListener)
272        */

273       public void addPropertyChangeListener(final PropertyChangeListener JavaDoc listener) {
274         this.m_action.addPropertyChangeListener(listener);
275       }
276
277       /**
278        * @see java.lang.Object#equals(java.lang.Object)
279        */

280       public boolean equals(final Object JavaDoc obj) {
281         return this.m_action.equals(obj);
282       }
283
284       /**
285        * @see javax.swing.AbstractAction#getValue(java.lang.String)
286        */

287       public Object JavaDoc getValue(final String JavaDoc key) {
288         return this.m_action.getValue(key);
289       }
290
291       /**
292        * @see java.lang.Object#hashCode()
293        */

294       public int hashCode() {
295         return this.m_action.hashCode();
296       }
297
298       /**
299        * @see javax.swing.AbstractAction#isEnabled()
300        */

301       public boolean isEnabled() {
302         return this.m_action.isEnabled();
303       }
304
305       /**
306        * @see javax.swing.AbstractAction#putValue(java.lang.String,
307        * java.lang.Object)
308        */

309       public void putValue(final String JavaDoc key, final Object JavaDoc value) {
310         this.m_action.putValue(key, value);
311       }
312
313       /**
314        * @see javax.swing.AbstractAction#removePropertyChangeListener(java.beans.PropertyChangeListener)
315        */

316       public void removePropertyChangeListener(final PropertyChangeListener JavaDoc listener) {
317         this.m_action.removePropertyChangeListener(listener);
318       }
319
320       /**
321        * @see javax.swing.AbstractAction#setEnabled(boolean)
322        */

323       public void setEnabled(final boolean b) {
324         this.m_action.setEnabled(b);
325       }
326
327       /**
328        * @see java.lang.Object#toString()
329        */

330       public String JavaDoc toString() {
331         return this.m_action.toString();
332       }
333     }
334
335     /**
336      * Generated <code>serialVersionUID</code>.
337      */

338     private static final long serialVersionUID = 3834870273894857017L;
339
340     /** The menu to control this items order within. */
341     private JMenu JavaDoc m_menu;
342
343     /**
344      * Creates an instance that will adapt it's own basic UI properties to the
345      * given component, trigger the given action upon checkbox selection /
346      * deselection and order itself in the given menu as described in the class
347      * comment.
348      * <p>
349      *
350      * @param component
351      * the component to adapt basic UI properties to.
352      *
353      * @param action
354      * the action to trigger.
355      *
356      * @param container
357      * the instance this menu item is contained in.
358      *
359      * @see LayoutFactory.PropertyChangeCheckBoxMenuItem
360      */

361     public OrderingCheckBoxMenuItem(final JComponent JavaDoc component, final Action JavaDoc action,
362         final JMenu JavaDoc container, final boolean checked) {
363       super(component, checked);
364       this.m_menu = container;
365       super.setAction(new JMenuOrderingAction(action));
366     }
367   }
368
369   /**
370    * A <code>JCheckBoxMenuItem</code> that listens for changes of background
371    * color, foreground color and font of the given <code>JComponent</code> and
372    * adapts it's own settings.
373    * <p>
374    * Additionally - as this item has a state - it is possible to let the state
375    * be changed from outside (unlike only changing it from the UI): Sth. that
376    * seems to have been forgotten in the java implementation. It's state ({@link JCheckBoxMenuItem#setState(boolean)},
377    * {@link javax.swing.AbstractButton#setSelected(boolean)}) listens on
378    * property {@link #PROPERTY_SELECTED} for changes of the state. These events
379    * are normally fired by the custom {@link Action} implementations like
380    * {@link Chart2DActionSetAxis}.
381    * <p>
382    * Instances register themselves to receive events from the action given to
383    * their constructor.
384    * <p>
385    *
386    * @author <a HREF="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
387    *
388    */

389   public static class PropertyChangeCheckBoxMenuItem
390       extends JCheckBoxMenuItem JavaDoc {
391
392     /** The property identifying a change of selection. */
393     public static final String JavaDoc PROPERTY_SELECTED = "";
394
395     /**
396      * Generated <code>serialVersionUID</code>.
397      */

398     private static final long serialVersionUID = 3690196534012752439L;
399
400     /**
401      * Creates an instance with the given name that listens to the components
402      * background color, foreground color and font.
403      * <p>
404      *
405      * The source of the {@link java.awt.event.ActionEvent} given to the
406      * {@link Action} ({@link java.util.EventObject#getSource()}) will be of
407      * type {@link JCheckBoxMenuItem}- the state (selected / deselected) may be
408      * obtained from it.
409      * <p>
410      *
411      * @param component
412      * The component to whose basic UI properties this item will adapt.
413      *
414      * @param action
415      * The <code>Action</code> to trigger when this item is clicked.
416      *
417      * @param checked
418      * the inital state of the checkbox.
419      */

420     public PropertyChangeCheckBoxMenuItem(final JComponent JavaDoc component, final Action JavaDoc action,
421         final boolean checked) {
422       super(action);
423       this.setState(checked);
424       new BasicPropertyAdaptSupport(this, component);
425       if (action != null) {
426         action.addPropertyChangeListener(new SelectionPropertyAdaptSupport(this));
427       }
428     }
429
430     /**
431      * Internal constructor that should not be used unless
432      * {@link javax.swing.AbstractButton#setAction(javax.swing.Action)} is
433      * invoked afterwards on this instance (else NPE!).
434      * <p>
435      *
436      * @param component
437      * The component to whose basic UI properties this item will adapt.
438      *
439      * @param checked
440      * the inital state of the checkbox.
441      *
442      */

443     protected PropertyChangeCheckBoxMenuItem(final JComponent JavaDoc component, final boolean checked) {
444       this(component, null, checked);
445     }
446
447     /**
448      * @see javax.swing.AbstractButton#setAction(javax.swing.Action)
449      */

450     public void setAction(final Action JavaDoc a) {
451       if (a != null) {
452         super.setAction(a);
453         a.addPropertyChangeListener(new SelectionPropertyAdaptSupport(this));
454       }
455     }
456   }
457
458   /**
459    * A <code>JRadioButtonMenuItem</code> that listens for changes of
460    * background color, foreground color and font of the given
461    * <code>JComponent</code> and adapts it's own settings.
462    * <p>
463    *
464    * Additionally - as this item has a state - it is possible to let the state
465    * be changed from outside (unlike only changing it from the UI): Sth. that
466    * seems to have been forgotten in the java implementation. It's state ({@link JCheckBoxMenuItem#setState(boolean)},
467    * {@link javax.swing.AbstractButton#setSelected(boolean)}) listens on
468    * property {@link #PROPERTY_SELECTED} for changes of the state. These events
469    * are normally fired by the custom {@link Action} implementations like
470    * {@link Chart2DActionSetAxis}.
471    * <p>
472    * Instances register themselves to receive events from the action given to
473    * their constructor.
474    * <p>
475    *
476    * @author <a HREF="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
477    *
478    */

479   private static class PropertyChangeJRadioButtonMenuItem
480       extends JRadioButtonMenuItem JavaDoc {
481
482     /**
483      * Internal constructor that should not be used unless
484      * {@link javax.swing.AbstractButton#setAction(javax.swing.Action)} is
485      * invoked afterwards on this instance (else NPE!).
486      * <p>
487      *
488      * @param component
489      * The component to whose basic UI properties this item will adapt.
490      */

491     protected PropertyChangeJRadioButtonMenuItem(final JComponent JavaDoc component) {
492       this(component, null);
493     }
494
495     /**
496      * Creates an instance with the given name that listens to the components
497      * background color, foreground color and font.
498      * <p>
499      *
500      * The source of the {@link java.awt.event.ActionEvent} given to the
501      * {@link Action} ({@link java.util.EventObject#getSource()}) will be of
502      * type {@link JRadioButtonMenuItem}.
503      * <p>
504      *
505      * @param component
506      * The component to whose basic UI properties this item will adapt.
507      *
508      * @param action
509      * The <code>Action</code> to trigger when this item is clicked.
510      */

511     public PropertyChangeJRadioButtonMenuItem(final JComponent JavaDoc component, final Action JavaDoc action) {
512       super(action);
513       new BasicPropertyAdaptSupport(this, component);
514       if (action != null) {
515         action.addPropertyChangeListener(new SelectionPropertyAdaptSupport(this));
516       }
517
518     }
519
520     /**
521      * @see javax.swing.AbstractButton#setAction(javax.swing.Action)
522      */

523     public void setAction(final Action JavaDoc a) {
524       if (a != null) {
525         super.setAction(a);
526         a.addPropertyChangeListener(new SelectionPropertyAdaptSupport(this));
527       }
528     }
529
530   }
531
532   /**
533    * A <code>JRadioButtonMenuItem</code> that listens on it's assigned
534    * <code>Action</code> for selection changes.
535    * <p>
536    *
537    * As this item has a state - it is possible to let the state be changed from
538    * outside (unlike only changing it from the UI): Sth. that seems to have been
539    * forgotten in the java implementation. It's state ({@link JCheckBoxMenuItem#setState(boolean)},
540    * {@link javax.swing.AbstractButton#setSelected(boolean)}) listens on
541    * property {@link #PROPERTY_SELECTED} for changes of the state. These events
542    * are normally fired by the custom {@link Action} implementations like
543    * {@link Chart2DActionSetAxis}.
544    * <p>
545    * Instances register themselves to receive events from the action given to
546    * their constructor.
547    * <p>
548    *
549    * @author <a HREF="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
550    *
551    */

552   private static class SelectionAdaptJRadioButtonMenuItem
553       extends JRadioButtonMenuItem JavaDoc {
554
555     /**
556      * Creates an instance with the given name that listens to the components
557      * background color, foreground color and font.
558      * <p>
559      *
560      * The source of the {@link java.awt.event.ActionEvent} given to the
561      * {@link Action} ({@link java.util.EventObject#getSource()}) will be of
562      * type {@link JRadioButtonMenuItem}.
563      * <p>
564      *
565      * @param action
566      * The <code>Action</code> to trigger when this item is clicked.
567      */

568     public SelectionAdaptJRadioButtonMenuItem(final Action JavaDoc action) {
569       super(action);
570       if (action != null) {
571         action.addPropertyChangeListener(new SelectionPropertyAdaptSupport(this));
572       }
573     }
574
575     /**
576      * @see javax.swing.AbstractButton#setAction(javax.swing.Action)
577      */

578     public void setAction(final Action JavaDoc a) {
579       if (a != null) {
580         super.setAction(a);
581         a.addPropertyChangeListener(new SelectionPropertyAdaptSupport(this));
582       }
583     }
584
585   }
586
587   /**
588    * A <code>JCheckBoxMenuItem</code> that listens on it's assigned
589    * <code>Action</code> for selection changes.
590    * <p>
591    *
592    * As this item has a state - it is possible to let the state be changed from
593    * outside (unlike only changing it from the UI): Sth. that seems to have been
594    * forgotten in the java implementation. It's state ({@link JCheckBoxMenuItem#setState(boolean)},
595    * {@link javax.swing.AbstractButton#setSelected(boolean)}) listens on
596    * property {@link #PROPERTY_SELECTED} for changes of the state. These events
597    * are normally fired by the custom {@link Action} implementations like
598    * {@link Chart2DActionSetAxis}.
599    * <p>
600    * Instances register themselves to receive events from the action given to
601    * their constructor.
602    * <p>
603    *
604    * @author <a HREF="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
605    *
606    */

607   private static class SelectionAdaptJCheckBoxMenuItem
608       extends JCheckBoxMenuItem JavaDoc {
609
610     /**
611      * Creates an instance with the given name that listens to the components
612      * background color, foreground color and font.
613      * <p>
614      *
615      * The source of the {@link java.awt.event.ActionEvent} given to the
616      * {@link Action} ({@link java.util.EventObject#getSource()}) will be of
617      * type {@link JRadioButtonMenuItem}.
618      * <p>
619      *
620      * @param action
621      * The <code>Action</code> to trigger when this item is clicked.
622      *
623      * @param state
624      * the initial state of the checkbox.
625      */

626     public SelectionAdaptJCheckBoxMenuItem(final Action JavaDoc action, final boolean state) {
627       super(action);
628       this.setSelected(state);
629       if (action != null) {
630         action.addPropertyChangeListener(new SelectionPropertyAdaptSupport(this));
631       }
632     }
633
634     /**
635      * @see javax.swing.AbstractButton#setAction(javax.swing.Action)
636      */

637     public void setAction(final Action JavaDoc a) {
638       if (a != null) {
639         super.setAction(a);
640         a.addPropertyChangeListener(new SelectionPropertyAdaptSupport(this));
641       }
642     }
643
644   }
645
646   /**
647    * A <code>JMenu</code> that listens for changes of background color,
648    * foreground color and font of the given <code>JComponent</code> and adapts
649    * it's own settings.
650    * <p>
651    *
652    * @author <a HREF="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
653    *
654    */

655   private static class PropertyChangeMenu
656       extends JMenu JavaDoc {
657     /**
658      * Generated <code>serialVersionUID</code>.
659      */

660     private static final long serialVersionUID = 3256437027795973685L;
661
662     /**
663      * Creates an instance with the given name that listens to the components
664      * background color, foreground color and font.
665      * <p>
666      *
667      * @param name
668      * The name to display.
669      *
670      * @param component
671      * The component to whose background color this item will adapt.
672      */

673     public PropertyChangeMenu(final JComponent JavaDoc component, final String JavaDoc name) {
674       super(name);
675       new BasicPropertyAdaptSupport(this, component);
676
677     }
678   }
679
680   /**
681    * A <code>JMenuItem</code> that listens for changes of background color,
682    * foreground color and font of the given <code>JComponent</code> and adapts
683    * it's own settings.
684    * <p>
685    *
686    * @author <a HREF="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
687    *
688    */

689   private static class PropertyChangeMenuItem
690       extends JMenuItem JavaDoc {
691
692     /**
693      * Generated <code>serialVersionUID</code>.
694      */

695     private static final long serialVersionUID = 3690196534012752439L;
696
697     /**
698      * Creates an instance with the given name that listens to the components
699      * background color, foreground color and font.
700      * <p>
701      *
702      * @param component
703      * The component to whose background color this item will adapt.
704      *
705      * @param action
706      * The <code>Action</code> to trigger when this item is clicked.
707      */

708     public PropertyChangeMenuItem(final JComponent JavaDoc component, final Action JavaDoc action) {
709       super(action);
710       new BasicPropertyAdaptSupport(this, component);
711     }
712   }
713
714   /**
715    * A <code>JPopupMenu</code> that listens for changes of background color,
716    * foreground color and font of the given <code>JComponent</code> and adapts
717    * it's own settings.
718    * <p>
719    *
720    * @author <a HREF="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
721    *
722    */

723
724   private static class PropertyChangePopupMenu
725       extends JPopupMenu JavaDoc {
726
727     /**
728      * Generated <code>serialVersionUID</code>.
729      */

730     private static final long serialVersionUID = 3617013061525780016L;
731
732     /**
733      * @param component
734      * The component to whose background color this item will adapt.
735      */

736     public PropertyChangePopupMenu(final JComponent JavaDoc component) {
737       new BasicPropertyAdaptSupport(this, component);
738     }
739   }
740
741   /**
742    * A <code>JPopupMenu</code> that listens for changes of background color,
743    * foreground color and font of the given <code>JComponent</code> and adapts
744    * it's own settings.
745    * <p>
746    *
747    * @author <a HREF="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
748    *
749    */

750
751   private static class PropertyChangeJMenuBar
752       extends JMenuBar JavaDoc {
753
754     /**
755      * @param component
756      * The component to whose background color this item will adapt.
757      */

758     public PropertyChangeJMenuBar(final JComponent JavaDoc component) {
759       new BasicPropertyAdaptSupport(this, component);
760     }
761   }
762
763   /**
764    * <p>
765    * Implementation for a <code>PropertyChangeListener</code> that adpapts a
766    * wrapped <code>JComponent</code> to the following properties.
767    * <p>
768    *
769    * <ul>
770    * <li>background color</li>
771    * <li>foreground color (text)</li>
772    * <li>font</li>
773    * </ul>
774    * <p>
775    *
776    * @author <a HREF="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
777    *
778    */

779   public static class SelectionPropertyAdaptSupport implements PropertyChangeListener JavaDoc {
780
781     /** The model to adapt selection upon. */
782     protected WeakReference JavaDoc m_delegate;
783
784     /**
785      *
786      * @param delegate
787      * The component to adapt the properties on.
788      */

789     public SelectionPropertyAdaptSupport(final AbstractButton JavaDoc delegate) {
790       this.m_delegate = new WeakReference JavaDoc(delegate);
791     }
792
793     /**
794      * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
795      */

796     public void propertyChange(final PropertyChangeEvent JavaDoc evt) {
797       String JavaDoc prop = evt.getPropertyName();
798       AbstractButton JavaDoc button = (AbstractButton JavaDoc) this.m_delegate.get();
799       if (button != null) {
800         if (prop.equals(LayoutFactory.PropertyChangeCheckBoxMenuItem.PROPERTY_SELECTED)) {
801           boolean state = ((Boolean JavaDoc) evt.getNewValue()).booleanValue();
802           button.setSelected(state);
803         }
804       } else {
805         ((Component JavaDoc) evt.getSource()).removePropertyChangeListener(this);
806       }
807     }
808
809   }
810
811   /**
812    * <p>
813    * A <code>JLabel</code> that implements <code>ActionListener</code> in
814    * order to change it's text color whenever the color of a corresponding
815    * {@link ITrace2D} is changed.
816    * </p>
817    *
818    * @author <a HREF="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
819    *
820    */

821   final class TraceJLabel
822       extends JLabel JavaDoc implements PropertyChangeListener JavaDoc {
823
824     /**
825      * Generated <code>serialVersionUID</code>.
826      */

827     private static final long serialVersionUID = 3617290112636172342L;
828
829     /**
830      * Creates a label with the given name.
831      * <p>
832      *
833      * @param name
834      * the name of the label.
835      */

836     public TraceJLabel(final String JavaDoc name) {
837       super(name);
838     }
839
840     /**
841      * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
842      */

843     public void propertyChange(final PropertyChangeEvent JavaDoc evt) {
844       String JavaDoc propertyName = evt.getPropertyName();
845       if (propertyName.equals(ITrace2D.PROPERTY_COLOR)) {
846         Color color = (Color) evt.getNewValue();
847         Color background = this.getBackground();
848         if (color.equals(background)) {
849           this.setBackground(this.getForeground());
850         }
851         this.setForeground(color);
852       } else if (propertyName.equals(Chart2D.PROPERTY_BACKGROUND_COLOR)) {
853         Color background = (Color) evt.getNewValue();
854         Color foreground = this.getForeground();
855         if (background.equals(foreground)) {
856           this.setForeground(this.getBackground());
857         }
858         this.setBackground(background);
859       } else if (propertyName.equals(Chart2D.PROPERTY_FONT)) {
860         Font JavaDoc font = (Font JavaDoc) evt.getNewValue();
861         this.setFont(font);
862       } else if (propertyName.equals(ITrace2D.PROPERTY_NAME)) {
863         String JavaDoc name = (String JavaDoc) evt.getNewValue();
864         this.setText(name);
865       }
866     }
867   }
868
869   /** The singleton instance of this factory. */
870   private static LayoutFactory instance;
871
872   /**
873    * Singleton retrival method.
874    * <p>
875    *
876    * @return the single instance of this factory within this VM.
877    */

878   public static LayoutFactory getInstance() {
879     if (LayoutFactory.instance == null) {
880       LayoutFactory.instance = new LayoutFactory();
881     }
882     return LayoutFactory.instance;
883   }
884
885   /**
886    * Stroke names, quick hack - no "NamedStroke" subtype.
887    */

888   private String JavaDoc[] m_strokeNames;
889
890   /**
891    * Shared strokes.
892    */

893   private Stroke[] m_strokes;
894
895   /**
896    * Singleton constructor.
897    * <p>
898    */

899   private LayoutFactory() {
900     super();
901     this.m_strokes = new Stroke[6];
902     this.m_strokeNames = new String JavaDoc[6];
903     this.m_strokes[0] = new BasicStroke JavaDoc();
904     this.m_strokeNames[0] = "basic";
905     this.m_strokes[1] = new BasicStroke JavaDoc(2);
906     this.m_strokeNames[1] = "thick";
907     this.m_strokes[2] = new BasicStroke JavaDoc(6, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 10.0f,
908         new float[] {0, 10f }, 0f);
909     this.m_strokeNames[2] = "round caps";
910     this.m_strokes[3] = new BasicStroke JavaDoc(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.5f,
911         new float[] {5f, 5f }, 2.5f);
912     this.m_strokeNames[3] = "dashed";
913     this.m_strokes[4] = new BasicStroke JavaDoc(6, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND, 10.0f,
914         new float[] {0, 10f }, 0f);
915     this.m_strokeNames[4] = "square caps";
916     this.m_strokes[5] = new BasicStroke JavaDoc(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 1.5f,
917         new float[] {2f, 2f }, 1f);
918     this.m_strokeNames[5] = "dashed thick";
919   }
920
921   /**
922    * Creates a {@link JMenuItem} that allows to trigger the features related to
923    * {@link info.monitorenter.gui.chart.AAxis} features.
924    * <p>
925    *
926    * @param axis
927    * the axis to control.
928    *
929    * @param axisDimension
930    * Identifies which dimension the axis controls in the chart: either
931    * {@link Chart2D#X} or {@link Chart2D#Y}
932    *
933    * @param adaptUI2Chart
934    * if true the menu will adapt it's basic UI properies (font,
935    * foreground and background color) to the given chart.
936    *
937    *
938    * @return a {@link JMenuItem} that allows to trigger the features related to
939    * {@link info.monitorenter.gui.chart.AAxis} features.
940    */

941   protected JMenuItem JavaDoc createAxisMenuItem(final IAxis axis, final int axisDimension,
942       final boolean adaptUI2Chart) {
943     final Chart2D chart = axis.getAccessor().getChart();
944     JMenuItem JavaDoc item;
945
946     // axis submenu
947
JMenuItem JavaDoc axisMenuItem;
948     if (adaptUI2Chart) {
949       axisMenuItem = new PropertyChangeMenu(chart, "Axis" + axis.getAccessor().toString());
950     } else {
951       axisMenuItem = new JMenu JavaDoc("Axis" + axis.getAccessor().toString());
952     }
953
954     axisMenuItem.add(createAxisTypeMenu(chart, axis, axisDimension, adaptUI2Chart));
955
956     axisMenuItem.add(createAxisRangePolicyMenu(chart, axis, adaptUI2Chart));
957
958     // Axis -> Range menu
959
if (adaptUI2Chart) {
960       item = new PropertyChangeMenuItem(chart, new AxisActionSetRange(axis, "Range"));
961     } else {
962       item = new JMenuItem JavaDoc(new AxisActionSetRange(axis, "Range"));
963     }
964     axisMenuItem.add(item);
965
966     // Axis -> show grid submenu
967
if (adaptUI2Chart) {
968       item = new PropertyChangeCheckBoxMenuItem(chart, new AxisActionSetGrid(axis, "Grid"), axis
969           .isPaintGrid());
970     } else {
971       item = new SelectionAdaptJCheckBoxMenuItem(new AxisActionSetGrid(axis, "Grid"), axis
972           .isPaintGrid());
973     }
974     axisMenuItem.add(item);
975     return axisMenuItem;
976   }
977
978   /**
979    * Creates a radio button menu for choose one the available
980    * {@link info.monitorenter.gui.chart.IRangePolicy} implementations to set to
981    * it's axis identified by argument <code>axis</code>.
982    * <p>
983    *
984    * @param axis
985    * the axis to control.
986    *
987    * @param adaptUI2Chart
988    * if true the menu will adapt it's basic UI properies (font,
989    * foreground and background color) to the given chart.
990    *
991    * @return a radio button menu for choose one the available
992    * {@link info.monitorenter.gui.chart.IRangePolicy} implementations to
993    * set to it's axis identified by argument <code>axis</code>.
994    */

995   public JMenu JavaDoc createAxisRangePolicyMenu(final Chart2D chart, final IAxis axis,
996       final boolean adaptUI2Chart) {
997     JMenuItem JavaDoc item;
998     // Axis -> Range policy submenu
999
JMenu JavaDoc axisRangePolicy;
1000    if (adaptUI2Chart) {
1001      axisRangePolicy = new PropertyChangeMenu(chart, "Range policy");
1002    } else {
1003      axisRangePolicy = new JMenu JavaDoc("Range policy");
1004    }
1005    // Use a button group to control unique selection state of radio buttons:
1006
ButtonGroup JavaDoc buttonGroup = new ButtonGroup JavaDoc();
1007    // check the default selected item:
1008
Class JavaDoc rangePolicyClass = axis.getRangePolicy().getClass();
1009    if (adaptUI2Chart) {
1010      item = new PropertyChangeJRadioButtonMenuItem(chart, new AxisActionSetRangePolicy(axis,
1011          "Fixed viewport", new RangePolicyFixedViewport()));
1012    } else {
1013      item = new SelectionAdaptJRadioButtonMenuItem(new AxisActionSetRangePolicy(axis,
1014          "Fixed viewport", new RangePolicyFixedViewport()));
1015    }
1016    item
1017        .setToolTipText("Zooms or expands to the configured range without respect to the data to display. ");
1018    axisRangePolicy.add(item);
1019    buttonGroup.add(item);
1020    if (rangePolicyClass == RangePolicyFixedViewport.class) {
1021      buttonGroup.setSelected(item.getModel(), true);
1022    }
1023
1024    if (adaptUI2Chart) {
1025      item = new PropertyChangeJRadioButtonMenuItem(chart, new AxisActionSetRangePolicy(axis,
1026          "Minimum viewport", new RangePolicyUnbounded()));
1027    } else {
1028      item = new SelectionAdaptJRadioButtonMenuItem(new AxisActionSetRangePolicy(axis,
1029          "Minimum viewport", new RangePolicyUnbounded()));
1030    }
1031    axisRangePolicy.add(item);
1032    item.setToolTipText("Ensures all data is shown with minimal bounds.");
1033    buttonGroup.add(item);
1034    if (rangePolicyClass == RangePolicyUnbounded.class) {
1035      buttonGroup.setSelected(item.getModel(), true);
1036    }
1037
1038    if (adaptUI2Chart) {
1039      item = new PropertyChangeJRadioButtonMenuItem(chart, new AxisActionSetRangePolicy(axis,
1040          "Minimum viewport with range", new RangePolicyMinimumViewport(new Range(10, 10))));
1041    } else {
1042      item = new SelectionAdaptJRadioButtonMenuItem(new AxisActionSetRangePolicy(axis,
1043          "Minimum viewport with range", new RangePolicyMinimumViewport(new Range(10, 10))));
1044    }
1045    item.setToolTipText("Ensures that all data is shown and expands if range is higher. ");
1046    axisRangePolicy.add(item);
1047    buttonGroup.add(item);
1048    if (rangePolicyClass == RangePolicyMinimumViewport.class) {
1049      buttonGroup.setSelected(item.getModel(), true);
1050    }
1051
1052    if (adaptUI2Chart) {
1053      item = new PropertyChangeJRadioButtonMenuItem(chart, new AxisActionSetRangePolicy(axis,
1054          "Ensure visible point", new RangePolicyForcedPoint(0)));
1055    } else {
1056      item = new SelectionAdaptJRadioButtonMenuItem(new AxisActionSetRangePolicy(axis,
1057          "Ensure visible point", new RangePolicyForcedPoint(0)));
1058    }
1059    item.setToolTipText("Only the minimum value of the axis' range will be ensured to be visible.");
1060    axisRangePolicy.add(item);
1061    buttonGroup.add(item);
1062    if (rangePolicyClass == RangePolicyForcedPoint.class) {
1063      buttonGroup.setSelected(item.getModel(), true);
1064    }
1065
1066    if (adaptUI2Chart) {
1067      item = new PropertyChangeJRadioButtonMenuItem(chart, new AxisActionSetRangePolicy(axis,
1068          "Highest points within max-50 to max.", new RangePolicyHighestValues(50)));
1069    } else {
1070      item = new SelectionAdaptJRadioButtonMenuItem(new AxisActionSetRangePolicy(axis,
1071          "Highest points within max-50 to max.", new RangePolicyHighestValues(50)));
1072    }
1073    item.setToolTipText("Shows the highest values from max-50 to max.");
1074    axisRangePolicy.add(item);
1075    buttonGroup.add(item);
1076    if (rangePolicyClass == RangePolicyHighestValues.class) {
1077      buttonGroup.setSelected(item.getModel(), true);
1078    }
1079    return axisRangePolicy;
1080  }
1081
1082  /**
1083   * Creates a radio button menu for choose one the available axis types of the
1084   * given chart that will be set to it's axis identified by argument
1085   * <code>axisDimension</code>.
1086   * <p>
1087   *
1088   * @param axis
1089   * the axis to control.
1090   *
1091   * @param axisDimension
1092   * Identifies which dimension the axis controls in the chart: either
1093   * {@link Chart2D#X} or {@link Chart2D#Y}
1094   *
1095   * @param adaptUI2Chart
1096   * if true the menu will adapt it's basic UI properies (font,
1097   * foreground and background color) to the given chart.
1098   *
1099   * @return a radio button menu for choose one the available axis types of the
1100   * given chart that will be set to it's axis identified by argument
1101   * <code>axisDimension</code>.
1102   */

1103  public JMenu JavaDoc createAxisTypeMenu(final Chart2D chart, final IAxis axis, final int axisDimension,
1104      final boolean adaptUI2Chart) {
1105    // Axis -> Axis type
1106
JMenu JavaDoc axisType;
1107    if (adaptUI2Chart) {
1108      axisType = new PropertyChangeMenu(chart, "Type");
1109    } else {
1110      axisType = new JMenu JavaDoc("Type");
1111    }
1112    // Use a button group to control unique selection state of radio buttons:
1113
ButtonGroup JavaDoc buttonGroup = new ButtonGroup JavaDoc();
1114    // check the default selected item:
1115
Class JavaDoc typeClass = axis.getClass();
1116    JMenuItem JavaDoc item;
1117
1118    if (adaptUI2Chart) {
1119      item = new PropertyChangeJRadioButtonMenuItem(chart, new Chart2DActionSetAxis(chart,
1120          new AxisLinear(), "Linear", axisDimension));
1121    } else {
1122      item = new SelectionAdaptJRadioButtonMenuItem(new Chart2DActionSetAxis(chart,
1123          new AxisLinear(), "Linear", axisDimension));
1124    }
1125    axisType.add(item);
1126    buttonGroup.add(item);
1127    if (typeClass == AxisLinear.class) {
1128      buttonGroup.setSelected(item.getModel(), true);
1129    }
1130    if (adaptUI2Chart) {
1131      item = new PropertyChangeJRadioButtonMenuItem(chart, new Chart2DActionSetAxis(chart,
1132          new AxisLogE(), "Log E", axisDimension));
1133    } else {
1134      item = new SelectionAdaptJRadioButtonMenuItem(new Chart2DActionSetAxis(chart, new AxisLogE(),
1135          "Log E", axisDimension));
1136    }
1137    axisType.add(item);
1138    buttonGroup.add(item);
1139    if (typeClass == AxisLogE.class) {
1140      buttonGroup.setSelected(item.getModel(), true);
1141    }
1142    if (adaptUI2Chart) {
1143      item = new PropertyChangeJRadioButtonMenuItem(chart, new Chart2DActionSetAxis(chart,
1144          new AxisLog10(), "Log 10", axisDimension));
1145    } else {
1146      item = new SelectionAdaptJRadioButtonMenuItem(new Chart2DActionSetAxis(chart,
1147          new AxisLog10(), "Log 10", axisDimension));
1148    }
1149    axisType.add(item);
1150    buttonGroup.add(item);
1151    if (typeClass == AxisLog10.class) {
1152      buttonGroup.setSelected(item.getModel(), true);
1153    }
1154
1155    return axisType;
1156  }
1157
1158  /**
1159   * Creates a menu for choosing the background color of the given chart.
1160   * <p>
1161   *
1162   * @param chart
1163   * the chart to set the background color of by the menu to return.
1164   *
1165   * @param adaptUI2Chart
1166   * if true the menu will adapt it's basic UI properies (font,
1167   * foreground and background color) to the given chart.
1168   *
1169   * @return a menu for choosing the background color of the given chart.
1170   */

1171  public JMenu JavaDoc createBackgroundColorMenu(final Chart2D chart, final boolean adaptUI2Chart) {
1172    Color backgroundColor = chart.getBackground();
1173    boolean nonStandardColor = true;
1174
1175    // Background color menu:
1176
JMenuItem JavaDoc item;
1177    JMenu JavaDoc bgColorMenu;
1178    if (adaptUI2Chart) {
1179      bgColorMenu = new PropertyChangeMenu(chart, "Background color");
1180    } else {
1181      bgColorMenu = new JMenu JavaDoc("Background color");
1182    }
1183
1184    ButtonGroup JavaDoc buttonGroup = new ButtonGroup JavaDoc();
1185    if (adaptUI2Chart) {
1186      item = new PropertyChangeJRadioButtonMenuItem(chart, new JComponentActionSetBackground(chart,
1187          "White", Color.WHITE));
1188    } else {
1189      item = new SelectionAdaptJRadioButtonMenuItem(new JComponentActionSetBackground(chart,
1190          "White", Color.WHITE));
1191    }
1192    if (backgroundColor.equals(Color.WHITE)) {
1193      item.setSelected(true);
1194      nonStandardColor = false;
1195    }
1196    buttonGroup.add(item);
1197    bgColorMenu.add(item);
1198    if (adaptUI2Chart) {
1199      item = new PropertyChangeJRadioButtonMenuItem(chart, new JComponentActionSetBackground(chart,
1200          "Gray", Color.GRAY));
1201    } else {
1202      item = new SelectionAdaptJRadioButtonMenuItem(new JComponentActionSetBackground(chart,
1203          "Gray", Color.GRAY));
1204    }
1205    if (backgroundColor.equals(Color.GRAY)) {
1206      item.setSelected(true);
1207      nonStandardColor = false;
1208    }
1209    buttonGroup.add(item);
1210    bgColorMenu.add(item);
1211    if (adaptUI2Chart) {
1212      item = new PropertyChangeJRadioButtonMenuItem(chart, new JComponentActionSetBackground(chart,
1213          "Light gray", Color.LIGHT_GRAY));
1214    } else {
1215      item = new SelectionAdaptJRadioButtonMenuItem(new JComponentActionSetBackground(chart,
1216          "Light gray", Color.LIGHT_GRAY));
1217    }
1218    if (backgroundColor.equals(Color.LIGHT_GRAY)) {
1219      item.setSelected(true);
1220      nonStandardColor = false;
1221    }
1222    buttonGroup.add(item);
1223    bgColorMenu.add(item);
1224    if (adaptUI2Chart) {
1225      item = new PropertyChangeJRadioButtonMenuItem(chart, new JComponentActionSetBackground(chart,
1226          "Black", Color.BLACK));
1227    } else {
1228      item = new SelectionAdaptJRadioButtonMenuItem(new JComponentActionSetBackground(chart,
1229          "Black", Color.BLACK));
1230    }
1231    if (backgroundColor.equals(Color.BLACK)) {
1232      item.setSelected(true);
1233      nonStandardColor = false;
1234    }
1235    buttonGroup.add(item);
1236    bgColorMenu.add(item);
1237    if (adaptUI2Chart) {
1238      item = new PropertyChangeJRadioButtonMenuItem(chart,
1239          JComponentActionSetCustomBackgroundSingleton.getInstance(chart, "Custom Color"));
1240    } else {
1241      item = new SelectionAdaptJRadioButtonMenuItem(JComponentActionSetCustomBackgroundSingleton
1242          .getInstance(chart, "Custom Color"));
1243    }
1244    item.setSelected(nonStandardColor);
1245    buttonGroup.add(item);
1246    bgColorMenu.add(item);
1247    return bgColorMenu;
1248  }
1249
1250  /**
1251   * Creates a menu for choosing the foreground color of the given chart.
1252   * <p>
1253   *
1254   * @param chart
1255   * the chart to set the foreground color of by the menu to return.
1256   *
1257   * @param adaptUI2Chart
1258   * if true the menu will adapt it's basic UI properies (font,
1259   * foreground and background color) to the given chart.
1260   *
1261   * @return a menu for choosing the foreground color of the given chart.
1262   */

1263  public JMenuItem JavaDoc createForegroundColorMenu(final Chart2D chart, final boolean adaptUI2Chart) {
1264
1265    Color foregroundColor = chart.getForeground();
1266    boolean nonStandardColor = true;
1267    ButtonGroup JavaDoc buttonGroup = new ButtonGroup JavaDoc();
1268
1269    JMenuItem JavaDoc item;
1270    JMenu JavaDoc fgColorMenu;
1271    if (adaptUI2Chart) {
1272      fgColorMenu = new PropertyChangeMenu(chart, "Foreground color");
1273    } else {
1274      fgColorMenu = new JMenu JavaDoc("Foreground color");
1275    }
1276    if (adaptUI2Chart) {
1277      item = new PropertyChangeJRadioButtonMenuItem(chart, new JComponentActionSetForeground(chart,
1278          "White", Color.WHITE));
1279    } else {
1280      item = new SelectionAdaptJRadioButtonMenuItem(new JComponentActionSetForeground(chart,
1281          "White", Color.WHITE));
1282    }
1283    if (foregroundColor.equals(Color.WHITE)) {
1284      item.setSelected(true);
1285      nonStandardColor = false;
1286    }
1287    buttonGroup.add(item);
1288    fgColorMenu.add(item);
1289    if (adaptUI2Chart) {
1290      item = new PropertyChangeJRadioButtonMenuItem(chart, new JComponentActionSetForeground(chart,
1291          "Gray", Color.GRAY));
1292    } else {
1293      item = new SelectionAdaptJRadioButtonMenuItem(new JComponentActionSetForeground(chart,
1294          "Gray", Color.GRAY));
1295    }
1296    if (foregroundColor.equals(Color.GRAY)) {
1297      item.setSelected(true);
1298      nonStandardColor = false;
1299    }
1300    buttonGroup.add(item);
1301    fgColorMenu.add(item);
1302    if (adaptUI2Chart) {
1303      item = new PropertyChangeJRadioButtonMenuItem(chart, new JComponentActionSetForeground(chart,
1304          "Light gray", Color.LIGHT_GRAY));
1305    } else {
1306      item = new SelectionAdaptJRadioButtonMenuItem(new JComponentActionSetForeground(chart,
1307          "Light gray", Color.LIGHT_GRAY));
1308    }
1309    if (foregroundColor.equals(Color.LIGHT_GRAY)) {
1310      item.setSelected(true);
1311      nonStandardColor = false;
1312    }
1313    buttonGroup.add(item);
1314    fgColorMenu.add(item);
1315    if (adaptUI2Chart) {
1316      item = new PropertyChangeJRadioButtonMenuItem(chart, new JComponentActionSetForeground(chart,
1317          "Black", Color.BLACK));
1318    } else {
1319      item = new SelectionAdaptJRadioButtonMenuItem(new JComponentActionSetForeground(chart,
1320          "Black", Color.BLACK));
1321    }
1322    if (foregroundColor.equals(Color.BLACK)) {
1323      item.setSelected(true);
1324      nonStandardColor = false;
1325    }
1326    buttonGroup.add(item);
1327    fgColorMenu.add(item);
1328    if (adaptUI2Chart) {
1329      item = new PropertyChangeJRadioButtonMenuItem(chart,
1330          JComponentActionSetCustomForegroundSingleton.getInstance(chart, "Custom Color"));
1331    } else {
1332      item = new SelectionAdaptJRadioButtonMenuItem(JComponentActionSetCustomForegroundSingleton
1333          .getInstance(chart, "Custom Color"));
1334    }
1335    item.setSelected(nonStandardColor);
1336    buttonGroup.add(item);
1337    fgColorMenu.add(item);
1338    return fgColorMenu;
1339  }
1340
1341  /**
1342   * Creates a menu for choosing the grid color of the given chart.
1343   * <p>
1344   *
1345   * @param chart
1346   * the chart to set the grid color of by the menu to return.
1347   *
1348   * @param adaptUI2Chart
1349   * if true the menu will adapt it's basic UI properies (font,
1350   * foreground and background color) to the given chart.
1351   *
1352   * @return a menu for choosing the grid color of the given chart.
1353   */

1354  public JMenu JavaDoc createGridColorMenu(final Chart2D chart, final boolean adaptUI2Chart) {
1355    JMenuItem JavaDoc item;
1356    Color gridColor = chart.getGridColor();
1357    boolean nonStandardColor = true;
1358    ButtonGroup JavaDoc buttonGroup = new ButtonGroup JavaDoc();
1359
1360    JMenu JavaDoc gridColorMenu;
1361    if (adaptUI2Chart) {
1362      gridColorMenu = new PropertyChangeMenu(chart, "Grid color");
1363    } else {
1364      gridColorMenu = new JMenu JavaDoc("Grid color");
1365    }
1366
1367    if (adaptUI2Chart) {
1368      item = new PropertyChangeJRadioButtonMenuItem(chart, new Chart2DActionSetGridColor(chart,
1369          "Gray", Color.GRAY));
1370    } else {
1371      item = new SelectionAdaptJRadioButtonMenuItem(new Chart2DActionSetGridColor(chart, "Gray",
1372          Color.GRAY));
1373    }
1374    if (gridColor.equals(Color.GRAY)) {
1375      item.setSelected(true);
1376      nonStandardColor = false;
1377    }
1378    buttonGroup.add(item);
1379    gridColorMenu.add(item);
1380    if (adaptUI2Chart) {
1381      item = new PropertyChangeJRadioButtonMenuItem(chart, new Chart2DActionSetGridColor(chart,
1382          "Light gray", Color.LIGHT_GRAY));
1383    } else {
1384      item = new SelectionAdaptJRadioButtonMenuItem(new Chart2DActionSetGridColor(chart,
1385          "Light gray", Color.LIGHT_GRAY));
1386    }
1387    if (gridColor.equals(Color.LIGHT_GRAY)) {
1388      item.setSelected(true);
1389      nonStandardColor = false;
1390    }
1391
1392    buttonGroup.add(item);
1393    gridColorMenu.add(item);
1394    if (adaptUI2Chart) {
1395      item = new PropertyChangeJRadioButtonMenuItem(chart, new Chart2DActionSetGridColor(chart,
1396          "Black", Color.BLACK));
1397    } else {
1398      item = new SelectionAdaptJRadioButtonMenuItem(new Chart2DActionSetGridColor(chart, "Black",
1399          Color.BLACK));
1400    }
1401    if (gridColor.equals(Color.BLACK)) {
1402      item.setSelected(true);
1403      nonStandardColor = false;
1404    }
1405    buttonGroup.add(item);
1406    gridColorMenu.add(item);
1407    if (adaptUI2Chart) {
1408      item = new PropertyChangeJRadioButtonMenuItem(chart, new Chart2DActionSetGridColor(chart,
1409          "White", Color.WHITE));
1410    } else {
1411      item = new SelectionAdaptJRadioButtonMenuItem(new Chart2DActionSetGridColor(chart, "White",
1412          Color.WHITE));
1413    }
1414    if (gridColor.equals(Color.WHITE)) {
1415      item.setSelected(true);
1416      nonStandardColor = false;
1417    }
1418    buttonGroup.add(item);
1419    gridColorMenu.add(item);
1420    if (adaptUI2Chart) {
1421      item = new PropertyChangeJRadioButtonMenuItem(chart, Chart2DActionSetCustomGridColorSingleton
1422          .getInstance(chart, "Custom"));
1423    } else {
1424      item = new SelectionAdaptJRadioButtonMenuItem(Chart2DActionSetCustomGridColorSingleton
1425          .getInstance(chart, "Custom"));
1426    }
1427    item.setSelected(nonStandardColor);
1428    buttonGroup.add(item);
1429    gridColorMenu.add(item);
1430    return gridColorMenu;
1431  }
1432
1433  /**
1434   * Adds a popup menu to the given chart that offers various controls over it.
1435   * <p>
1436   *
1437   * @param chart
1438   * the chart to add the popup menue to.
1439   *
1440   * @param adaptUI2Chart
1441   * if true the menu will adapt it's basic UI properies (font,
1442   * foreground and background color) to the given chart.
1443   */

1444  public void createPopupMenu(final Chart2D chart, final boolean adaptUI2Chart) {
1445
1446    // Color background = chart.getBackground();
1447

1448    // Axis submenu:
1449
JMenu JavaDoc axisMenu;
1450    if (adaptUI2Chart) {
1451      axisMenu = new PropertyChangeMenu(chart, "Axis");
1452    } else {
1453      axisMenu = new JMenu JavaDoc("Axis");
1454    }
1455    // axisMenu.setBackground(background);
1456

1457    // X axis submenu
1458
JMenuItem JavaDoc xAxisMenuItem = this.createAxisMenuItem(chart.getAxisX(), Chart2D.X, adaptUI2Chart);
1459    axisMenu.add(xAxisMenuItem);
1460    // Y axis submenu
1461
JMenuItem JavaDoc yAxisMenuItem = this.createAxisMenuItem(chart.getAxisY(), Chart2D.Y, adaptUI2Chart);
1462    axisMenu.add(yAxisMenuItem);
1463
1464    // fill top-level popup menu
1465
JPopupMenu JavaDoc popup;
1466    if (adaptUI2Chart) {
1467      popup = new PropertyChangePopupMenu(chart);
1468    } else {
1469      popup = new JPopupMenu JavaDoc();
1470    }
1471    popup.add(createBackgroundColorMenu(chart, adaptUI2Chart));
1472    popup.add(createForegroundColorMenu(chart, adaptUI2Chart));
1473    popup.add(createGridColorMenu(chart, adaptUI2Chart));
1474    popup.add(axisMenu);
1475    chart.addMouseListener(new PopupListener(popup));
1476  }
1477
1478  /**
1479   * Creates a menu bar that offers various controls over the given chart.
1480   * <p>
1481   *
1482   * @param chart
1483   * the chart to access.
1484   *
1485   * @param adaptUI2Chart
1486   * if true the menu will adapt it's basic UI properies (font,
1487   * foreground and background color) to the given chart.
1488   */

1489  public JMenuBar JavaDoc createMenuBar(final Chart2D chart, final boolean adaptUI2Chart) {
1490
1491    JMenu JavaDoc chartMenu = createMenu(chart, adaptUI2Chart);
1492    JMenuBar JavaDoc menubar;
1493    if (adaptUI2Chart) {
1494      menubar = new PropertyChangeJMenuBar(chart);
1495    } else {
1496      menubar = new JMenuBar JavaDoc();
1497    }
1498    menubar.add(chartMenu);
1499    return menubar;
1500  }
1501
1502  /**
1503   * Creates a menu that offers various controls over the given chart.
1504   * <p>
1505   *
1506   * @param chart
1507   * the chart to access.
1508   *
1509   * @param adaptUI2Chart
1510   * if true the menu will adapt it's basic UI properies (font,
1511   * foreground and background color) to the given chart.
1512   */

1513  public JMenu JavaDoc createMenu(final Chart2D chart, final boolean adaptUI2Chart) {
1514
1515    JMenu JavaDoc chartMenu;
1516    if (adaptUI2Chart) {
1517      chartMenu = new PropertyChangeMenu(chart, "Chart");
1518    } else {
1519      chartMenu = new JMenu JavaDoc("Chart");
1520    }
1521
1522    // Axis submenu:
1523
JMenu JavaDoc axisMenu;
1524    if (adaptUI2Chart) {
1525      axisMenu = new PropertyChangeMenu(chart, "Axis");
1526    } else {
1527      axisMenu = new JMenu JavaDoc("Axis");
1528    }
1529    // axisMenu.setBackground(background);
1530

1531    // X axis submenu
1532
JMenuItem JavaDoc xAxisMenuItem = this.createAxisMenuItem(chart.getAxisX(), Chart2D.X, adaptUI2Chart);
1533    axisMenu.add(xAxisMenuItem);
1534    // Y axis submenu
1535
JMenuItem JavaDoc yAxisMenuItem = this.createAxisMenuItem(chart.getAxisY(), Chart2D.Y, adaptUI2Chart);
1536    axisMenu.add(yAxisMenuItem);
1537
1538    // fill top-level popup menu
1539
chartMenu.add(createBackgroundColorMenu(chart, adaptUI2Chart));
1540    chartMenu.add(createForegroundColorMenu(chart, adaptUI2Chart));
1541    chartMenu.add(createGridColorMenu(chart, adaptUI2Chart));
1542    chartMenu.add(axisMenu);
1543
1544    return chartMenu;
1545  }
1546
1547  /**
1548   * <p>
1549   * Creates a <code>JLabel</code> that is capable of triggering a
1550   * <code>JPopupMenu</code> for the settings available for the
1551   * <code>ITrace2D</code>.
1552   * </p>
1553   *
1554   * @param chart
1555   * The chart the given trace is a member of. This will be used for
1556   * getting a <code>PopupMenu</code> that adapts to layout
1557   * properties (such as background color).
1558   *
1559   * @param trace
1560   * The trace on which the <code>JPopupMenu</code> of the
1561   * <code>JLabel</code> will act.
1562   *
1563   * @return a label that offers a popup menue with controls for the given
1564   * trace.
1565   */

1566  public JLabel JavaDoc createContextMenuLable(final Chart2D chart, final ITrace2D trace) {
1567    TraceJLabel ret = new TraceJLabel(trace.getLable());
1568
1569    // ret.setSize(new Dimension(20, 100));
1570
JPopupMenu JavaDoc popup = new PropertyChangePopupMenu(chart);
1571    // set the initial background color:
1572
Color background = chart.getBackground();
1573    ret.setBackground(background);
1574    ret.setForeground(trace.getColor());
1575
1576    // submenu for trace color
1577
JMenu JavaDoc colorMenu = new PropertyChangeMenu(chart, "Color");
1578    JMenuItem JavaDoc item = new PropertyChangeMenuItem(chart, new Trace2DActionSetColor(trace, "Red",
1579        Color.RED));
1580    colorMenu.add(item);
1581    item = new PropertyChangeMenuItem(chart, new Trace2DActionSetColor(trace, "Green", Color.GREEN));
1582    colorMenu.add(item);
1583    item = new PropertyChangeMenuItem(chart, new Trace2DActionSetColor(trace, "Blue", Color.BLUE));
1584    colorMenu.add(item);
1585    item = new PropertyChangeMenuItem(chart, new Trace2DActionSetColor(trace, "Gray", Color.GRAY));
1586    colorMenu.add(item);
1587    item = new PropertyChangeMenuItem(chart, new Trace2DActionSetColor(trace, "Magenta",
1588        Color.MAGENTA));
1589    colorMenu.add(item);
1590    item = new PropertyChangeMenuItem(chart, new Trace2DActionSetColor(trace, "Pink", Color.PINK));
1591    colorMenu.add(item);
1592    item = new PropertyChangeMenuItem(chart, new Trace2DActionSetColor(trace, "Black", Color.BLACK));
1593    colorMenu.add(item);
1594    item = new PropertyChangeMenuItem(chart, new Trace2DActionSetCustomColor(trace, "Custom", ret));
1595    colorMenu.add(item);
1596
1597    // submenu for zIndex
1598
JMenu JavaDoc zIndexMenu = new PropertyChangeMenu(chart, "layer");
1599    zIndexMenu.setBackground(background);
1600    item = new PropertyChangeMenuItem(chart, new Trace2DActionSetZindex(trace, "bring to front", 0));
1601    zIndexMenu.add(item);
1602    item = new PropertyChangeMenuItem(chart, new Trace2DActionSetZindex(trace, "send to back",
1603        ITrace2D.ZINDEX_MAX));
1604    zIndexMenu.add(item);
1605    item = new PropertyChangeMenuItem(chart, new Trace2DActionZindexDecrease(trace, "forward", 2));
1606    zIndexMenu.add(item);
1607    item = new PropertyChangeMenuItem(chart, new Trace2DActionZindexIncrease(trace, "backwards", 2));
1608    zIndexMenu.add(item);
1609
1610    // item for setVisible
1611
item = new PropertyChangeCheckBoxMenuItem(chart, new Trace2DActionSetVisible(trace, "Visible"),
1612        trace.isVisible());
1613    popup.add(item);
1614
1615    // item for setName
1616
item = new PropertyChangeMenuItem(chart, new Trace2DActionSetName(trace, "Name", chart));
1617    popup.add(item);
1618
1619    // strokes
1620
JMenu JavaDoc strokesMenu = new PropertyChangeMenu(chart, "Stroke");
1621    for (int i = 0; i < this.m_strokes.length; i++) {
1622      item = new PropertyChangeMenuItem(chart, new Trace2DActionSetStroke(trace,
1623          this.m_strokeNames[i], this.m_strokes[i]));
1624      strokesMenu.add(item);
1625    }
1626
1627    // trace painters
1628
JMenu JavaDoc painterMenu = new PropertyChangeMenu(chart, "renderer");
1629    ITracePainter painter = new TracePainterDisc(4);
1630    item = new OrderingCheckBoxMenuItem(chart, new Trace2DActionAddRemoveTracePainter(trace,
1631        "discs", painter), painterMenu, trace.containsTracePainter(painter));
1632    if (trace.getTracePainters().contains(painter)) {
1633      item.setSelected(true);
1634    }
1635    painterMenu.add(item);
1636
1637    painter = new TracePainterPolyline();
1638    item = new OrderingCheckBoxMenuItem(chart, new Trace2DActionAddRemoveTracePainter(trace,
1639        "line", painter), painterMenu, trace.containsTracePainter(painter));
1640    painterMenu.add(item);
1641    if (trace.getTracePainters().contains(painter)) {
1642      item.setSelected(true);
1643    }
1644
1645    painter = new TracePainterFill(chart);
1646    item = new OrderingCheckBoxMenuItem(chart, new Trace2DActionAddRemoveTracePainter(trace,
1647        "fill", painter), painterMenu, trace.containsTracePainter(painter));
1648    painterMenu.add(item);
1649    if (trace.getTracePainters().contains(painter)) {
1650      item.setSelected(true);
1651    }
1652
1653    // add the submenus
1654
popup.add(colorMenu);
1655    popup.add(zIndexMenu);
1656    popup.add(strokesMenu);
1657    popup.add(painterMenu);
1658
1659    ret.addMouseListener(new PopupListener(popup));
1660    new BasicPropertyAdaptSupport(ret, chart);
1661    return ret;
1662  }
1663}
1664
Popular Tags