KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > wings > SComponent


1 /*
2  * $Id: SComponent.java,v 1.45 2005/05/27 15:20:53 blueshift Exp $
3  * Copyright 2000,2005 wingS development team.
4  *
5  * This file is part of wingS (http://www.j-wings.org).
6  *
7  * wingS is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation; either version 2.1
10  * of the License, or (at your option) any later version.
11  *
12  * Please see COPYING for the complete licence.
13  */

14 package org.wings;
15
16
17 import org.apache.commons.logging.Log;
18 import org.apache.commons.logging.LogFactory;
19 import org.wings.border.SBorder;
20 import org.wings.event.SComponentEvent;
21 import org.wings.event.SComponentListener;
22 import org.wings.event.SParentFrameEvent;
23 import org.wings.event.SParentFrameListener;
24 import org.wings.event.SRenderEvent;
25 import org.wings.event.SRenderListener;
26 import org.wings.io.Device;
27 import org.wings.plaf.ComponentCG;
28 import org.wings.script.ScriptListener;
29 import org.wings.session.LowLevelEventDispatcher;
30 import org.wings.session.Session;
31 import org.wings.session.SessionManager;
32 import org.wings.style.CSSAttributeSet;
33 import org.wings.style.CSSProperty;
34 import org.wings.style.CSSSelector;
35 import org.wings.style.CSSStyle;
36 import org.wings.style.CSSStyleSheet;
37 import org.wings.style.Style;
38 import org.wings.util.ComponentVisitor;
39
40 import javax.swing.*;
41 import javax.swing.event.EventListenerList JavaDoc;
42 import java.awt.*;
43 import java.awt.event.ActionEvent JavaDoc;
44 import java.beans.BeanInfo JavaDoc;
45 import java.beans.Introspector JavaDoc;
46 import java.beans.PropertyDescriptor JavaDoc;
47 import java.io.IOException JavaDoc;
48 import java.io.Serializable JavaDoc;
49 import java.lang.reflect.Array JavaDoc;
50 import java.lang.reflect.Method JavaDoc;
51 import java.util.ArrayList JavaDoc;
52 import java.util.Arrays JavaDoc;
53 import java.util.Collection JavaDoc;
54 import java.util.Collections JavaDoc;
55 import java.util.EventListener JavaDoc;
56 import java.util.HashMap JavaDoc;
57 import java.util.Iterator JavaDoc;
58 import java.util.Map JavaDoc;
59
60 /**
61  * The basic component implementation for all components in this package.
62  *
63  * @author <a HREF="mailto:haaf@mercatis.de">Armin Haaf</a>
64  * @version $Revision: 1.45 $
65  */

