java beans

23
JavaBeans JavaBeans™ is a portable, platform-independent component model written in the Java programming language. The JavaBeans architecture was built through a collaborative industry effort and enables developers to write reusable components in the Java programming language. With the JavaBeans API you can create reusable, platform-independent components. Using JavaBeans-compliant application builder tools, you can combine these components into applets, applications, or composite components. JavaBean components are known as beans. Beans are dynamic in that they can be changed or customized. Through the design mode of a builder tool, you use the property sheet or bean customizer to customize the bean and then save (persist) your customized beans. JavaBeans Concepts The JavaBeans™ architecture is based on a component model which enables developers to create software units called components. Components are self-contained, reusable software units that can be visually assembled into composite components, applets, applications, and servlets using visual application builder tools. JavaBean components are known as beans. A set of APIs describes a component model for a particular language. The JavaBeans API specification describes the core detailed elaboration for the JavaBeans component architecture. Beans are dynamic in that they can be changed or customized. Through the design mode of a builder tool you can use the Properties window of the bean to customize the bean and then save (persist) your beans using visual manupulation. You can select a bean from the toolbox, drop it into a form, modify its appearance and behavior, define its interaction with other beans, and combine it and other beans into an applet, application, or a new bean. 1 1

Upload: adarsh

Post on 15-Nov-2014

720 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Java Beans

JavaBeansJavaBeans™ is a portable, platform-independent component

model written in the Java programming language. The JavaBeans architecture was built through a collaborative industry effort and enables developers to write reusable components in the Java programming language.

With the JavaBeans API you can create reusable, platform-independent components. Using JavaBeans-compliant application builder tools, you can combine these components into applets, applications, or composite components.

JavaBean components are known as beans. Beans are dynamic in that they can be changed or customized. Through the design mode of a builder tool, you use the property sheet or bean customizer to customize the bean and then save (persist) your customized beans.

JavaBeans ConceptsThe JavaBeans™ architecture is based on a component model

which enables developers to create software units called components. Components are self-contained, reusable software units that can be visually assembled into composite components, applets, applications, and servlets using visual application builder tools. JavaBean components are known as beans.

A set of APIs describes a component model for a particular language. The JavaBeans API specificationdescribes the core detailed elaboration for the JavaBeans component architecture.

Beans are dynamic in that they can be changed or customized. Through the design mode of a builder tool you can use the Properties window of the bean to customize the bean and then save (persist) your beans using visual manupulation. You can select a bean from the toolbox, drop it into a form, modify its appearance and behavior, define its interaction with other beans, and combine it and other beans into an applet, application, or a new bean.

The following list briefly describes key bean concepts.

Builder tools discover a bean's features (that is, its properties, methods, and events) by a process known as introspection. Beans support introspection in two ways:

o By adhering to specific rules, known as design patterns, when naming bean features. The Introspector class examines beans for these design patterns to discover bean features. The Introspector class relies on the core reflection API. The

1

1

Page 2: Java Beans

trail The Reflection API is an excellent place to learn about reflection.

o By explicitly providing property, method, and event information with a related bean information class. A bean information class implements the BeanInfo interface. A BeanInfo class explicitly lists those bean features that are to be exposed to application builder tools.

Properties are the appearance and behavior characteristics of a bean that can be changed at design time. Builder tools introspect on a bean to discover its properties and expose those properties for manipulation.

Beans expose properties so they can be customized at design time. Customization is supported in two ways: by using property editors, or by using more sophisticated bean customizers.

Beans use events to communicate with other beans. A bean that is to receive events (a listener bean) registers with the bean that fires the event (a source bean). Builder tools can examine a bean and determine which events that bean can fire (send) and which it can handle (receive).

Persistence enables beans to save and restore their state. After changing a bean's properties, you can save the state of the bean and restore that bean at a later time with the property changes intact. The JavaBeans architecture uses Java Object Serialization to support persistence.

A bean's methods are no different from Java methods, and can be called from other beans or a scripting environment. By default all public methods are exported.

Beans vary in functionality and purpose. You have probably met some of the following beans in your programming practice:

GUI (graphical user interface)

Non-visual beans, such as a spelling checker

Animation applet

Spreadsheet application

Writing a Simple BeanIn this section you will learn more about beans by performing the following actions:

