620 likes | 939 Views
Chapter 8: JavaBeans. Java Programming - Advanced Topics. Objectives. In this unit you will: Learn what the JavaBeans component model is Create your own JavaBean components Learn how beanboxes consume beans
E N D
Chapter 8: JavaBeans Java Programming - Advanced Topics
Objectives • In this unit you will: • Learn what the JavaBeans component model is • Create your own JavaBean components • Learn how beanboxes consume beans • Learn the characteristics of a JavaBean, including how to define the properties, methods, and events for your own beans • Add custom event types to your beans
Objectives • In this unit you will: • Use JavaBeans information classes to make all features available to beanboxes that operate on your beans • Provide customized editors so that properties of your beans can be edited in a beanbox • Use the BeanContext API to create JavaBeans that can search their environment for available services • Gain a basic understanding of what an Enterprise JavaBean is
JavaBeans Component Model • Increasingly, Integrated Development Environment (IDEs) for the Java platform, such as IBM’s VisualAge for Java, are being designed to accept JavaBean components • When you use a visual development environment, the distinguishing feature of components such as JavaBeans becomes clear
JavaBeans Component Model • The components are manipulated at design time as binary executables • JavaBeans is the first component model for the Java platform • It is possible to define classes that conform to the specification of the JavaBeans component model and are also compatible with other Java programming models
What Makes a Class a Bean • The core classes and interfaces in the packages java.beans and java.beans.beancontext provide the support for creating JavaBeans • There is no JavaBean superclass that all JavaBeans extend and no interface that all JavaBeans implement • Creating a class of JavaBeans largely involves adhering to the standards of the JavaBeans component model
What Makes a Class a Bean • Some of the main characteristics of JavaBeans follow: • If a bean has a property names X, it can have public methods named setX or getX, to assign and return the value of the property • If a bean can generate events of the class Yevent, it should have public methods of the following forms: void addYListener( YEvent ) void removeYListener( Yevent )
What Makes a Class a Bean • Other public methods of the class are actions that the JavaBean can execute • All beans should have a constructor that takes no arguments because most beanboxes call this constructor • A JavaBean class must implement the marker interface Serializable because beanboxes use serialization to save the state of beans
Bean Development Environments • Sun created a demonstration development environment called the BeanBox • When using the BeanBox, keep in mind that it is not a production IDE and that you should not use it to create JavaBean applications • Instead, you should perform production development using tools such as IBM VisualAge for Java • You can load beans into the Sun BeanBox directly from a .jar file
Bean Development Environments • In general, a beanbox uses the classes of the java.lang.reflect package to analyze the classes contained within the .jar file • If the beanbox finds public methods of the form setX, getX, or isX, it assumes that X is a property of the JavaBean • If the beanbox finds public methods of the form addYListener and removeYListener, both of which return void and take a single argument of type Yevent, it assumes that the JavaBean fires events of the class YEvent
Using the Sun BeanBox • To start the BeanBox: 1. Open a command-line window and go to the folder in which you installed the BDK 2. Make the subfolder beanbox the current folder 3. Enter run
Using the Sun BeanBox • To position a demonstration bean in the Composition window: 1. Select the OrangeButton bean from the Toolbox window by clicking the word OrangeButton with the mouse 2. Position the cross-hair cursor on the BeanBox window. Click the BeanBox window, and the OrangeButton bean drops into place 3. Try changing some properties. Click the background box in the Properties window
Using the Sun BeanBox 4. Change the color of the bean by selecting a color from the drop-down list on the right of the window or by change the red, green, or blue intensity values in the middle of the window • To remove the bean from the BeanBox window: 1. Make sure the bean is selected 2. Click Edit from the BeanBox menu bar, and then click Cut 3. Click File from the BeanBox menu bar, and then click Exit to close the BeanBox window
Using the Sun BeanBox • When a bean is instantiated in a beanbox, the bean’s methods are called in the following order: • The constructor with no arguments is called to set up the bean • The preferredSize method, which you encounter again later in this unit, returns the display dimensions of the bean • The paint method draws the bean on the BeanBox window
Creating a JavaBean Class • An example JavaBean is developed throughout this unit • The bean displays an image on a panel • The first version is a class called ImageBean1 • It extends the class Panel and manipulates an object of type Image
Creating a JavaBean Class • The ImageBean1 bean has three properties: • The properties fileName and fillColor have mutator methods setFileName and setFillColor, and accessor methods getFileName and getFillColor. They are read-write properties • ImageBean1 has a getPreferredSize method but no setPreferredSize method. The property preferredSize is a read-only property of the bean
Breakdown of the ImageBean1 Class • The ImageBean1 class uses the JPanel class in the package javax.swing, several classes in the packages java.awt and java.io, as well as the ImageObserver class in the package java.awt.image as shown on page 700 • The class ImageBean1 inherits its serialization behavior from its superclass, JPanel • Therefore, ImageBean1 does not have to declare explicitly that it implements the interface Serializable as shown on page 700
Breakdown of the ImageBean1 Class • The fields of the ImageBean1 class record the state of the JavaBean • TheimageUpdate method is part of the ImageObserver interface that all AWT components implement • When a method is called to draw an image, the method may return before the image is fully available
ImageBean1 Class Used in a Beanbox • Before you can access a JavaBean in a beanbox, you must put it in a .jar file • The .jar file must include a manifest that specifies which .class files in the .jar file are JavaBeans • To load this example bean into the BeanBox window of the BDK: 1. Create a minimal manifest file for the bean ImageBean1. In a text editor, create a flat text file that contains the following two lines(as shown on page 703), followed by a blank line
ImageBean1 Class Used in a Beanbox 2. Save the file with filename ImageBean.manifest in the folder that is the parent of the folder that contains the package examples 3. Make sure the current folder is the one that contains the file ImageBeans.manifest and the examples folder 4. Copy the file ImageBeans.jar into the jars subfolder of the folder in which you installed the BDK 5. To start the beanbox, make the subfolder beanbox the current folder, and enter the command run 6. Using the same method described earlier in this unit, load the ImageBean1 bean into the BeanBox
ImageBean1 Class Used in a Beanbox 7. Select the ImageBean1 bean from the Toolbox window by clicking the word ImageBean1 with the mouse 8. Position the cross-hair cursor on the BeanBox window. Click the BeanBox window, and the ImageBean1 bean drops into place
ImageBean1 Class Used in a Beanbox • To tie a property from the JellyBean JavaBean to the ImageBean1 JavaBean: 1. The BeanBox ships a JellyBean JavaBean that has a color property. Select the JellyBean bean from the Toolbox window, and then drop the bean on the BeanBox composition window 2. The JellyBean should be surrounded by a hatched black and gray border to indicate it is selected 3. Click Edit on the menu bar of the BeanBox window, and then click Bind property
ImageBean1 Class Used in a Beanbox • The PropertyNameDialog box appears • A red line appears. One end of the line is attached to the JellyBean and the other end follows the mouse 6. The PropertyNameDialog box appears again, now showing the properties of the ImageBean1 bean. Select fillColor, and click OK
Indexed Properties • Properties are not limited to individual values • They can be indexed under a single name with an integer index value • You can provide methods for reading and writing individual elements of the property • Syntax property_type getproperty_name ( int index ) void setproperty_name( property_type x, int index )
Bound Properties • Bound properties provide notification when they change so that other JavaBeans can listen for these changes and act accordingly • The package java.beans includes a class for use with bound properties, PropertyChangeSupport, that is detailed next • Class: java.beans.PropertyChangeSupport • Purpose: You can create an instance of this class for a JavaBean class and delegate to it the tasks of maintaining a list of interested listeners and sending java.beans.PropertyChangeEvent objects
Bound Properties • Constructors: PropertyChangeSupport( Object sourceBean ) • Methods: • void addPropertyChangeListener( PropertyChangeListener listener ) • void firePropertyChange( String propertyName, Object oldValue, Object newValue ) • void removePropertyChangeListener( PropertyChangeListener listener )
Bound Properties • The next example program shows how these methods are used typically: • A class defines its own addPropertyChangeListener and removePropertyCnageListener methods that do little more than pass the PropertyChangeListener parameter they receive along to the PropertyChangeSupport instance • The set methods for the properties are modified to call the firePropertyChange method to indicate that the value has changed
Constrained Properties • The JavaBeans component model allows for the possibility that one or more of the listening objects might not allow some changes to the value of a property • This variation is known as a constrained property • To implement a constrained property, a JavaBean class should use a VetoablesChangeSupport object • Class: java.beans.VetoableChangeSupport
Constrained Properties • Purpose: Use a VetoableChangeSupport object for constrained properties much like you use a PropertyChangeSupport object for bound properties • Constructors: • VetoableChangeSupport( Object sourceBean ) • Methods: • void addVetoableChangeListener( PropertyChangeListener listener ) • void firePropertyChange( String propertyName, Object oldValue, Object newValue ) • void removeVetoableChangeListener( PropertyChangeListener listener )
Adding Custom Event Types • JavaBeans are not limited to just the PropertyChangeEvent event type • To create and use a custom event: 1. Define the event class that extends java.util.EventObject or one of its subclasses 2. Define the interface, XListener, that the event listeners must implement. This interface should extend the marker interface java.util.EventListener 3. The JavaBean class should define a method, fireX, that goes through the list of registered listeners and calls the handleX method, passing an X object for each of them
Creating a JavaBean Class With Events • The second JavaBean class, ImageBean2, is an enhancement of the ImageBean1 class • This class converts all the properties into bound properties and adds a custom event type, FillColorEvent • In a beanbox, it is very simple to add a button JavaBean and then connect the button’s click action to one of these methods
Breakdown of the ImageBean2 Class • The two new fields support the handling of events • The field myListeners provides the support for creating bound properties • The field FillColorListeners is the list of listeners registered to receive FillColorEvent objects (as shown on page 715) • The methods for accessing the properties have not changed, but the imageUpdate method has change to fire a PropertyChangeEvent if the image loaded has a size different from the previous image
Custom Event Class for the ImageBean2 Bean • A separate class defines the custom event used in the ImageBean2 class • The constructor takes three inputs: a reference to the object that is the source of the event, an integer constant that is the event identifier, and the color associated with the event • The source reference is passed along to the superclass constructor, Event Object
Listener Interface for the Custom Event Class • The last piece of code needed for this example is the definition of the FillColorListener interface • It adds just one empty method to the EventListener interface: package examples.beans; import java.util.EventListener; public interface FillColorListener extends EventListener { /** The method called when a FillColor change occurs */ public void fillColorChange( FillColorEvent e ) ; }
ImageBean2 Used in a BeanBox • To load ImageBean2 into the BDK BeanBox: 1. Add lines to the ImageBeans.manifest file in the folder into which you unpacked the examples.jar file, so that the file lists both ImageBean1 and ImageBean2 2. Type the following command, on one line, from the parent folder of the examples folder to create a .jar file ImageBeans.jar as shown on page 719 3. Copy the file ImageBeans.jar into the jars subfolder of the folder in which you installed the BDK 4. Start the BeanBox. See that ImageBean2 is now listed in the Toolbox window
ImageBean2 Used in a BeanBox 5. You can have a little fun with this bean. Drop an ImageBean2 bean onto the BeanBox window 6. Drop two BlueButton beans on to the BeanBox window and position them near, but not on top of, the ImageBean2. These beans look like buttons labeled “press” 7. Change the background property of one BlueButton to red and the other BlueButton to green 8. Click the red button. While it is selected, click Edit on the menu bar, and then select Events 9. Move over the area of the ImageBean2 bean, and click
ImageBean2 Used in a BeanBox 10. The EventTargetDialog appears, inviting you to select a target method 11. Now, try clicking the red button. The fill color of the ImageBean2 should turn red 12. In a similar fashion, make the green button change the fill color of the ImageBean2 to green 13. Now, you can use the bound properties of the ImageBean2. Drop a JellyBean onto the BeanBox window 14. Select the ImageBean2. Click Edit from the menu bar and then click Bind property 15. Connect the red line from the ImageBean2 to the JellyBean
Supplying Additional JavaBean Information • A beanbox finds the information classes as follows: • For each JavaBean class, the beanbox looks for a class with a name formed by appending the suffix BeanInfo onto the name of the JavaBean class • If a class satisfies the naming convention, the beanbox next checks whether the class implements the BeanInfo interface • If a class satisfies these requirements, the beanbox can call its methods to collect detailed information about the JavaBean
Supplying Additional JavaBean Information • Methods: • BeanInfo[ ] getAdditionalBeanInfo() • BeanDescriptor getBeanDescriptor() • int getDefaultEventIndex() • int getDefaultPropertyIndex() • EventSetDescriptor[ ] getEventSetDescriptors() • Image getIcon( int iconKind ) • MethodDescriptor[ ] getMethodDescriptors() • Property Descriptor[ ] getPropertyDescriptors()
Supplying Additional JavaBean Information • You can define a class that implements the BeanInfo interface and supply implementations of all the BeanInfo methods • A simpler approach is to define a class that extends the class java.beans.SimpleBeanInfo • You can extend the SimpleBeanInfoclass and override selected methods
Providing a Custom Property Editor • Beanboxes can provide property editors for several different types of properties, including String, Font, and Color • A programmer who creates JavaBeans must provide a property editor for other kinds of properties • All property editors must implement the interface java.beans.PropertyEditor • The class java.beans.PropertyEditorSupport provides a trivial property editor • Beanboxes usually provide a dialog box containing a list of all the JavaBean properties and a field for editing each one
Providing a Custom Property Editor • A special purpose customizer can treat the JavaBean as a whole because it can understand the dependencies between fields and makes sure that they are respected • The class must implement the java.beans.Customizer interface • An instance of the class must be an AWT component that can be embedded in a dialog box • The class must have a constructor that has no arguments • When you create a customizer class, you must also provide the method getBeanDescriptor in the BeanInfo class associated with the JavaBean
Creating a JavaBean Class With a BeanInfo Class • The third version of the example JavaBean, the ImageBean3 class is expanded further by the addition of another property called scaling • It allows the image to appear at its original size or scaled to fit the panel that contains it • This property has only two allowable values, the constants ORIGINAL_SIZE and SCALED_TO_FIT, both of which are defined in the class • ImageBean3 also has an accompanying BeanInfo class
Breakdown of the ImageBean3 Class • The ImageBean3 class is a variation on the ImageBean1 class that has a BeanInfo class • The paintComponent method is changed to handle the choices of image scaling • None of the other methods in the ImageBean3 class are new or have been updated • However, this class uses two additional classes: • The property editor class • The bean information class
Property Editor Class for the ImageBean3 Class • The scaling property of the ImageBean3 class requires a customized editor, and the ScalingEditor class provides it • This simple property editor only needs to present a list of two choices for users • Therefore, the ScalingEditor can be defined as a subclass of PropertyEditorSupport and can use most of the inherited method implementations
Property Editor Class for the ImageBean3 Class • The ScalingEditor class overrides three methods of the PropertyEditorSupport class that relate to the names and values of the allowable choices • The getTagsmethod returns the names of the value scaling for the property: public String[ ] getTags( )
Breakdown of the ImageBean3BeanInfo Class • The first method of the class, getPropertyDescriptors, returns an array of objects in which each element describes a different property of the ImageBean3 class: public class ImageBean3BeanInfo extends SimpleBeanInfo { public PropertyDescriptor[ ] getPropertyDescriptors( ) { • The method setPropertyEditorClass makes the association between the scaling property and its editor class
More Breakdown of the ImageBean3BeanInfo Class • The catch block is required to handle any errors that may occur because the introspection process could not be completed for the JavaBean • This catch clause recovers by printing a message to the console and returning the default list of property descriptors, as determined by the superclass SimpleBeanInfo • The other method in this BeanInfo class is used to indicate the default property for the JavaBean
Creating a JavaBean Class That Uses the BeanContext API • The fourth and final version of the example JavaBean, the ImageBean4 class, is expanded further using the BeanContext API to dynamically query its run-time environment to discover and use services offered by other JavaBeans • The BeanContext API has two parts • The first is a logical containment hierarchy for JavaBeans that describes JavaBeans as being located within something called a BeanContext container
Creating a JavaBean Class That Uses the BeanContext API • In the case if the ImageBean4 example, the BeanContext container is the BeanBox itself • To take advantage of the fact that it contains BeanContext, a JavaBean must implement the BeanContextChild interface or implement the BeanContextProxy interface • A JavaBean that implements the BeanContextProxy acts as a proxy for the object that does implement the BeanContextChild interface