66 public abstract class SComponent
67         implements Cloneable JavaDoc, Serializable JavaDoc, Renderable {
68     private static final Object JavaDoc[] EMPTY_OBJECT_ARRAY = new Object JavaDoc[0];
69
70     private static final Log log = LogFactory.getLog(SComponent.class);
71
72     /* Components unique name. */
73     private String JavaDoc name;
74
75     /**
76      * the session
77      */

78     private transient Session session;
79
80     /**
81      * The code generation delegate, which is responsible for
82      * the visual representation of this component.
83      */

84     protected transient ComponentCG cg;
85
86     /**
87      * Vertical alignment
88      */

89     protected int verticalAlignment = SConstants.NO_ALIGN;
90
91     /**
92      * Horizontal alignment
93      */

94     protected int horizontalAlignment = SConstants.NO_ALIGN;
95
96     /**
97      * The name of the style class
98      */

99     protected String JavaDoc style;
100
101     /**
102      * List of dynamic styles
103      */

104     protected Map JavaDoc dynamicStyles;
105
106     /**
107      * Visibility.
108      */

109     protected boolean visible = true;
110
111     /**
112      * Enabled / disabled.
113      */

114     protected boolean enabled = true;
115
116     /**
117      * The container, this component resides in.
118      */

119     protected SContainer parent;
120
121     /**
122      * The frame in which this component resides.
123      */

124     protected SFrame parentFrame;
125
126     /**
127      * The border for the component.
128      */

129     protected SBorder border;
130
131     /**
132      * The tooltip for this component.
133      */

134     protected String JavaDoc tooltip;
135
136     /**
137      * The focus traversal Index
138      */

139     protected int focusTraversalIndex = -1;
140
141     /**
142      * Preferred size of component in pixel.
143      */

144     protected SDimension preferredSize;
145
146     /**
147      * This is for performance optimizations. With this flag is set, property change
148      * events are generated and so every property setter method has to test if a property
149      * has changed and temporarily store the old value to generate the property
150      * change event
151      */

152     private boolean fireComponentChangeEvents = false;
153
154     private boolean fireParentFrameChangeEvents = false;
155
156     private EventListenerList JavaDoc listeners;
157
158     private Boolean JavaDoc useNamedEvents;
159
160     private boolean showAsFormComponent = true;
161
162     private SPopupMenu popupMenu;
163
164     private boolean inheritsPopupMenu;
165
166     private InputMap inputMap;
167
168     private ActionMap actionMap;
169
170     private final Map JavaDoc actionEvents = new HashMap JavaDoc();
171
172     private final CSSSelector thisComponentCssSelector = new CSSSelector(this);
173
174     /**
175      * Default constructor.cript
176      * The method updateCG is called to get a cg delegate installed.
177      */

178     public SComponent() {
179         updateCG();
180     }
181
182     public SBorder getBorder() {
183         return border;
184     }
185
186     public void setBorder(SBorder border) {
187         reloadIfChange(this.border, border);
188         this.border = border;
189     }
190
191     /**
192      * Return the parent container.
193      *
194      * @return the container this component resides in
195      */

196     public final SContainer getParent() {
197         return parent;
198     }
199
200     /**
201      * Sets the parent container. Also gets the parent frame from the parent.
202      *
203      * @param parent the container
204      */

205     public void setParent(SContainer parent) {
206         reloadIfChange(this.parent, parent);
207         this.parent = parent;
208         if (parent != null)
209             setParentFrame(parent.getParentFrame());
210         else
211             setParentFrame(null);
212     }
213
214     /**
215      * Sets the parent frame.
216      *
217      * @param parentFrame the frame
218      */

219     protected void setParentFrame(SFrame parentFrame) {
220         if (this.parentFrame == parentFrame) {
221             return;
222         }
223
224         if (this.parentFrame != null) {
225             unregister();
226             fireParentFrameEvent(new SParentFrameEvent(this, SParentFrameEvent.PARENTFRAME_REMOVED, this.parentFrame));
227         }
228
229         this.parentFrame = parentFrame;
230
231         if (this.parentFrame != null) {
232             register();
233             // notify the listeners...
234
fireParentFrameEvent(new SParentFrameEvent(this, SParentFrameEvent.PARENTFRAME_ADDED, this.parentFrame));
235         }
236
237         if (this.popupMenu != null) {
238             popupMenu.setParentFrame(parentFrame);
239         }
240
241         reload();
242     }
243
244     public void setInheritsPopupMenu(boolean inheritsPopupMenu) {
245         reloadIfChange(this.inheritsPopupMenu, inheritsPopupMenu);
246         this.inheritsPopupMenu = inheritsPopupMenu;
247     }
248
249     public boolean getInheritsPopupMenu() {
250         return inheritsPopupMenu;
251     }
252
253     public void setComponentPopupMenu(SPopupMenu popupMenu) {
254         reloadIfChange(this.popupMenu, popupMenu);
255         if (this.popupMenu != null)
256             this.popupMenu.setParentFrame(null);
257         this.popupMenu = popupMenu;
258         if (this.popupMenu != null)
259             this.popupMenu.setParentFrame(getParentFrame());
260     }
261
262     public SPopupMenu getComponentPopupMenu() {
263         /* (OL) we probably don't need the recursive stuff here... */
264 // if (!getInheritsPopupMenu())
265
// return popupMenu;
266
//
267
// if (popupMenu == null) {
268
// // Search parents for its popup
269
// SContainer parent = getParent();
270
// while (parent != null) {
271
// if (parent instanceof SComponent) {
272
// return ((SComponent) parent).getComponentPopupMenu();
273
// }
274
// if (parent instanceof SFrame)
275
// break;
276
//
277
// parent = parent.getParent();
278
// }
279
// return null;
280
// }
281
return popupMenu;
282     }
283
284     public boolean hasComponentPopupMenu() {
285         return popupMenu != null;
286     }
287
288     public RequestURL getRequestURL() {
289         SFrame p = getParentFrame();
290         if (p == null)
291             throw new IllegalStateException JavaDoc("no parent frame");
292
293         return p.getRequestURL();
294     }
295
296     /**
297      * Set the preferred size of the receiving component in pixel.
298      * It is not guaranteed that the component accepts this property because of
299      * missing implementations in the component cg or html properties.
300      * If <i>width</i> or <i>height</i> is zero, it is ignored and the browser
301      * defines the size.
302      *
303      * @see org.wings.SComponent#getPreferredSize
304      */

305     public void setPreferredSize(SDimension preferredSize) {
306         reloadIfChange(this.preferredSize, preferredSize);
307         this.preferredSize = preferredSize;
308     }
309
310     /**
311      * Get the preferred size of this component.
312      *
313      * @see SComponent#setPreferredSize
314      */

315     public SDimension getPreferredSize() {
316         return preferredSize;
317     }
318
319
320     /**
321      * Adds the specified component listener to receive component events from
322      * this component.
323      * If l is null, no exception is thrown and no action is performed.
324      *
325      * @param l the component listener.
326      * @see org.wings.event.SComponentEvent
327      * @see org.wings.event.SComponentListener
328      * @see org.wings.SComponent#removeComponentListener
329      */

330     public final void addComponentListener(SComponentListener l) {
331         addEventListener(SComponentListener.class, l);
332         fireComponentChangeEvents = true;
333     }
334
335     /**
336      * Removes the specified component listener so that it no longer
337      * receives component events from this component. This method performs
338      * no function, nor does it throw an exception, if the listener
339      * specified by the argument was not previously added to this component.
340      * If l is null, no exception is thrown and no action is performed.
341      *
342      * @param l the component listener.
343      * @see org.wings.event.SComponentEvent
344      * @see org.wings.event.SComponentListener
345      * @see org.wings.SComponent#addComponentListener
346      */

347     public final void removeComponentListener(SComponentListener l) {
348         removeEventListener(SComponentListener.class, l);
349     }
350
351     /**
352      * Adds the specified parent frame listener to receive events from
353      * this component.
354      * If l is null, no exception is thrown and no action is performed.
355      *
356      * @param l the parent frame listener.
357      * @see org.wings.event.SParentFrameEvent
358      * @see org.wings.event.SParentFrameListener
359      * @see org.wings.SComponent#removeParentFrameListener
360      */

361     public final void addParentFrameListener(SParentFrameListener l) {
362         addEventListener(SParentFrameListener.class, l);
363         fireParentFrameChangeEvents = true;
364     }
365
366     /**
367      * Removes the specified parent frame listener so that it no longer
368      * receives events from this component. This method performs
369      * no function, nor does it throw an exception, if the listener
370      * specified by the argument was not previously added to this component.
371      * If l is null, no exception is thrown and no action is performed.
372      *
373      * @param l the parent frame listener.
374      * @see org.wings.event.SParentFrameEvent
375      * @see org.wings.event.SParentFrameListener
376      * @see org.wings.SComponent#addParentFrameListener
377      */

378     public final void removeParentFrameListener(SParentFrameListener l) {
379         removeEventListener(SParentFrameListener.class, l);
380     }
381
382     /**
383      * Reports a component change.
384      *
385      * @param aEvent report this event to all listeners
386      * @see org.wings.event.SComponentListener
387      */

388     protected void fireComponentChangeEvent(SComponentEvent aEvent) {
389         // maybe the better way to do this is to user the getListenerList
390
// and iterate through all listeners, this saves the creation of
391
// an array but it must cast to the apropriate listener
392
Object JavaDoc[] listeners = getListenerList();
393         for (int i = listeners.length - 2; i >= 0; i -= 2) {
394             if (listeners[i] == SComponentListener.class) {
395                 // Lazily create the event:
396
processComponentEvent((SComponentListener) listeners[i + 1],
397                         aEvent);
398             }
399         }
400
401     }
402
403     /**
404      * Reports a parent frame change.
405      *
406      * @param aEvent report this event to all listeners
407      * @see org.wings.event.SParentFrameListener
408      */

409     private void fireParentFrameEvent(SParentFrameEvent aEvent) {
410         // are listeners registered?
411
if (fireParentFrameChangeEvents) {
412             // maybe the better way to do this is to user the getListenerList
413
// and iterate through all listeners, this saves the creation of
414
// an array but it must cast to the apropriate listener
415
Object JavaDoc[] listeners = getListenerList();
416             for (int i = listeners.length - 2; i >= 0; i -= 2) {
417                 if (listeners[i] == SParentFrameListener.class) {
418                     // Lazily create the event:
419
processParentFrameEvent((SParentFrameListener) listeners[i + 1],
420                             aEvent);
421                 }
422             }
423         }
424
425     }
426
427     /**
428      * Processes parent frame events occurring on this component by
429      * dispatching them to any registered
430      * <code>SParentFrameListener</code> objects.
431      * <p/>
432      *
433      */

434     private void processParentFrameEvent(SParentFrameListener listener, SParentFrameEvent event) {
435         int id = event.getID();
436         switch (id) {
437             case SParentFrameEvent.PARENTFRAME_ADDED:
438                 listener.parentFrameAdded(event);
439                 break;
440             case SParentFrameEvent.PARENTFRAME_REMOVED:
441                 listener.parentFrameRemoved(event);
442                 break;
443         }
444     }
445
446     /**
447      * Processes component events occurring on this component by
448      * dispatching them to any registered
449      * <code>SComponentListener</code> objects.
450      * <p/>
451      * This method is not called unless component events are
452      * enabled for this component. Component events are enabled
453      * when one of the following occurs:
454      * <p><ul>
455      * <li>A <code>SComponentListener</code> object is registered
456      * via <code>addComponentListener</code>.
457      * </ul>
458      *
459      * @param e the component event.
460      * @see org.wings.event.SComponentEvent
461      * @see org.wings.event.SComponentListener
462      * @see org.wings.SComponent#addComponentListener
463      */

464     protected void processComponentEvent(SComponentListener listener, SComponentEvent e) {
465         int id = e.getID();
466         switch (id) {
467             case SComponentEvent.COMPONENT_RESIZED:
468                 listener.componentResized(e);
469                 break;
470             case SComponentEvent.COMPONENT_MOVED:
471                 listener.componentMoved(e);
472                 break;
473             case SComponentEvent.COMPONENT_SHOWN:
474                 listener.componentShown(e);
475                 break;
476             case SComponentEvent.COMPONENT_HIDDEN:
477                 listener.componentHidden(e);
478                 break;
479         }
480     }
481
482     /**
483      * Adds the specified component listener to receive component events from
484      * this component.
485      * If l is null, no exception is thrown and no action is performed.
486      * If there is already a ScriptListener which is equal, the new one is not
487      * added.
488      *
489      * @param listener the component listener.
490      * @see org.wings.event.SComponentEvent
491      * @see org.wings.event.SComponentListener
492      * @see org.wings.SComponent#removeComponentListener
493      */

494     public final void addScriptListener(ScriptListener listener) {
495         ScriptListener[] listeners = getScriptListeners();
496         for (int i = 0; i < listeners.length; i++) {
497             if (listeners[i].equals(listener)) {
498                 return;
499             }
500         }
501         addEventListener(ScriptListener.class, listener);
502     }
503
504
505     /**
506      * Removes the specified component listener so that it no longer
507      * receives component events from this component. This method performs
508      * no function, nor does it throw an exception, if the listener
509      * specified by the argument was not previously added to this component.
510      * If l is null, no exception is thrown and no action is performed.
511      *
512      * @param listener the component listener.
513      * @see org.wings.event.SComponentEvent
514      * @see org.wings.event.SComponentListener
515      * @see org.wings.SComponent#addComponentListener
516      */

517     public final void removeScriptListener(ScriptListener listener) {
518         removeEventListener(ScriptListener.class, listener);
519     }
520
521     public ScriptListener[] getScriptListeners() {
522         return (ScriptListener[]) getListeners(ScriptListener.class);
523     }
524
525     public void setName(String JavaDoc name) {
526         if (name != null) {
527             if (!Character.isJavaIdentifierStart(name.charAt(0)) || name.charAt(0) == '_')
528                 throw new IllegalArgumentException JavaDoc(name + " is not a valid identifier");
529             for (int i=1; i < name.length(); i++)
530                 if (!Character.isJavaIdentifierPart(name.charAt(i)) || name.charAt(0) == '_')
531                     throw new IllegalArgumentException JavaDoc(name + " is not a valid identifier");
532         }
533         reloadIfChange(this.name, name);
534         this.name = name;
535     }
536
537     public final String JavaDoc getName() {
538         if (name == null)
539             name = getSession().createUniqueId();
540         return name;
541     }
542
543     /**
544      * Return the session this component belongs to.
545      *
546      * @return the session
547      */

548     public final Session getSession() {
549         if (session == null) {
550             session = SessionManager.getSession();
551         }
552
553         return session;
554     }
555
556     /**
557      * Return the dispatcher.
558      *
559      * @return the dispatcher
560      */

561     public final LowLevelEventDispatcher getDispatcher() {
562         return getSession().getDispatcher();
563     }
564
565     /*
566      * If a subclass implements the {@link LowLevelEventListener} interface,
567      * it will be unregistered at the associated dispatcher.
568      */

569     private final void unregister() {
570         if (getDispatcher() != null && this instanceof LowLevelEventListener) {
571             getDispatcher().unregister((LowLevelEventListener) this);
572         }
573     }
574
575     /*
576      * If a subclass implements the {@link LowLevelEventListener} interface,
577      * it will be registered at the associated dispatcher.
578      */

579     private final void register() {
580         if (getDispatcher() != null && this instanceof LowLevelEventListener) {
581             getDispatcher().register((LowLevelEventListener) this);
582         }
583     }
584
585     /**
586      * Set the class of the laf-provided style.
587      *
588      * @param value the new value for style
589      */

590     public void setStyle(String JavaDoc value) {
591         reloadIfChange(style, value);
592         this.style = value;
593     }
594
595     /**
596      * @return the current style
597      */

598     public String JavaDoc getStyle() {
599         return style;
600     }
601
602     public void addDynamicStyle(Style style) {
603         if (dynamicStyles == null)
604             dynamicStyles = new HashMap JavaDoc(4);
605         dynamicStyles.put(style.getSelector(), style);
606         reload();
607     }
608
609     public void removeDynamicStyle(String JavaDoc selector) {
610         if (dynamicStyles == null)
611             return;
612         dynamicStyles.remove(selector);
613         reload();
614     }
615
616     public Style getDynamicStyle(Object JavaDoc selector) {
617         if (dynamicStyles == null)
618             return null;
619         return (Style) dynamicStyles.get(selector);
620     }
621
622     public void setDynamicStyles(Collection JavaDoc dynamicStyles) {
623         if (dynamicStyles == null)
624             return;
625         if (this.dynamicStyles == null)
626             this.dynamicStyles = new HashMap JavaDoc(4);
627         for (Iterator JavaDoc iterator = dynamicStyles.iterator(); iterator.hasNext();) {
628             Style style = (Style) iterator.next();
629             this.dynamicStyles.put(style.getSelector(), style);
630         }
631         reload();
632     }
633
634     public Collection JavaDoc getDynamicStyles() {
635         if (dynamicStyles == null || dynamicStyles.size() == 0)
636             return null;
637         return Collections.unmodifiableCollection(dynamicStyles.values());
638     }
639
640     /** @deprecated Use {@link #setAttribute(org.wings.style.CSSProperty, String)} */
641     public void setAttribute(String JavaDoc cssPropertyName, String JavaDoc value) {
642         setAttribute(thisComponentCssSelector, new CSSProperty(cssPropertyName), value);
643     }
644
645     public void setAttribute(CSSProperty property, String JavaDoc propertyValue) {
646          setAttribute(thisComponentCssSelector, property, propertyValue);
647     }
648
649     public void setAttribute(CSSSelector selector, CSSProperty property, SIcon icon) {
650         setAttribute(selector, property, icon != null ? "url('"+icon.getURL().toString()+"')" : "none");
651     }
652
653     public void setAttribute(CSSSelector selector, CSSProperty property, String JavaDoc propertyValue) {
654         CSSStyle style = (CSSStyle) getDynamicStyle(selector);
655         if (style == null) {
656             addDynamicStyle(new CSSStyle(selector, property, propertyValue));
657             reload();
658         } else {
659             String JavaDoc old = style.put(property, propertyValue);
660             reloadIfChange(old, propertyValue);
661         }
662     }
663
664     public void setAttributes(CSSAttributeSet attributes) {
665         log.debug("attributes = " + attributes);
666         setAttributes(thisComponentCssSelector, attributes);
667     }
668
669     public void setAttributes(CSSSelector selector, CSSAttributeSet attributes) {
670         CSSStyle style = (CSSStyle) getDynamicStyle(selector);
671         if (style == null) {
672             addDynamicStyle(new CSSStyle(selector, attributes));
673             reload();
674         } else {
675             boolean changed = style.putAll(attributes);
676             if (changed)
677                 reload();
678         }
679     }
680
681     /**
682      * Return the background color.
683      *
684      * @return the background color
685      */

686     public Color getBackground() {
687         return dynamicStyles == null || dynamicStyles.get(thisComponentCssSelector) == null ? null : CSSStyleSheet.getBackground((CSSAttributeSet) dynamicStyles.get(thisComponentCssSelector));
688     }
689
690     /**
691      * Set the foreground color.
692      *
693      * @param color the new foreground color
694      */

695     public void setBackground(Color color) {
696         setAttribute(thisComponentCssSelector, CSSProperty.BACKGROUND_COLOR, CSSStyleSheet.getAttribute(color));
697     }
698
699     /**
700      * Return the foreground color.
701      *
702      * @return the foreground color
703      */

704     public Color getForeground() {
705         return dynamicStyles == null || dynamicStyles.get(thisComponentCssSelector) == null ? null : CSSStyleSheet.getForeground((CSSAttributeSet) dynamicStyles.get(thisComponentCssSelector));
706     }
707
708     /**
709      * Set the foreground color.
710      *
711      * @param color the new foreground color
712      */

713     public void setForeground(Color color) {
714         setAttribute(thisComponentCssSelector, CSSProperty.COLOR, CSSStyleSheet.getAttribute(color));
715     }
716
717     /**
718      * Set the font.
719      *
720      * @param font the new font
721      */

722     public void setFont(SFont font) {
723         setAttributes(thisComponentCssSelector, CSSStyleSheet.getAttributes(font));
724     }
725
726     /**
727      * Return the font.
728      *
729      * @return the font
730      */

731     public SFont getFont() {
732         return dynamicStyles == null || dynamicStyles.get(thisComponentCssSelector) == null ? null : CSSStyleSheet.getFont((CSSAttributeSet) dynamicStyles.get(thisComponentCssSelector));
733     }
734
735     /**
736      * Set the visibility.
737      *
738      * @param visible wether this component will show or not
739      */

740     public void setVisible(boolean visible) {
741         boolean old = this.visible;
742         this.visible = visible;
743         if (fireComponentChangeEvents && (visible != old)) {
744             fireComponentChangeEvent(new SComponentEvent(this, visible
745                     ? SComponentEvent.COMPONENT_SHOWN
746                     : SComponentEvent.COMPONENT_HIDDEN));
747         }
748     }
749
750     /**
751      * Return the visibility.
752      *
753      * @return wether the component will show
754      */

755     public boolean isVisible() {
756         return visible;
757     }
758
759     /**
760      * Set wether this component should be enabled.
761      *
762      * @param enabled true if the component is enabled, false otherwise
763      */

764     public void setEnabled(boolean enabled) {
765         this.enabled = enabled;
766     }
767
768     /**
769      * Return true if this component is enabled.
770      *
771      * @return true if component is enabled
772      */

773     public boolean isEnabled() {
774         return enabled;
775     }
776
777     /**
778      * Mark the component as subject to reload.
779      * The component will be registered with the ReloadManager.
780      */

781     public final void reload() {
782         getSession().getReloadManager().reload(this);
783     }
784
785     /**
786      * Mark this component as subject to reload for the given
787      * aspect if the property, that is given in its old and new
788      * fashion, changed. Convenience method for {@link #reload()}
789      *
790      * @param oldVal the old value of some property
791      * @param newVal the new value of some property
792      */

793     protected final void reloadIfChange(Object JavaDoc oldVal, Object JavaDoc newVal) {
794         if (!((oldVal == newVal) || (oldVal != null && oldVal.equals(newVal)))) {
795             //System.err.println(getClass().getDescription() + ": reload. old:" + oldVal + "; new: "+ newVal);
796
reload();
797         }
798     }
799
800     /**
801      * Mark this component as subject to reload for the given
802      * aspect if the property, that is given in its old and new
803      * fashion, changed. Convenience method for {@link #reload()}
804      *
805      * @param oldVal the old value of some property
806      * @param newVal the new value of some property
807      */

808     protected final void reloadIfChange(int oldVal, int newVal) {
809         if (oldVal != newVal) {
810             reload();
811         }
812     }
813
814     /**
815      * Mark this component as subject to reload for the given
816      * aspect if the property, that is given in its old and new
817      * fashion, changed. Convenience method for {@link #reload()}
818      *
819      * @param oldVal the old value of some property
820      * @param newVal the new value of some property
821      */

822     protected final void reloadIfChange(boolean oldVal, boolean newVal) {
823         if (oldVal != newVal) {
824             reload();
825         }
826     }
827
828     /**
829      * Mark this component as subject to reload for the given
830      * aspect if the property, that is given in its old and new
831      * fashion, changed. Convenience method for {@link #reload()}
832      *
833      * @param oldVal the old value of some property
834      * @param newVal the new value of some property
835      */

836     protected final void reloadIfChange(byte oldVal, byte newVal) {
837         if (oldVal != newVal) {
838             reload();
839         }
840     }
841
842     /**
843      * Mark this component as subject to reload for the given
844      * aspect if the property, that is given in its old and new
845      * fashion, changed. Convenience method for {@link #reload()}
846      *
847      * @param oldVal the old value of some property
848      * @param newVal the new value of some property
849      */

850     protected final void reloadIfChange(short oldVal, short newVal) {
851         if (oldVal != newVal) {
852             reload();
853         }
854     }
855
856     /**
857      * Mark this component as subject to reload for the given
858      * aspect if the property, that is given in its old and new
859      * fashion, changed. Convenience method for {@link #reload()}
860      *
861      * @param oldVal the old value of some property
862      * @param newVal the new value of some property
863      */

864     protected final void reloadIfChange(long oldVal, long newVal) {
865         if (oldVal != newVal) {
866             reload();
867         }
868     }
869
870     /**
871      * Mark this component as subject to reload for the given
872      * aspect if the property, that is given in its old and new
873      * fashion, changed. Convenience method for {@link #reload()}
874      *
875      * @param oldVal the old value of some property
876      * @param newVal the new value of some property
877      */

878     protected final void reloadIfChange(float oldVal, float newVal) {
879         if (oldVal != newVal) {
880             reload();
881         }
882     }
883
884     /**
885      * Mark this component as subject to reload for the given
886      * aspect if the property, that is given in its old and new
887      * fashion, changed. Convenience method for {@link #reload()}
888      *
889      * @param oldVal the old value of some property
890      * @param newVal the new value of some property
891      */

892     protected final void reloadIfChange(double oldVal, double newVal) {
893         if (oldVal != newVal) {
894             reload();
895         }
896     }
897
898     /**
899      * Mark this component as subject to reload for the given
900      * aspect if the property, that is given in its old and new
901      * fashion, changed. Convenience method for {@link #reload()}
902      *
903      * @param oldVal the old value of some property
904      * @param newVal the new value of some property
905      */

906     protected final void reloadIfChange(char oldVal, char newVal) {
907         if (oldVal != newVal) {
908             reload();
909         }
910     }
911
912     /**
913      * Let the code generator deletate write the component's code
914      * to the device. The code generator is the actual 'plaf'.
915      *
916      * @param s the Device to write into
917      * @throws IOException Thrown if the connection to the client gets broken,
918      * for example when the user stops loading
919      */

920     public void write(Device s) throws IOException JavaDoc {
921         try {
922             if (visible)
923                 cg.write(s, this);
924         } catch (IOException JavaDoc se) {
925             // Typical double-clicks. Not severe
926
log.debug( "Socket exception during code generation for " + getClass().getName() + se);
927         } catch (Throwable JavaDoc t) {
928             log.warn( "Exception during code generation for " + getClass().getName(), t);
929         }
930     }
931
932     /**
933      * a string representation of this component. Just
934      * renders the component into a string.
935      */

936     public String JavaDoc toString() {
937         return paramString();
938     }
939
940
941     /**
942      * Generic implementation for generating a string that represents
943      * the components configuration.
944      *
945      * @return a string containing all properties
946      */

947     public String JavaDoc paramString() {
948         StringBuffer JavaDoc buffer = new StringBuffer