2

2

Page 3: Java Beans

Creating a simple bean

Compiling the bean

Generating a Java Archive (JAR) file

Loading the bean into the GUI Builder of the NetBeans IDE

Inspecting the bean's properties and events

Your bean will be named SimpleBean. Here are the steps to create it:

1.Write the SimpleBean code. Put it in a file named SimpleBean.java, in the directory of your choice. Here's the code: import java.awt.Color;import java.beans.XMLDecoder;import javax.swing.JLabel;import java.io.Serializable;

public class SimpleBean extends JLabel implements Serializable { public SimpleBean() { setText( "Hello world!" ); setOpaque( true ); setBackground( Color.RED ); setForeground( Color.YELLOW ); setVerticalAlignment( CENTER ); setHorizontalAlignment( CENTER ); } }

SimpleBean extends the javax.swing.JLabel graphic component and inherits its properties, which makes the SimpleBean a visual component. SimpleBean also implements the java.io.Serializable interface. Your bean may implement either the Serializable or the Externalizable interface.

2. Create a manifest, the JAR file, and the class file SimpleBean.class. Use the Apache Ant tool to create these files. Apache Ant is a Java-based build tool that enables you to generate XML-based configurations files as follows: <?xml version="1.0" encoding="ISO-8859-1"?>

<project default="build">

<dirname property="basedir" file="${ant.file}"/>

<property name="beanname" value="SimpleBean"/> <property name="jarfile" value="${basedir}/${beanname}.jar"/>

3

3

Page 4: Java Beans

<target name="build" depends="compile"> <jar destfile="${jarfile}" basedir="${basedir}" includes="*.class"> <manifest> <section name="${beanname}.class"> <attribute name="Java-Bean" value="true"/> </section> </manifest> </jar> </target>

<target name="compile"> <javac destdir="${basedir}"> <src location="${basedir}"/> </javac> </target>

<target name="clean"> <delete file="${jarfile}"> <fileset dir="${basedir}" includes="*.class"/> </delete> </target>

</project>

It is recommended to save an XML script in the build.xml file, because Ant recognizes this file name automatically.

3. Load the JAR file. Use the NetBeans IDE GUI Builder to load the jar file as follows:

Start NetBeans.

From the File menu select "New Project" to create a new application for your bean. You can use "Open Project" to add your bean to an existing application.

Create a new application using the New Project Wizard.

Select a newly created project in the List of Projects, expand the Source Packages node, and select the Default Package element.

Click the right mouse button and select New|JFrameForm from the pop-up menu.

Select the newly created Form node in the Project Tree. A blank form opens in the GUI Builder view of an Editor tab.

Open the Palette Manager for Swing/AWT components by selecting Palette Manager in the Tools menu.

In the Palette Manager window select the beans components in the Palette tree and press the "Add from JAR" button.

4

4

Page 5: Java Beans

Specify a location for your SimpleBean JAR file and follow the Add from JAR Wizard instructions.

Select the Palette and Properties options from the Windows menu.

Expand the beans group in the Palette window. The SimpleBean object appears. Drag the SimpleBean object to the GUI Builder panel.

The following figure represents the SimpleBean object loaded in the GUI Builder panel:

4.Inspect Properties and Events. The SimpleBean properties will appear in the Properties window. For example, you can change a background property by selecting another color. To preview your form, use the Preview Design button of the GUI Builder toolbar. To inspect events associated with the SimpleBean object, switch to the Events tab of the Properties window. You will learn more about bean properties and events in the lessons that follow

Lesson: Properties

5

5

Page 6: Java Beans

In the following sections you will learn how to implement bean properties. A bean property is a named attribute of a bean that can affect its behavior or appearance. Examples of bean properties include color, label, font, font size, and display size.

The JavaBeans™ specification defines the following types of bean properties:

Simple – A bean property with a single value whose changes are independent of changes in any other property.

Indexed – A bean property that supports a range of values instead of a single value.

Bound – A bean property for which a change to the property results in a notification being sent to some other bean.

Constrained – A bean property for which a change to the property results in validation by another bean. The other bean may reject the change if it is not appropriate.

Bean properties can also be classified as follows:

Writable – A bean property that can be changed

o Standard

o Expert

o Preferred

Read Only – A bean property that cannot be changed.

