Archive for September, 2006

Developing Java Beans reject an unacceptable change to

Saturday, September 30th, 2006

Developing Java Beans // defer to the support object boundSupport.removePropertyChangeListener(l); } // add a constrained property listenerpublic void addVetoableChangeListener(VetoableChangeListener l) { // defer to the support object vetoSupport.addVetoableChangeListener(l); } // remove a constrained property listenerpublic void removeVetoableChangeListener(VetoableChangeListener l) { // defer to the support object vetoSupport.removeVetoableChangeListener(l); } // the get method for the Value property public int getValue() { return theValue; } // the set method for the Value property public void setValue(int newValue) throws PropertyVetoException { // fire the change to any constrained listenersvetoSupport.fireVetoableChange(”Value”, new Integer(theValue), new Integer(newValue)); // no veto, so save the old value and then change it Integer oldVal = new Integer(theValue); theValue = newValue; setText(String.valueOf(theValue)); repaint(); // fire the change to any bound listeners boundSupport.firePropertyChange(”Value”, oldVal, new Integer(theValue)); } // handle property change events from others public void propertyChange(PropertyChangeEvent evt) { // only interested in changes to Value properties if (evt.getPropertyName().equals(”Value”)) { // just change our own property Integer val = (Integer)evt.getNewValue(); try { setValue(val.intValue()); } catch (PropertyVetoException e) { } } } } page 66
Note: If you are looking for high quality webhost to host and run your jsp application check Vision jsp hosting services

Developing Java Beans reject an unacceptable change to

Saturday, September 30th, 2006

Developing Java Beans 4.5 Handling Events for Specific Properties If a Bean component supports bound properties, it is required to support the binding mechanism described earlier. This means that it must provide an addPropertyChangeListener() method for any client object that wants to receive bound property changes via the PropertyChangeListenerinterface. The same holds true for constrained properties. In that case, the Bean must provide an addVetoableChangeListener() method for any client object that wants to receive VetoableChangeEvent notifications via the VetoableChangeListener interface. But the Bean also has the option of providing specific registration methods for listeners to register for property change and vetoable change notifications for specific properties. There is no requirement to support these mechanisms, but they may be useful under some circumstances. There is a design pattern for registering and unregistering event listeners for changes to specific bound properties. The method signatures are as follows: public void addListener(PropertyChangeListener p); public void removeListener(PropertyChangeListener p); There is also a design pattern for registering and unregistering event listeners for vetoable change events for specific constrained properties. The method signatures are as follows: public void addListener(VetoableChangeListener p); public void removeListener(VetoableChangeListener p); This is convenient if a source object supports many properties and you are only interested in one. It eliminates unwanted PropertyChangeEvent and VetoableChangeEvent notifications. If you’re interested in changes for multiple properties, however, this technique probably doesn’t add any value. All of the property changes will still be directed to your one and only implementation of the propertyChange() or vetoableChange() methods. If you wanted to direct various property change events to different methods, you could combine these patterns with the adapter technique described in Chapter 3. 4.6 A java.awt Example The components provided by the java.awt package expose properties using the techniques just described. These user interface elements can be manipulated in the same way as any other object that conforms to the JavaBeans architecture. So let’s create an applet that illustrates the concepts of bound and constrained properties. Our applet will have a data member named primaryLabel which is an instance of class NumberLabel. A NumberLabel is a subclass of java.awt.Label that has a bound and constrained property named Value. The Value property is of type int, and the label always displays the contents of this property. We also have another instance of the NumberLabel class, named mirrorLabel, that will bind itself to the Value property of primaryLabel, and will keep its display consistent with it. There is one button to decrement the Value property of primaryLabel, and one to increment it; these button instances will be named decButton and incButton, respectively. Lastly, we will create an instance of class Constrainer, named cnstr, that constrains the Value property of primaryLabel to be between 10 and 20. A diagram of the interactions that will take place between the objects is shown in Figure 4.3. Figure 4.3. Constraining a property with a VetoableChangeEvent page 64
Note: If you are looking for high quality webhost to host and run your jsp application check Vision jsp hosting services

