001: /*
002: * Copyright (c) 2002-2007 JGoodies Karsten Lentzsch. All Rights Reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * o Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * o Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * o Neither the name of JGoodies Karsten Lentzsch nor the names of
015: * its contributors may be used to endorse or promote products derived
016: * from this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030:
031: package com.jgoodies.binding.beans;
032:
033: import java.beans.*;
034: import java.io.Serializable;
035:
036: import com.jgoodies.binding.BindingUtils;
037:
038: /**
039: * An abstract superclass that minimizes the effort required to provide
040: * change support for bound and constrained Bean properties.
041: * This class follows the conventions and recommendations as described
042: * in the <a href="http://java.sun.com/products/javabeans/docs/spec.html"
043: * >Java Bean Specification</a>.<p>
044: *
045: * Uses class {@link com.jgoodies.binding.beans.ExtendedPropertyChangeSupport},
046: * to enable the <code>==</code> or <code>#equals</code> test when
047: * changing values.<p>
048: *
049: * TODO: Consider adding a method <code>#fireChange</code> that invokes
050: * <code>#firePropertyChange</code> if and only if
051: * <code>new value != old value</code>. The background is, that
052: * <code>#firePropertyChange</code> must fire an event
053: * if <code>new value==null==old value</code>.
054: *
055: * @author Karsten Lentzsch
056: * @version $Revision: 1.14 $
057: *
058: * @see Observable
059: * @see java.beans.PropertyChangeEvent
060: * @see PropertyChangeListener
061: * @see PropertyChangeSupport
062: * @see ExtendedPropertyChangeSupport
063: * @see VetoableChangeListener
064: * @see VetoableChangeSupport
065: */
066: public abstract class Model implements Observable, Serializable {
067:
068: /**
069: * If any <code>PropertyChangeListeners</code> have been registered,
070: * the <code>changeSupport</code> field describes them.
071: *
072: * @see #addPropertyChangeListener(PropertyChangeListener)
073: * @see #addPropertyChangeListener(String, PropertyChangeListener)
074: * @see #removePropertyChangeListener(PropertyChangeListener)
075: * @see #removePropertyChangeListener(String, PropertyChangeListener)
076: * @see PropertyChangeSupport
077: */
078: private ExtendedPropertyChangeSupport changeSupport;
079:
080: /**
081: * If any <code>VetoableChangeListeners</code> have been registered,
082: * the <code>vetoSupport</code> field describes them.
083: *
084: * @see #addVetoableChangeListener(VetoableChangeListener)
085: * @see #addVetoableChangeListener(String, VetoableChangeListener)
086: * @see #removeVetoableChangeListener(VetoableChangeListener)
087: * @see #removeVetoableChangeListener(String, VetoableChangeListener)
088: * @see #fireVetoableChange(String, Object, Object)
089: */
090: private VetoableChangeSupport vetoSupport;
091:
092: // Managing Property Change Listeners **********************************
093:
094: /**
095: * Adds a PropertyChangeListener to the listener list. The listener is
096: * registered for all bound properties of this class.<p>
097: *
098: * If listener is <code>null</code>, no exception is thrown and no action is performed.
099: *
100: * @param listener the PropertyChangeListener to be added
101: *
102: * @see #removePropertyChangeListener(PropertyChangeListener)
103: * @see #removePropertyChangeListener(String, PropertyChangeListener)
104: * @see #addPropertyChangeListener(String, PropertyChangeListener)
105: * @see #getPropertyChangeListeners()
106: */
107: public final synchronized void addPropertyChangeListener(
108: PropertyChangeListener listener) {
109: if (listener == null) {
110: return;
111: }
112: if (changeSupport == null) {
113: changeSupport = new ExtendedPropertyChangeSupport(this );
114: }
115: changeSupport.addPropertyChangeListener(listener);
116: }
117:
118: /**
119: * Removes a PropertyChangeListener from the listener list. This method
120: * should be used to remove PropertyChangeListeners that were registered
121: * for all bound properties of this class.<p>
122: *
123: * If listener is <code>null</code>, no exception is thrown and no action is performed.
124: *
125: * @param listener the PropertyChangeListener to be removed
126: * @see #addPropertyChangeListener(PropertyChangeListener)
127: * @see #addPropertyChangeListener(String, PropertyChangeListener)
128: * @see #removePropertyChangeListener(String, PropertyChangeListener)
129: * @see #getPropertyChangeListeners()
130: */
131: public final synchronized void removePropertyChangeListener(
132: PropertyChangeListener listener) {
133: if (listener == null || changeSupport == null) {
134: return;
135: }
136: changeSupport.removePropertyChangeListener(listener);
137: }
138:
139: /**
140: * Adds a PropertyChangeListener to the listener list for a specific
141: * property. The specified property may be user-defined.<p>
142: *
143: * Note that if this Model is inheriting a bound property, then no event
144: * will be fired in response to a change in the inherited property.<p>
145: *
146: * If listener is <code>null</code>, no exception is thrown and no action is performed.
147: *
148: * @param propertyName one of the property names listed above
149: * @param listener the PropertyChangeListener to be added
150: *
151: * @see #removePropertyChangeListener(String, PropertyChangeListener)
152: * @see #addPropertyChangeListener(String, PropertyChangeListener)
153: * @see #getPropertyChangeListeners(String)
154: */
155: public final synchronized void addPropertyChangeListener(
156: String propertyName, PropertyChangeListener listener) {
157: if (listener == null) {
158: return;
159: }
160: if (changeSupport == null) {
161: changeSupport = new ExtendedPropertyChangeSupport(this );
162: }
163: changeSupport.addPropertyChangeListener(propertyName, listener);
164: }
165:
166: /**
167: * Removes a PropertyChangeListener from the listener list for a specific
168: * property. This method should be used to remove PropertyChangeListeners
169: * that were registered for a specific bound property.<p>
170: *
171: * If listener is <code>null</code>, no exception is thrown and no action is performed.
172: *
173: * @param propertyName a valid property name
174: * @param listener the PropertyChangeListener to be removed
175: *
176: * @see #addPropertyChangeListener(String, PropertyChangeListener)
177: * @see #removePropertyChangeListener(PropertyChangeListener)
178: * @see #getPropertyChangeListeners(String)
179: */
180: public final synchronized void removePropertyChangeListener(
181: String propertyName, PropertyChangeListener listener) {
182: if (listener == null || changeSupport == null) {
183: return;
184: }
185: changeSupport.removePropertyChangeListener(propertyName,
186: listener);
187: }
188:
189: // Managing Vetoable Change Listeners ***********************************
190:
191: /**
192: * Adds a VetoableChangeListener to the listener list. The listener is
193: * registered for all bound properties of this class.<p>
194: *
195: * If listener is <code>null</code>, no exception is thrown and no action is
196: * performed.
197: *
198: * @param listener the VetoableChangeListener to be added
199: *
200: * @see #removeVetoableChangeListener(String, VetoableChangeListener)
201: * @see #addVetoableChangeListener(String, VetoableChangeListener)
202: * @see #getVetoableChangeListeners()
203: */
204: public final synchronized void addVetoableChangeListener(
205: VetoableChangeListener listener) {
206: if (listener == null) {
207: return;
208: }
209: if (vetoSupport == null) {
210: vetoSupport = new VetoableChangeSupport(this );
211: }
212: vetoSupport.addVetoableChangeListener(listener);
213: }
214:
215: /**
216: * Removes a VetoableChangeListener from the listener list. This method
217: * should be used to remove VetoableChangeListeners that were registered
218: * for all bound properties of this class.<p>
219: *
220: * If listener is <code>null</code>, no exception is thrown and no action is performed.
221: *
222: * @param listener the VetoableChangeListener to be removed
223: *
224: * @see #addVetoableChangeListener(String, VetoableChangeListener)
225: * @see #removeVetoableChangeListener(String, VetoableChangeListener)
226: * @see #getVetoableChangeListeners()
227: */
228: public final synchronized void removeVetoableChangeListener(
229: VetoableChangeListener listener) {
230: if (listener == null || vetoSupport == null) {
231: return;
232: }
233: vetoSupport.removeVetoableChangeListener(listener);
234: }
235:
236: /**
237: * Adds a VetoableChangeListener to the listener list for a specific
238: * property. The specified property may be user-defined.<p>
239: *
240: * Note that if this Model is inheriting a bound property, then no event
241: * will be fired in response to a change in the inherited property.<p>
242: *
243: * If listener is <code>null</code>, no exception is thrown and no action is performed.
244: *
245: * @param propertyName one of the property names listed above
246: * @param listener the VetoableChangeListener to be added
247: *
248: * @see #removeVetoableChangeListener(String, VetoableChangeListener)
249: * @see #addVetoableChangeListener(String, VetoableChangeListener)
250: * @see #getVetoableChangeListeners(String)
251: */
252: public final synchronized void addVetoableChangeListener(
253: String propertyName, VetoableChangeListener listener) {
254: if (listener == null) {
255: return;
256: }
257: if (vetoSupport == null) {
258: vetoSupport = new VetoableChangeSupport(this );
259: }
260: vetoSupport.addVetoableChangeListener(propertyName, listener);
261: }
262:
263: /**
264: * Removes a VetoableChangeListener from the listener list for a specific
265: * property. This method should be used to remove VetoableChangeListeners
266: * that were registered for a specific bound property.<p>
267: *
268: * If listener is <code>null</code>, no exception is thrown and no action is performed.
269: *
270: * @param propertyName a valid property name
271: * @param listener the VetoableChangeListener to be removed
272: *
273: * @see #addVetoableChangeListener(String, VetoableChangeListener)
274: * @see #removeVetoableChangeListener(VetoableChangeListener)
275: * @see #getVetoableChangeListeners(String)
276: */
277: public final synchronized void removeVetoableChangeListener(
278: String propertyName, VetoableChangeListener listener) {
279: if (listener == null || vetoSupport == null) {
280: return;
281: }
282: vetoSupport
283: .removeVetoableChangeListener(propertyName, listener);
284: }
285:
286: // Requesting Listener Sets ***********************************************
287:
288: /**
289: * Returns an array of all the property change listeners
290: * registered on this component.
291: *
292: * @return all of this component's <code>PropertyChangeListener</code>s
293: * or an empty array if no property change
294: * listeners are currently registered
295: *
296: * @see #addPropertyChangeListener(PropertyChangeListener)
297: * @see #removePropertyChangeListener(PropertyChangeListener)
298: * @see #getPropertyChangeListeners(String)
299: * @see PropertyChangeSupport#getPropertyChangeListeners()
300: */
301: public final synchronized PropertyChangeListener[] getPropertyChangeListeners() {
302: if (changeSupport == null) {
303: return new PropertyChangeListener[0];
304: }
305: return changeSupport.getPropertyChangeListeners();
306: }
307:
308: /**
309: * Returns an array of all the listeners which have been associated
310: * with the named property.
311: *
312: * @param propertyName the name of the property to lookup listeners
313: * @return all of the <code>PropertyChangeListeners</code> associated with
314: * the named property or an empty array if no listeners have
315: * been added
316: *
317: * @see #addPropertyChangeListener(String, PropertyChangeListener)
318: * @see #removePropertyChangeListener(String, PropertyChangeListener)
319: * @see #getPropertyChangeListeners()
320: */
321: public final synchronized PropertyChangeListener[] getPropertyChangeListeners(
322: String propertyName) {
323: if (changeSupport == null) {
324: return new PropertyChangeListener[0];
325: }
326: return changeSupport.getPropertyChangeListeners(propertyName);
327: }
328:
329: /**
330: * Returns an array of all the property change listeners
331: * registered on this component.
332: *
333: * @return all of this component's <code>VetoableChangeListener</code>s
334: * or an empty array if no property change
335: * listeners are currently registered
336: *
337: * @see #addVetoableChangeListener(VetoableChangeListener)
338: * @see #removeVetoableChangeListener(VetoableChangeListener)
339: * @see #getVetoableChangeListeners(String)
340: * @see VetoableChangeSupport#getVetoableChangeListeners()
341: */
342: public final synchronized VetoableChangeListener[] getVetoableChangeListeners() {
343: if (vetoSupport == null) {
344: return new VetoableChangeListener[0];
345: }
346: return vetoSupport.getVetoableChangeListeners();
347: }
348:
349: /**
350: * Returns an array of all the listeners which have been associated
351: * with the named property.
352: *
353: * @param propertyName the name of the property to lookup listeners
354: * @return all of the <code>VetoableChangeListeners</code> associated with
355: * the named property or an empty array if no listeners have
356: * been added
357: *
358: * @see #addVetoableChangeListener(String, VetoableChangeListener)
359: * @see #removeVetoableChangeListener(String, VetoableChangeListener)
360: * @see #getVetoableChangeListeners()
361: */
362: public final synchronized VetoableChangeListener[] getVetoableChangeListeners(
363: String propertyName) {
364: if (vetoSupport == null) {
365: return new VetoableChangeListener[0];
366: }
367: return vetoSupport.getVetoableChangeListeners(propertyName);
368: }
369:
370: // Firing Changes for Bound Properties **********************************
371:
372: /**
373: * General support for reporting bound property changes. Sends the given
374: * PropertyChangeEvent to any registered PropertyChangeListener.<p>
375: *
376: * Most bean setters will invoke the fireXXX methods that get
377: * a property name and the old and new value. However some frameworks
378: * and setters may prefer to use this general method.
379: * Also, this method allows to fire IndexedPropertyChangeEvents
380: * that have been introduced in Java 5.
381: *
382: * @param event describes the property change
383: *
384: * @since 1.3
385: */
386: protected final void firePropertyChange(PropertyChangeEvent event) {
387: PropertyChangeSupport aChangeSupport = this .changeSupport;
388: if (aChangeSupport == null) {
389: return;
390: }
391: aChangeSupport.firePropertyChange(event);
392: }
393:
394: /**
395: * Support for reporting bound property changes for Object properties.
396: * This method can be called when a bound property has changed and it will
397: * send the appropriate PropertyChangeEvent to any registered
398: * PropertyChangeListeners.
399: *
400: * @param propertyName the property whose value has changed
401: * @param oldValue the property's previous value
402: * @param newValue the property's new value
403: */
404: protected final void firePropertyChange(String propertyName,
405: Object oldValue, Object newValue) {
406: PropertyChangeSupport aChangeSupport = this .changeSupport;
407: if (aChangeSupport == null) {
408: return;
409: }
410: aChangeSupport.firePropertyChange(propertyName, oldValue,
411: newValue);
412: }
413:
414: /**
415: * Support for reporting bound property changes for Object properties.
416: * This method can be called when a bound property has changed and it will
417: * send the appropriate PropertyChangeEvent to any registered
418: * PropertyChangeListeners.<p>
419: *
420: * The boolean parameter specifies whether differences between the old
421: * and new value are tested using <code>==</code> or <code>#equals</code>.
422: *
423: * @param propertyName the property whose value has changed
424: * @param oldValue the property's previous value
425: * @param newValue the property's new value
426: * @param checkIdentity true to check differences using <code>==</code>
427: * false to use <code>#equals</code>.
428: */
429: protected final void firePropertyChange(String propertyName,
430: Object oldValue, Object newValue, boolean checkIdentity) {
431:
432: if (changeSupport == null) {
433: return;
434: }
435: changeSupport.firePropertyChange(propertyName, oldValue,
436: newValue, checkIdentity);
437: }
438:
439: /**
440: * Support for reporting bound property changes for boolean properties.
441: * This method can be called when a bound property has changed and it will
442: * send the appropriate PropertyChangeEvent to any registered
443: * PropertyChangeListeners.
444: *
445: * @param propertyName the property whose value has changed
446: * @param oldValue the property's previous value
447: * @param newValue the property's new value
448: */
449: protected final void firePropertyChange(String propertyName,
450: boolean oldValue, boolean newValue) {
451: PropertyChangeSupport aChangeSupport = this .changeSupport;
452: if (aChangeSupport == null) {
453: return;
454: }
455: aChangeSupport.firePropertyChange(propertyName, oldValue,
456: newValue);
457: }
458:
459: /**
460: * Support for reporting bound property changes for integer properties.
461: * This method can be called when a bound property has changed and it will
462: * send the appropriate PropertyChangeEvent to any registered
463: * PropertyChangeListeners.
464: *
465: * @param propertyName the property whose value has changed
466: * @param oldValue the property's previous value
467: * @param newValue the property's new value
468: */
469: protected final void firePropertyChange(String propertyName,
470: double oldValue, double newValue) {
471: firePropertyChange(propertyName, Double.valueOf(oldValue),
472: Double.valueOf(newValue));
473: }
474:
475: /**
476: * Support for reporting bound property changes for integer properties.
477: * This method can be called when a bound property has changed and it will
478: * send the appropriate PropertyChangeEvent to any registered
479: * PropertyChangeListeners.
480: *
481: * @param propertyName the property whose value has changed
482: * @param oldValue the property's previous value
483: * @param newValue the property's new value
484: */
485: protected final void firePropertyChange(String propertyName,
486: float oldValue, float newValue) {
487: firePropertyChange(propertyName, Float.valueOf(oldValue), Float
488: .valueOf(newValue));
489: }
490:
491: /**
492: * Support for reporting bound property changes for integer properties.
493: * This method can be called when a bound property has changed and it will
494: * send the appropriate PropertyChangeEvent to any registered
495: * PropertyChangeListeners.
496: *
497: * @param propertyName the property whose value has changed
498: * @param oldValue the property's previous value
499: * @param newValue the property's new value
500: */
501: protected final void firePropertyChange(String propertyName,
502: int oldValue, int newValue) {
503: PropertyChangeSupport aChangeSupport = this .changeSupport;
504: if (aChangeSupport == null) {
505: return;
506: }
507: aChangeSupport.firePropertyChange(propertyName, Integer
508: .valueOf(oldValue), Integer.valueOf(newValue));
509: }
510:
511: /**
512: * Support for reporting bound property changes for integer properties.
513: * This method can be called when a bound property has changed and it will
514: * send the appropriate PropertyChangeEvent to any registered
515: * PropertyChangeListeners.
516: *
517: * @param propertyName the property whose value has changed
518: * @param oldValue the property's previous value
519: * @param newValue the property's new value
520: */
521: protected final void firePropertyChange(String propertyName,
522: long oldValue, long newValue) {
523: firePropertyChange(propertyName, Long.valueOf(oldValue), Long
524: .valueOf(newValue));
525: }
526:
527: /**
528: * Indicates that an arbitrary set of bound properties have changed.
529: * Sends a PropertyChangeEvent with property name, old and new value
530: * set <code>null</code> to any registered PropertyChangeListeners.
531: *
532: * @see java.beans.PropertyChangeEvent
533: *
534: * @since 1.0.3
535: */
536: protected final void fireMultiplePropertiesChanged() {
537: firePropertyChange(null, null, null);
538: }
539:
540: // Firing Indexed Changes *************************************************
541:
542: /**
543: * Report a bound indexed property update to any registered listeners.<p>
544: *
545: * No event is fired if old and new values are equal and non-null.
546: *
547: * @param propertyName The programmatic name of the property that
548: * was changed.
549: * @param index index of the property element that was changed.
550: * @param oldValue The old value of the property.
551: * @param newValue The new value of the property.
552: *
553: * @since 2.0
554: */
555: protected final void fireIndexedPropertyChange(String propertyName,
556: int index, Object oldValue, Object newValue) {
557: PropertyChangeSupport aChangeSupport = this .changeSupport;
558: if (aChangeSupport == null) {
559: return;
560: }
561: aChangeSupport.fireIndexedPropertyChange(propertyName, index,
562: oldValue, newValue);
563: }
564:
565: /**
566: * Report an <code>int</code> bound indexed property update
567: * to any registered listeners.<p>
568: *
569: * No event is fired if old and new values are equal and non-null.<p>
570: *
571: * This is merely a convenience wrapper around the more general
572: * fireIndexedPropertyChange method which takes Object values.
573: *
574: * @param propertyName The programmatic name of the property that
575: * was changed.
576: * @param index index of the property element that was changed.
577: * @param oldValue The old value of the property.
578: * @param newValue The new value of the property.
579: *
580: * @since 2.0
581: */
582: protected final void fireIndexedPropertyChange(String propertyName,
583: int index, int oldValue, int newValue) {
584: if (oldValue == newValue) {
585: return;
586: }
587: fireIndexedPropertyChange(propertyName, index, Integer
588: .valueOf(oldValue), Integer.valueOf(newValue));
589: }
590:
591: /**
592: * Report a <code>boolean</code> bound indexed property update
593: * to any registered listeners.<p>
594: *
595: * No event is fired if old and new values are equal and non-null.<p>
596: *
597: * This is merely a convenience wrapper around the more general
598: * fireIndexedPropertyChange method which takes Object values.
599: *
600: * @param propertyName The programmatic name of the property that
601: * was changed.
602: * @param index index of the property element that was changed.
603: * @param oldValue The old value of the property.
604: * @param newValue The new value of the property.
605: *
606: * @since 2.0
607: */
608: protected final void fireIndexedPropertyChange(String propertyName,
609: int index, boolean oldValue, boolean newValue) {
610: if (oldValue == newValue) {
611: return;
612: }
613: fireIndexedPropertyChange(propertyName, index, Boolean
614: .valueOf(oldValue), Boolean.valueOf(newValue));
615: }
616:
617: // Firing Changes for Constrained Properties ****************************
618:
619: /**
620: * General support for reporting constrained property changes. Sends the
621: * given PropertyChangeEvent to any registered PropertyChangeListener.<p>
622: *
623: * Most bean setters will invoke the fireXXX methods that get
624: * a property name and the old and new value. However some frameworks
625: * and setters may prefer to use this general method.
626: * Also, this method allows to fire IndexedPropertyChangeEvents
627: * that have been introduced in Java 5.
628: *
629: * @param event describes the property change
630: * @throws PropertyVetoException if a constrained property change is rejected
631: *
632: * @since 1.3
633: */
634: protected final void fireVetoableChange(PropertyChangeEvent event)
635: throws PropertyVetoException {
636: VetoableChangeSupport aVetoSupport = this .vetoSupport;
637: if (aVetoSupport == null) {
638: return;
639: }
640: aVetoSupport.fireVetoableChange(event);
641: }
642:
643: /**
644: * Support for reporting changes for constrained Object properties. This
645: * method can be called before a constrained property will be changed and
646: * it will send the appropriate PropertyChangeEvent to any registered
647: * VetoableChangeListeners.
648: *
649: * @param propertyName the property whose value has changed
650: * @param oldValue the property's previous value
651: * @param newValue the property's new value
652: * @throws PropertyVetoException if a constrained property change is rejected
653: */
654: protected final void fireVetoableChange(String propertyName,
655: Object oldValue, Object newValue)
656: throws PropertyVetoException {
657: VetoableChangeSupport aVetoSupport = this .vetoSupport;
658: if (aVetoSupport == null) {
659: return;
660: }
661: aVetoSupport.fireVetoableChange(propertyName, oldValue,
662: newValue);
663: }
664:
665: /**
666: * Support for reporting changes for constrained boolean properties. This
667: * method can be called before a constrained property will be changed and
668: * it will send the appropriate PropertyChangeEvent to any registered
669: * VetoableChangeListeners.
670: *
671: * @param propertyName the property whose value has changed
672: * @param oldValue the property's previous value
673: * @param newValue the property's new value
674: * @throws PropertyVetoException if a constrained property change is rejected
675: */
676: protected final void fireVetoableChange(String propertyName,
677: boolean oldValue, boolean newValue)
678: throws PropertyVetoException {
679: VetoableChangeSupport aVetoSupport = this .vetoSupport;
680: if (aVetoSupport == null) {
681: return;
682: }
683: aVetoSupport.fireVetoableChange(propertyName, oldValue,
684: newValue);
685: }
686:
687: /**
688: * Support for reporting changes for constrained integer properties. This
689: * method can be called before a constrained property will be changed and
690: * it will send the appropriate PropertyChangeEvent to any registered
691: * VetoableChangeListeners.
692: *
693: * @param propertyName the property whose value has changed
694: * @param oldValue the property's previous value
695: * @param newValue the property's new value
696: * @throws PropertyVetoException if a constrained property change is rejected
697: */
698: protected final void fireVetoableChange(String propertyName,
699: double oldValue, double newValue)
700: throws PropertyVetoException {
701: fireVetoableChange(propertyName, Double.valueOf(oldValue),
702: Double.valueOf(newValue));
703: }
704:
705: /**
706: * Support for reporting changes for constrained integer properties. This
707: * method can be called before a constrained property will be changed and
708: * it will send the appropriate PropertyChangeEvent to any registered
709: * VetoableChangeListeners.
710: *
711: * @param propertyName the property whose value has changed
712: * @param oldValue the property's previous value
713: * @param newValue the property's new value
714: * @throws PropertyVetoException if a constrained property change is rejected
715: */
716: protected final void fireVetoableChange(String propertyName,
717: int oldValue, int newValue) throws PropertyVetoException {
718: VetoableChangeSupport aVetoSupport = this .vetoSupport;
719: if (aVetoSupport == null) {
720: return;
721: }
722: aVetoSupport.fireVetoableChange(propertyName, Integer
723: .valueOf(oldValue), Integer.valueOf(newValue));
724: }
725:
726: /**
727: * Support for reporting changes for constrained integer properties. This
728: * method can be called before a constrained property will be changed and
729: * it will send the appropriate PropertyChangeEvent to any registered
730: * VetoableChangeListeners.
731: *
732: * @param propertyName the property whose value has changed
733: * @param oldValue the property's previous value
734: * @param newValue the property's new value
735: * @throws PropertyVetoException if a constrained property change is rejected
736: */
737: protected final void fireVetoableChange(String propertyName,
738: float oldValue, float newValue)
739: throws PropertyVetoException {
740: fireVetoableChange(propertyName, Float.valueOf(oldValue), Float
741: .valueOf(newValue));
742: }
743:
744: /**
745: * Support for reporting changes for constrained integer properties. This
746: * method can be called before a constrained property will be changed and
747: * it will send the appropriate PropertyChangeEvent to any registered
748: * VetoableChangeListeners.
749: *
750: * @param propertyName the property whose value has changed
751: * @param oldValue the property's previous value
752: * @param newValue the property's new value
753: * @throws PropertyVetoException if a constrained property change is rejected
754: */
755: protected final void fireVetoableChange(String propertyName,
756: long oldValue, long newValue) throws PropertyVetoException {
757: fireVetoableChange(propertyName, Long.valueOf(oldValue), Long
758: .valueOf(newValue));
759: }
760:
761: // Convenience Methods **************************************************
762:
763: /**
764: * Checks and answers if the two objects are both <code>null</code> or equal.
765: *
766: * @param o1 the first object to compare
767: * @param o2 the second object to compare
768: * @return boolean true if and only if both objects are <code>null</code>
769: * or equal
770: */
771: protected final boolean equals(Object o1, Object o2) {
772: return BindingUtils.equals(o1, o2);
773: }
774:
775: }
|