Hidden – A bean property that can be changed. However, these properties are not disclosed with the BeanInfo class

BeanBuilder uses this schema to group and represent properties in the Properties window.

Simple PropertiesTo add simple properties to a bean, add appropriate getXXX and setXXX methods (or isXXX and setXXX methods for a boolean property).

The names of these methods follow specific rules called design patterns. These design pattern-based method names allow builder

6

6

Page 7: Java Beans

tools such as the NetBeans GUI Builder, to provide the following features:

Discover a bean's properties

Determine the properties' read/write attributes

Determine the properties' types

Locate the appropriate property editor for each property type

Display the properties (usually in the Properties window)

Alter the properties (at design time)

Bound Properties

Bound properties support the PropertyChangeListener (in the API reference documentation) class.

Sometimes when a Bean property changes, another object might need to be notified of the change, and react to the change.

Whenever a bound property changes, notification of the change is sent to interested listeners.

The accessor methods for a bound property are defined in the same way as those for simple properties. However, you also need to provide the event listener registration methods forPropertyChangeListener classes and fire a PropertyChangeEvent (in the API reference documentation) event to the PropertyChangeListener objects by calling their propertyChange methods

The convenience PropertyChangeSupport (in the API reference documentation) class enables your bean to implement these methods. Your bean can inherit changes from the PropertyChangeSupportclass, or use it as an inner class.

In order to listen for property changes, an object must be able to add and remove itself from the listener list on the bean containing the bound property. It must also be able to respond to the event notification method that signals a property change.

7

7

Page 8: Java Beans

The PropertyChangeEvent class encapsulates property change information, and is sent from the property change event source to each object in the property change listener list with the propertyChange method.

Implementing Bound Property Support Within a BeanTo implement a bound property in your application, follow these steps:

1. Import the java.beans package. This gives you access to the PropertyChangeSupport class.

2. Instantiate a PropertyChangeSupport object. This object maintains the property change listener list and fires property change events. You can also make your class a PropertyChangeSupport subclass.

3. Implement methods to maintain the property change listener list. Since a PropertyChangeSupport subclass implements these methods, you merely wrap calls to the property-change support object's methods.

4. Modify a property's set method to fire a property change event when the property is changed.

Constrained Properties

A bean property is constrained if the bean supports the VetoableChangeListener(in the API reference documentation) and PropertyChangeEvent(in the API reference documentation) classes, and if the set method for this property throws a PropertyVetoException(in the API reference documentation).

Constrained properties are more complicated than bound properties because they also support property change listeners which happen to be vetoers.

The following operations in the setXXX method for the constrained property must be implemented in this order:

1. Save the old value in case the change is vetoed.

8

8

Page 9: Java Beans

2. Notify listeners of the new proposed value, allowing them to veto the change.

3. If no listener vetoes the change (no exception is thrown), set the property to the new value.

The accessor methods for a constrained property are defined in the same way as those for simple properties, with the addition that the setXXX method throws a PropertyVetoException exception. The syntax is as follows:

public void setPropertyName(PropertyType pt)throws PropertyVetoException {code}

Handling VetoesIf a registered listener vetoes a proposed property change by throwing a PropertyVetoException exception, the source bean with the constrained property is responsible for the following actions:

Catching exceptions.

Reverting to the old value for the property.

Issuing a new VetoableChangeListener.vetoableChange call to all listeners to report the reversion.

The VetoableChangeListener class throws a PropertyVetoException and handles the PropertyChangeEvent event fired by the bean with the constrained property.

The VetoableChangeSupport provides the following operations:

Keeping track of VetoableChangeListener objects.

Issuing the vetoableChange method on all registered listeners.

Catching any vetoes (exceptions) thrown by listeners.

Informing all listeners of a veto by calling vetoableChange again, but with the old property value as the proposed "new" value.

9

9

Page 10: Java Beans

Indexed PropertiesAn indexed property is an array of properties or objects that supports a range of values and enables the accessor to specify an element of a property to read or write.

Indexed properties are specified by the following methods: //Methods to access individual values

public PropertyElement getPropertyName(int index)public void setPropertyName(int index, PropertyElement element)

and //Methods to access the entire indexed property array

public PropertyElement[] getPropertyName()public void setPropertyName(PropertyElement element[])