Developing Java Beans reject an unacceptable change to

Saturday, September 30th, 2006

Developing Java Beans theTemperature = temperature; // register for property change events theTemperature.addPropertyChangeListener(this); // construct the constrained property support object constrainedHandler = new VetoableChangeSupport(this); } [The existing code goes here] // add a VetoableChangeListener public void addVetoableChangeListener(VetoableChangeListener l) { // defer to the support handler constrainedHandler.addVetoableChangeListener(l); } // remove a VetoableChangeListener public void removeVetoableChangeListener(VetoableChangeListener l) { // defer to the support handler constrainedHandler.removeVetoableChangeListener(l); } // get the MinimumTemperature property value public double getMinimumTemperature() { return minTemperature; } // set the MinimumTemperature property value public void setMinimumTemperature(double newVal) throws PropertyVetoException { // let’s check against our own criterion first if (newVal < 10.0) { PropertyChangeEvent e = new PropertyChangeEvent(this, "MinimumTemperature", null, new Double(newVal)); throw new PropertyVetoException("Bad MinimumTemperature", e); } // defer to the support handler constrainedHandler.fireVetoableChange("MinimumTemperature", new Double(minTemperature), new Double(newVal)); // if the previous call did not throw an exception, then we are// free to make the changeminTemperature = newVal; } } The setMinimumTemperature() method first checks to see that the new value is not less than the absolute minimum value of 10 degrees Celsius. If it's not, the fireVetoableChange() method is called on the support object. This method handles all of the details of notifying the registered VetoableChangeListener objects and reverting them to the old value if any of them reject the change. If the change is rejected, the PropertyVetoException will be thrown. If not, the last line saves the new value of the property. page 63
Note: If you are looking for high quality webhost to host and run your jsp application check Vision jsp hosting services

Developing Java Beans reject an unacceptable change to

Saturday, September 30th, 2006

