|
|
Start of Tutorial > Start of Trail > Start of Lesson |
Search
Feedback Form |
To get the most out of this section, first read the following:
- Chapter 7 of the JavaBeans API Specification
![]()
VetoableChangeListenerinterface
VetoableChangeSupportclass
PropertyChangeEventclass
PropertyVetoExceptionclass
A Bean property is constrained when any change to that property can be vetoed. Usually an outside object exercises the right to veto, but the Bean itself can also veto a property change.
The JavaBeans API provides an event mechanism, very similar to the bound property mechanism, that allows objects to veto a Bean's property changes.
There are three parts to constrained property implementations:
- A source Bean containing one or more constrained properties.
- Listener objects that implement the
VetoableChangeListenerinterface. This object accepts or rejects proposed changes to a constrained property in the source Bean.- A
PropertyChangeEventobject containing the property name, and its old and new values. This is the same class used for bound properties.
A Bean containing constrained properties must
- Allow
VetoableChangeListenerobjects to register and unregister their interest in receiving notification that a property change is proposed.- Fire property change events at those interested listeners when a property change is proposed. The event should be fired before the actual property change takes place. This gives each listener a chance to veto the proposed change. The
PropertyChangeEventis fired by a call to each listenersvetoableChangemethod.- If a listener vetoes, then make sure that any other listeners can revert to the old value. This means reissuing the
vetoableChangecall to all the listeners, with aPropertyChangeEventcontaining the old value.The
VetoableChangeSupportutility class is provided to implement these capabilities. This class implements methods to add and removeVetoableChangeListenerobjects to a listener list, and a method that fires property change events at each listener in that list when a property change is proposed. This method will also catch any vetoes, and resend the property change event with the original property value. Your Bean can either inherit fromVetoableChangeSupport, or use an instance of it.Note that, in general, constrained properties should also be bound properties. When a constrained property change does occur, a
PropertyChangeEventcan be sent viaPropertyChangeListener.propertyChangeto signal allVetoableChangeListenerBeans that the change has taken effect. This lets all the vetoable change listeners know that the change was not vetoed by any listener.The
JellyBeandemo Bean has a constrained property. We will its code to illustrate the steps in implementing constrained properties. Here's the steps to implement constrained properties in your Beans:
- Import the
java.beanspackage. This gives you access to theVetoableChangeSupportclass.
- Instantiate a
VetoableChangeSupportobject within your Bean:private VetoableChangeSupport vetos = new VetoableChangeSupport(this);VetoableChangeSupportmanages a list ofVetoableChangeListenerobjects, and fires property change events at each object in the list when a change occurs to a constrained property.
- Implement methods to maintain the property change listener list. These merely wrap calls to the
VetoableChangeSupportobject's methods:public void addVetoableChangeListener( VetoableChangeListener l) { vetos.addVetoableChangeListener(l); } public void removeVetoableChangeListener( VetoableChangeListener l) { vetos.removeVetoableChangeListener(l); }- Write a property's setter method to fire a property change event when the property is changed. This includes adding a
throwsclause to the setter method's signature. JellyBean'ssetPriceInCentsmethod looks like this:public void setPriceInCents(int newPriceInCents) throws PropertyVetoException { int oldPriceInCents = ourPriceInCents; // First tell the vetoers about the change. // If anyone objects, we don't catch the exception // but just let if pass on to our caller. vetos.fireVetoableChange("priceInCents", new Integer(oldPriceInCents), new Integer(newPriceInCents)); // No-one vetoed, so go ahead and make the change. ourPriceInCents = newPriceInCents; changes.firePropertyChange("priceInCents", new Integer(oldPriceInCents), new Integer(newPriceInCents)); }Note that
setPriceInCentsstores the oldprice, because both the old and new prices must be passed tofireVetoableChange. Also note that the primitiveintprices are converted toIntegerobjects.public void fireVetoableChange(String propertyName, Object oldValue, Object newValue) throws PropertyVetoExceptionThese values are then bundled into a
PropertyChangeEventobject sent to each listener. The old and new values are treated asObjectvalues, so if they are primitive types such asint, you must use the object version such asjava.lang.Integer.Now you are ready to implement a Bean that listens for constrained property changes.
To listen for property change events, your listener Bean must implement the
VetoableChangeListenerinterface. This interface contains one method:void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException;So to make your class able to listen and respond to property change events, your listener class must:
- Implement the
VetoableChangeListenerinterface.
- Implement the
vetoableChangemethod. This is the method that will be called by the source Bean on each object in the listener list (maintained by theVetoableChangeSupportobject). This is also the method that exercises veto power. A property change is vetoed by throwing thePropertyVetoException.Note that the
VetoableChangeListenerobject is often an adapter class. The adapter class implements theVetoableChangeListenerinterface and thevetoableChangemethod. This adapter is added to the constrained Bean's listener list, intercepts thevetoableChangecall, and calls the target Bean method that exercises veto power. You'll see an example of this in the next section.
When the BeanBox recognizes the design patterns for constrained properties within your Bean, you will see a
vetoableChangeinterface item when you pull down the Edit|Events menu.As with any event hookup, the BeanBox generates an adapter class when you hook up a Bean with a constrained property to another Bean. To see how this works, take the following steps:
- Drop
VoterandJellyBeaninstances into the BeanBox.- Select the
JellyBeaninstance, and choose the Edit|Events|vetoableChange|vetoableChange menu item.- Connect the rubber band line to the
VoterBean. This brings up theEventTargetDialogpanel.- Choose the
VoterBean'svetoableChangemethod, and push the OK button. This generates an event adapter. You can view this adapter in thebeans/beanbox/tmp/sunw/beanboxdirectory.- Test the constrained property. Select the
JellyBeanand edit itspriceInCentsproperty in the Properties sheet. APropertyVetoExceptionis thrown, and an error dialog pops up.Behind the scenes the BeanBox generated the event hookup adapter. This adapter implements the
VetoableChangeListenerinterface, and also generates avetoableChangemethod implementation that calls theVoter.vetoableChangemethod. Here's the generated adapter source code:// Automatically generated event hookup file. package tmp.sunw.beanbox; import sunw.demo.misc.Voter; import java.beans.VetoableChangeListener; import java.beans.PropertyChangeEvent; public class ___Hookup_1475dd3cb5 implements java.beans.VetoableChangeListener, java.io.Serializable { public void setTarget(sunw.demo.misc.Voter t) { target = t; } public void vetoableChange(java.beans.PropertyChangeEvent arg0) throws java.beans.PropertyVeto Exception { target.vetoableChange(arg0); } private sunw.demo.misc.Voter target; }The
VoterBean need not implement theVetoableChangeListenerinterface; instead, the generated adapter class implementsVetoableChangeListener. The adapter'svetoableChangemethod calls the appropriate method in the target object (Voter).
As with bound property support, JavaBeans has design pattern support for adding and removing
VetoableChangeListenerobjects that are tied to a specific named property:As an alternative, for each constrained property a Bean can provide methods with the following signature to register and unregister vetoable change listeners on a per property basis:void addVetoableChangeListener(String propertyName, VetoableChangeListener listener); void removeVetoableChangeListener(String propertyName, VetoableChangeListener listener);void add<PropertyName>Listener(VetoableChangeListener p); void remove<PropertyName>Listener(VetoableChangeListener p);
|
|
Start of Tutorial > Start of Trail > Start of Lesson |
Search
Feedback Form |
Copyright 1995-2004 Sun Microsystems, Inc. All rights reserved.