Note that the distinction between the get and set methods for indexed properties is subtle. The get method either has an argument that is the array index of the property, or returns an array. The set method either has two arguments, namely an integer array index and the property element object that is being set, or has the entire array as an argument.

Manipulating Events

Event passing is the means by which components communicate with each other. Components broadcast events, and the underlying framework delivers the events to the components that are to be notified. The notified components usually perform some action based on the event that took place.

The event model was designed to accommodate the JavaBeans™ architecture. To understand how events and event handling work in the JavaBeans component model, you must understand the concepts of events, listeners, and sources. To refresh your knowledge in these areas, read the Writing Event Listeners lesson of the Swing tutorial.

The event model that is used by the JavaBeans architecture is a delegation model. This model is composed of three main parts: sources, events, and listeners.

The source of an event is the object that originates or fires the event. The source must define the events it will fire, as well as the methods for registering listeners of those events. A listener is an object that indicates that it is to be notified of events of a particular type. Listeners register for events using the methods defined by the sources of those events.

10

10

Page 11: Java Beans

From the Properties lesson you discovered two event listeners. The PropertyChangeListener(in the API reference documentation) interface provides a notification whenever a bound property value is changed and the VetoableChangeListener(in the API reference documentation) creates a notification whenever a bean changes a constrained property value.

Simple Event ExampleThis example represents an application that performs an action when a button is clicked. Button components are defined as sources of an event type called ActionEvent(in the API reference documentation). Listeners of events of this type must register for these events using the addActionListener method.

Therefore, the addActionListener method is used to register the ButtonHandler object as a listener of the ActionEvent event that is fired by the button.

In addition, according to the requirements of the ActionListener class, you must define an actionPerformed method, which is the method that is called when the button is clicked. import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JTextArea;import java.awt.BorderLayout;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.WindowConstants;

public class ButtonHandler implements ActionListener { /** * Component that will contain messages about * events generated. */ private JTextArea output; /** * Creates an ActionListener that will put messages in * JTextArea everytime event received. */ public ButtonHandler( JTextArea output ) { this.output = output; }

/** * When receives action event notification, appends * message to the JTextArea passed into the constructor. */ public void actionPerformed( ActionEvent event ) { this.output.append( "Action occurred: " + event + '\n' ); }

11

11

Page 12: Java Beans

}

class ActionTester { public static void main(String args[]) { JFrame frame = new JFrame( "Button Handler" ); JTextArea area = new JTextArea( 6, 80 ); JButton button = new JButton( "Fire Event" ); button.addActionListener( new ButtonHandler( area ) ); frame.add( button, BorderLayout.NORTH ); frame.add( area, BorderLayout.CENTER ); frame.pack(); frame.setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE ); frame.setLocationRelativeTo( null ); frame.setVisible( true ); }}

Bean PersistenceA bean has the property of persistence when its properties, fields, and state information are saved to and retrieved from storage. Component models provide a mechanism for persistence that enables the state of components to be stored in a non-volatile place for later retrieval.

The mechanism that makes persistence possible is called serialization. Object serialization means converting an object into a data stream and writing it to storage. Any applet, application, or tool that uses that bean can then "reconstitute" it by deserialization. The object is then restored to its original state.

For example, a Java application can serialize a Frame window on a Microsoft Windows machine, the serialized file can be sent with e-mail to a Solaris machine, and then a Java application can restore the Frame window to the exact state which existed on the Microsoft Windows machine.

Any applet, application, or tool that uses that bean can then "reconstitute" it by deserialization.

All beans must persist. To persist, your beans must support serialization by implementing either the java.io.Serializable(in the API reference documentation) interface, or the java.io.Externalizable(in the API reference documentation) interface. These interfaces offer you the choices of automatic serialization and customized serialization. If any class in a class's inheritance hierarchy implements Serializable or Externalizable, then that class is serializable.

Classes That Are Serializable

12

12

Page 13: Java Beans

Any class is serializable as long as that class or a parent class implements the java.io.Serializable interface. Examples of serializable classes include Component, String, Date, Vector, and Hashtable. Thus, any subclass of the Component class, including Applet, can be serialized. Notable classes not supporting serialization include Image, Thread, Socket, and InputStream. Attempting to serialize objects of these types will result in an NotSerializableException.