Developing Java Beans reject an unacceptable change to the FontSize property before any of the listening objects are ever notified. The class java.beans.VetoableChangeSupport is provided to make managing constrained properties easier. You can either inherit from this class or use an instance of it. The public methods of VetoableChangeSupport are shown here: public class java.beans.VetoableChangeSupportimplements java.io.Serializable { // construct the objectpublic VetoableChangeSupport(Object source); // add a vetoable change listener public synchronized void addVetoableChangeListener(VetoableChangeListener l); // fire a vetoable change event to any listeners public void fireVetoableChange(String propertyName, Object oldValue, Object newValue) throws java.beans.PropertyVetoException; // remove a vetoable change listenerpublic synchronized voidremoveVetoableChangeListener(VetoableChangeListener l); } The fireVetoableChange() method performs a valuable service. It fires the VetoableChangeEvent to all registered listeners, and if any of them veto the change it refires the event to all listeners to revert them to the old property value and then rethrows the java.beans.PropertyVetoException. This can be a real convenience, as we will see in the next example. Let’s look again at our Thermometer class. If an instance of this class is used to control a heating device, we might have a property of the Thermometer named MinimumTemperature. This is a read/write property that is used to set the temperature threshold that will trigger the turning on and off of the connected heating device. When the temperature drops 1 degree below this threshold, the heater will be turned on. The heater will be shut off when the temperature reaches the MinimumTemperature value. Let’s constrain the MinimumTemperature value to be no less than 10 degrees Celsius (50 degrees Fahrenheit), the minimum value that the Thermometer class itself will allow. The relevant additions to the Thermometer class are shown next. package BeansBook.Simulator; import java.beans.*; public class Thermometer implements PropertyChangeListener { // the minimum temperature threshold value defaults to// 15 degrees Celsiusprotected double minTemperature = 15.0; // the support object for constrained properties protected VetoableChangeSupport constrainedHandler; // constructor Thermometer(Temperature temperature) { page 62
Note: If you are looking for high quality webhost to host and run your jsp application check Vision jsp hosting services

Developing Java Beans changed, the getPropertyName() method may

Friday, September 29th, 2006

Developing Java Beans // notify listening objects of CurrentTemperature property changes protected void notifyTemperatureChange() { // fire the eventfirePropertyChange(”CurrentTemperature”, null, new Double(currentTemp)); } } 4.4 Constrained Properties To this point we’ve assumed that all the property changes that take place are acceptable. Often this will not be the case; it’s possible that an attempt to set a property to a given value will be unacceptable and therefore rejected. The simple case is when the object that owns the property wants to reject the change, but there may be times when another object wants a chance to voice its disapproval. Properties that go through this approval process are known as constrained properties. The design pattern for setting and getting constrained properties is similar to the design pattern for properties that are not constrained. The difference is that the set method declares that it throws the exception java.beans.PropertyVetoException. The method signatures look as follows: public get(); public void set( value) throws java.beans.PropertyVetoException; 4.4.1 Binding to Non-Specific Constrained Properties Those objects that want to participate in the approval process for a change to a constrained property must implement the java.beans.VetoableChangeListener interface. This interface contains a method called vetoableChange() that takes a single parameter of type PropertyChangeEvent. This method may throw the java.beans.PropertyVetoException if it wants to reject the change. Objects that support constrained properties must provide methods for registering and unregistering VetoableChangeListener objects. The methods should look like the following: public void addVetoableChangeListener(VetoableChangeListener p); public void removeVetoableChangeListener(VetoableChangelistener p); It’s possible for the object that owns the property to reject a change itself. So if a set() method is called with an unacceptable property value, the java.beans.PropertyVetoException can be thrown. If the owning object does not reject the change, it must send notifications to all registered VetoableChangeListener objects. This interaction is shown in Figure 4.2. Figure 4.2. Vetoable property changes page 60
Note: If you are looking for inexpensive but high quality provider to host and run your jsp application check Astra jsp hosting services

Developing Java Beans changed, the getPropertyName() method may

Friday, September 29th, 2006

Developing Java Beans A VetoableChangeEvent for a constrained property should be fired before the actual value of the property has changed. This gives any VetoableChangeListener a chance to reject the change when its vetoableChange() method is called. The event source must catch the java.beans.PropertyVetoException. If a listener throws the exception, the source object must fire a new Vetoable-ChangeEvent to all the registered VetoableChangeListener objects, using the current value for the property. This is necessary because if there were multiple listeners, some of them may already have been notified of the change that was subsequently rejected. So the second round of events gives those listeners the opportunity to revert to the old value. In this case, any PropertyVetoException that is thrown can be caught and ignored. The convention that the second round of PropertyVetoExceptions can be ignored prevents infinite loops in which no satisfactory value can be found. When a listener is informed of a change to a constrained property, it should not assume that the change has already taken place, because some other object may veto the change. If this happens, the listener will be notified again with the property reverted to its old value. Unfortunately, there is no way for the listener to know if the change will be universally accepted at the time of the first notification. So what should the listening object do? For example, let’s say that we have a dialog box that includes a component that allows the user to enter the font size to use for all of the controls on the dialog. This font sizer may have a constrained property named FontSize. All of the controls on the dialog are registered listeners implementing the java.beans.VetoableChangeListenerinterface, and each control has its own notion of the maximum font size. When each is notified of a request to change the value of the FontSize property, each compares the proposed value to its own maximum and throws the java.beans.PropertyVetoException if the value is too high. The control that rejects the change may do so after other controls have already been notified, in which case the previously notified controls may already have repainted themselves with the new font size. Now that another control has subsequently rejected the change, all of the controls will be notified again with the old font size value. The result is that the controls have to repaint themselves again. This is certainly not visually appealing, and is potentially time-consuming as well. The JavaBeans architecture addresses this issue by stating that properties can be both bound and constrained at the same time. In this case the property owner should fire a VetoableChangeEventbefore the property value is actually changed. If no VetoableChangeListener rejects the change, the property value should be changed and then the PropertyChangeEvent should be fired. The dialog controls I just discussed could be registered with the font sizer as both a PropertyChangeListener and a VetoableChangeListener at the same time. This would allow one of the controls to reject the change when the vetoableChange() method is called, but defer reacting to it until the propertyChange() method gets called. Another way to deal with this kind of problem is to have each control inform the font sizer of its maximum font size at initialization time. This way the font sizer itself will have the opportunity to page 61
Note: If you are looking for inexpensive but high quality provider to host and run your jsp application check Astra jsp hosting services

Developing Java Beans changed, the getPropertyName() method may

Friday, September 29th, 2006

Developing Java Beans null, it goes back to the source to get the value of the CurrentTemperature property. If it isn’t null, the value is retrieved directly from the new value object. A support class called java.beans.PropertyChangeSupport can be used to fire property change events to the registered listeners. You can either inherit from this class, or directly use an instance of it. PropertyChangeSupport implements the java.io.Serializable interface, which we discuss in Chapter 5. The method signatures of this class are as follows: public class java.beans.PropertyChangeSupportimplements java.io.Serializable { // construct the objectpublic PropertyChangeSupport(Object source); // add a property change listener public synchronized void addPropertyChangeListener(PropertyChangeListener l); // fire a property change event to any listeners public void firePropertyChange(String propertyName, Object oldValue, Object newValue); // remove a property change listener public synchronized void removePropertyChangeListener(PropertyChangeListener l); } We could reimplement the Temperature class by inheriting from the PropertyChangeSupportclass. This would eliminate the code that deals with the property change events. Note that the version of the constructor that takes no parameters calls the superclass constructor to make itself the event source. Although we aren’t going to keep the Temperature class like this, here’s what the code would look like if we did: package BeansBook.Simulator; import java.beans.*; import java.util.Vector; public class Temperature extends PropertyChangeSupport { // the current temperature in Celsiusprotected double currentTemp = 22.2; // the constructors public Temperature(double startingTemp) { this(); currentTemp = startingTemp; } public Temperature() { super(this); } // the get method for property CurrentTemperature public double getCurrentTemperature() { return currentTemp; } page 59
Note: If you are looking for inexpensive but high quality provider to host and run your jsp application check Astra jsp hosting services

Developing Java Beans changed, the getPropertyName() method may

Friday, September 29th, 2006

Developing Java Beans for (int i = 0; i < cnt; i++) { PropertyChangeListener client = (PropertyChangeListener)v.elementAt(i); client.propertyChange(evt); } } } With this change in place, we have to change the implementation of the Thermometer class as well. Instead of implementing the TempChangeListener interface it will implement the PropertyChangeListener interface. We remove the tempChanged() method and replace it with a propertyChange() method. For the sake of simplicity, let's revert to the case where the Thermometer works with a single Temperature object named theTemperature instead of the two that we worked with previously. The code for the changed constructor and propertyChange() method is shown below: // constructorThermometer(Temperature temperature) { theTemperature = temperature; // register for property change eventstheTemperature.addPropertyChangeListener(this); } // handle the property change eventspublic void propertyChange(PropertyChangeEvent evt) { // determine if the CurrentTemperature property of the temperature // object is the one that changed if (evt.getSource() == theTemperature && evt.getPropertyName() == "CurrentTemperature") { Temperature t = (Temperature)evt.getSource(); // get the new value object Object o = evt.getNewValue(); double newTemperature; if (o == null) { // go back to the object to get the temperature newTemperature = t.getCurrentTemperature(); } else { // get the new temperature valuenewTemperature = ((Double)o).doubleValue(); } } } The propertyChange() method first determines if the source of the event was its instance of the Temperature class, and if the property that changed is called CurrentTemperature. If these two things are true, the source is cast to type Temperature and the new value object is retrieved from the event object. Since the new value object can be null, there is a check for that condition. If it is page 58
Note: If you are looking for inexpensive but high quality provider to host and run your jsp application check Astra jsp hosting services

Developing Java Beans changed, the getPropertyName() method may

Friday, September 29th, 2006

Developing Java Beans { // the current temperature in Celsiusprotected double currentTemp = 22.2; // the collection of objects listening for property changes protected Vector propChangeListeners = new Vector(); // the constructors public Temperature(double startingTemp) { this(); currentTemp = startingTemp; } public Temperature() { } // the get method for property CurrentTemperature public double getCurrentTemperature() { return currentTemp; } // add a property change listener public synchronized void addPropertyChangeListener(PropertyChangeListener l) { // add a listener if it is not already registered if (!propChangeListeners.contains(l)) { propChangeListeners.addElement(l); } } // remove a property change listener public synchronized void removePropertyChangeListener(PropertyChangeListener l) { // remove it if it is registered if (propChangeListeners.contains(l)) { propChangeListeners.removeElement(l); } } // notify listening objects of CurrentTemperature property changesprotected void notifyTemperatureChange() { // create the event objectPropertyChangeEvent evt = new PropertyChangeEvent(this, “CurrentTemperature”, null, new Double(currentTemp)); // make a copy of the listener object vector so that it cannot// be changed while we are firing eventsVector v; synchronized(this) { v = (Vector) propChangeListeners.clone(); } // fire the event to all listenersint cnt = v.size(); page 57
Note: If you are looking for inexpensive but high quality provider to host and run your jsp application check Astra jsp hosting services

Developing Java Beans changed, the getPropertyName() method may

Friday, September 29th, 2006

Developing Java Beans changed, the getPropertyName() method may return null. The PropertyChangeEvent also contains something called a propagation ID. This is reserved for future use. If you receive a PropertyChangeEvent and then in turn generate and fire another PropertyChangeEvent, you must propagate the propagation ID as well. A PropertyChangeEvent for a bound property should only be fired after its internal state has been updated. This means that the event signifies a change that has already taken place. If an object supports bound properties, it will provide the following methods for registering and unregistering the associated event listeners: public void addPropertyChangeListener(PropertyChangeListener p); public void removePropertyChangeListener(PropertyChangelistener p); The java.beans.PropertyChangeListener interface extends the base Java class java.util.EventListener. This interface supports a single method called propertyChange(), which takes only one parameter as an argument, of type java.beans.PropertyChangeEvent. If an object wants to receive notifications of bound property changes, it would implement the java.beans.PropertyChangeListener interface and register itself with the source object by calling its addPropertyChangeListener() method. A diagram of this interaction is shown in Figure 4.1. Figure 4.1. Notifying a listener that a property has changed Let’s go back to our Temperature class. Earlier we added a read-only property to this class named CurrentTemperature. If we wanted to implement this as a bound property, we would implement the addPropertyChangeListener() and removePropertyChangeListener() methods. Then whenever CurrentTemperature changed, we would fire a PropertyChangeEvent to all listeners. Originally we designed the Temperature class to fire a TempChangedEvent to listeners that implement the TempChangeListener interface. For now we’ll remove the code related to the firing of TempChangeEvent events. Now that we understand properties, let’s modify the Temperatureclass to fire the PropertyChangeEvent instead. Because the object does not keep track of the previous temperature, the oldValue parameter of the PropertyChangeEvent constructor is set to null. The code would now look like this: package BeansBook.Simulator; import java.beans.*; import java.util.Vector; public class Temperature page 56
Note: If you are looking for inexpensive but high quality provider to host and run your jsp application check Astra jsp hosting services