The Java Object Serialization API automatically serializes most fields of a Serializable object to the storage stream. This includes primitive types, arrays,and strings. The API does not serialize or deserialize fields that are marked transient or static.

Controlling Serialization

You can control the level of serialization that your beans undergo. Three ways to control serilization are:

Automatic serialization, implemented by the Serializable interface. The Java serialization software serializes the entire object, except transient and static fields.

Customized serialization. Selectively exclude fields you do not want serialized by marking with the transient (or static) modifier.

Customized file format, implemented by the Externalizable interface and its two methods. Beans are written in a specific file format.

Default Serialization: The Serializable Interface

The Serializable interface provides automatic serialization by using the Java Object Serialization tools. Serializable declares no methods; it acts as a marker, telling the Object Serialization tools that your bean class is serializable. Marking your class Serializable means you are telling the Java Virtual Machine (JVM) that you have made sure your class will work with default serialization. Here are some important points about working with the Serializable interface:

Classes that implement Serializable must have an access to a no-argument constructor of supertype. This constructor will be called when an object is "reconstituted" from a .ser file.

You don't need to implement Serializable in your class if it is already implemented in a superclass.

13

13

Page 14: Java Beans

All fields except static and transient fields are serialized. Use the transient modifier to specify fields you do not want serialized, and to specify classes that are not serializable.

The Externalizable Interface

Use the Externalizable interface when you need complete control over your bean's serialization (for example, when writing and reading a specific file format). To use the Externalizable interface you need to implement two methods: readExternal and writeExternal. Classes that implement Externalizable must have a no-argument constructor.

IntrospectionIntrospection is the automatic process of analyzing a bean's design patterns to reveal the bean's properties, events, and methods. This process controls the publishing and discovery of bean operations and properties. This lesson explains the purpose of introspection, introduces the Introspection API, and gives an example of introspection code.

Purpose of Introspection

A growing number of Java object repository sites exist on the Internet in answer to the demand for centralized deployment of applets, classes, and source code in general. Any developer who has spent time hunting through these sites for licensable Java code to incorporate into a program has undoubtedly struggled with issues of how to quickly and cleanly integrate code from one particular source into an application.

The way in which introspection is implemented provides great advantages, including:

1. Portability - Everything is done in the Java platform, so you can write components once, reuse them everywhere. There are no extra specification files that need to be maintained independently from your component code. There are no platform-specific issues to contend with. Your component is not tied to one component model or one proprietary platform. You get all the advantages of the evolving Java APIs, while maintaining the portability of your components.

2. Reuse - By following the JavaBeans design conventions, implementing the appropriate interfaces, and extending the appropriate classes, you provide your component with reuse potential that possibly exceeds your expectations.

Introspection API

14

14

Page 15: Java Beans

The JavaBeans API architecture supplies a set of classes and interfaces to provide introspection.

The BeanInfo (in the API reference documentation) interface of the java.beans package defines a set of methods that allow bean implementors to provide explicit information about their beans. By specifying BeanInfo for a bean component, a developer can hide methods, specify an icon for the toolbox, provide descriptive names for properties, define which properties are bound properties, and much more.

The getBeanInfo(beanName) (in the API reference documentation) of the Introspector (in the API reference documentation) class can be used by builder tools and other automated environments to provide detailed information about a bean. The getBeanInfo method relies on the naming conventions for the bean's properties, events, and methods. A call to getBeanInfo results in the introspection process analyzing the bean’s classes and superclasses.

The Introspector class provides descriptor classes with information about properties, events, and methods of a bean. Methods of this class locate any descriptor information that has been explicitly supplied by the developer through BeanInfo classes. Then the Introspector class applies the naming conventions to determine what properties the bean has, the events to which it can listen, and those which it can send.

The following figure represents a hierarchy of the FeatureDescriptor classes:

Each class represented in this group describes a particular attribute of the bean. For example, the isBound method of the PropertyDescriptor class indicates whether a PropertyChangeEvent event is fired when the value of this property changes.

Bean Customization

15

15

Page 16: Java Beans

Customization provides a means for modifying the appearance and behavior of a bean within an application builder so it meets your specific needs. There are several levels of customization available for a bean developer to allow other developers to get maximum benefit from a bean’s potential functionality.

The following links are useful for learning about property editors and customizers:

PropertyEditor (in the API reference documentation) interface

PropertyEditorSupport (in the API reference documentation) class

PropertyEditorManager (in the API reference documentation) class

Customizer (in the API reference documentation) interface

BeanInfo (in the API reference documentation) interface

A bean's appearance and behavior can be customized at design time within beans-compliant builder tools. There are two ways to customize a bean:

By using a property editor. Each bean property has its own property editor. The NetBeans GUI Builder usually displays a bean's property editors in the Properties window. The property editor that is associated with a particular property type edits that property type.

By using customizers. Customizers give you complete GUI control over bean customization. Customizers are used where property editors are not practical or applicable. Unlike a property editor, which is associated with a property, a customizer is associated with a bean.

Property Editors

A property editor is a tool for customizing a particular property type. Property editors are activated in the Properties window. This window determines a property's type, searches for a relevant property editor, and displays the property's current value in a relevant way.

Property editors must implement the PropertyEditor interface, which provides methods to specify how a property should be displayed in a

16

16

Page 17: Java Beans

property sheet. The following figure represents the Properties window containing myBean1 properties:

You begin the process of editing these properties by clicking the property entry. Clicking most of these entries will bring up separate panels. For example, to set up the foreground or background use selection boxes with choices of colors, or press the "..." button to work with a standard ColorEditor window. Clicking on the toolTipText property opens a StringEditor window.

The support class PropertyEditorSupport provides a default implementation of the PropertyEditor interface. By subclassing your property editor from PropertyEditorSupport, you can simply override the methods you need.

To display the current property value "sample" within the Properties window, you need to override isPaintable to return true. You then must override paintValue to paint the current property value in a rectangle in the property sheet. Here's how ColorEditor implements paintValue: public void paintValue(java.awt.Graphics gfx, java.awt.Rectangle box) { Color oldColor = gfx.getColor(); gfx.setColor(Color.black); gfx.drawRect(box.x, box.y, box.width-3, box.height-3); gfx.setColor(color); gfx.fillRect(box.x+1, box.y+1, box.width-4, box.height-4); gfx.setColor(oldColor);}

To support the custom property editor, override two more methods. Override supportsCustomEditor to return true, and then override getCustomEditor to return a custom editor instance. ColorEditor.getCustomEditor returns this.

In addition, the PropertyEditorSupport class maintains a PropertyChangeListener list, and fires property change event notifications to those listeners when a bound property is changed.

How Property Editors are Associated with Properties

Property editors are discovered and associated with a given property in the following ways:

Explicit association by way of a BeanInfo object. The editor of the title's property is set with the following line of code:

pd.setPropertyEditorClass(TitleEditor.class);

Explicit registration by way of the java.beans.PropertyEditorManager.registerEditor method. This

17

17

Page 18: Java Beans

method takes two arguments: the bean class type, and the editor class to be associated with that type.

Name search. If a class has no explicitly associated property editor, then the PropertyEditorManager searchs for that class's property editor in the following ways:

o Appending "Editor" to the fully qualified class name. For example, for the my.package.ComplexNumber class, the property editor manager would search for the my.package.ComplexNumberEditor class.

o Appending "Editor" to the class name and searching a class path.

Customizers

You have learned that builder tools provide support for you to create your own property editors. What other needs should visual builders meet for complex, industrial-strength beans? Often it is undesirable to have all the properties of a bean revealed on a single (sometimes huge) property sheet. What if one single root choice about the type of the bean rendered half the properties irrelevant? The JavaBeans specification provides for user-defined customizers, through which you can define a higher level of customization for bean properties than is available with property editors.

When you use a bean Customizer, you have complete control over how to configure or edit a bean. A Customizer is an application that specifically targets a bean's customization. Sometimes properties are insufficient for representing a bean's configurable attributes. Customizers are used where sophisticated instructions would be needed to change a bean, and where property editors are too primitive to achieve bean customization.

All customizers must:

Extend java.awt.Component or one of its subclasses.

Implement the java.beans.Customizer interface This means implementing methods to register PropertyChangeListener objects, and firing property change events at those listeners when a change to the target bean has occurred.

Implement a default constructor.

Associate the customizer with its target class via BeanInfo.getBeanDescriptor.

18

18

Page 19: Java Beans

19

19