|
|
Start of Tutorial > Start of Trail |
Search
Feedback Form |
How does a builder tool examine a Bean and expose its features (properties, events, and methods) in a property sheet? By using the
The following documentation will help you learn about reflection, introspection, and theBeanInfoclass:
- Chapter 8 of the JavaBeans API Specification
![]()
- Core Reflection Documentation:
- The Reflection API
trail
- JDK Reflection
documentation
- Beans API Documentation:
BeanInfointerface
SimpleBeanInfoclass
Introspectorclass
FeatureDescriptorclass
BeanDescriptorclass
EventSetDescriptorclass
PropertyDescriptorclass
IndexedPropertyDescriptorclass
MethodDescriptorclass
ParameterDescriptorclass
java.beans.Introspectorclass. TheIntrospectorclass uses the JDK core reflection API to discover a Bean's methods, and then applies the JavaBeans design patterns to discover the Beans features. This discovery process is named introspection.Alternatively, you can explicitly expose a Bean's features in a separate, associated class that implements the
BeanInfointerface. By associating aBeanInfoclass with your Bean, you can:
- Expose only those features you want to expose.
- Rely on
BeanInfoto expose some Bean features while relying on low-level reflection to expose others.- Associate an icon with the target Bean.
- Specify a customizer class.
- Segregate features into normal and expert categories.
- Provide a more descriptive display name, or additional information about a Bean feature.
BeanInfodefines methods that return descriptors for each property, method, or event that you want exposed. Here's the prototypes for these methods:Each of these methods returns an array of descriptors for each feature.PropertyDescriptor[] getPropertyDescriptors(); MethodDescriptor[] getMethodDescriptors(); EventSetDescriptor[] getEventSetDescriptors();
BeanInfoclasses contain descriptors that precisely describe the target Bean's features. The BDK implements the following descriptor classes:
FeatureDescriptoris the base class for the other descriptor classes. It declares the aspects common to all descriptor types.BeanDescriptordescribes the target Bean's class type and name, and describes the target Bean's customizer class if it exists.PropertyDescriptordescribes the target Bean's properties.IndexedPropertyDescriptoris a subclass ofPropertyDescriptor, and describes the target Bean's indexed properties.EventSetDescriptordescribes the events the target Bean fires.MethodDescriptordescribes the target Bean's methods.ParameterDescriptordescribes method parameters.The
BeanInfointerface declares methods that return arrays of the above descriptors.
This section uses the
ExplicitButtonBeanInfodemo class to illustrate creating aBeanInfoclass. Here are the general steps to make aBeanInfoclass:
- Name your
BeanInfoclass. You must append the string "BeanInfo" to the target class name. If the target class name isExplicitButton, then its associated Bean information class must be namedExplicitButtonBeanInfo
- Subclass
SimpleBeanInfo. This is a convenience class that implementsBeanInfomethods to return null, or an equivalent no-op value.Usingpublic class ExplicitButtonBeanInfo extends SimpleBeanInfo {SimpleBeanInfosaves you from implementing all theBeanInfomethods; you only have to override those methods you need.
- Override the appropriate methods to return the properties, methods, or events that you want exposed.
ExplicitButtonBeanInfooverrides thegetPropertyDescriptors()method to return four properties:There are two important things to note here:public PropertyDescriptor[] getPropertyDescriptors() { try { PropertyDescriptor background = new PropertyDescriptor("background", beanClass); PropertyDescriptor foreground = new PropertyDescriptor("foreground", beanClass); PropertyDescriptor font = new PropertyDescriptor("font", beanClass); PropertyDescriptor label = new PropertyDescriptor("label", beanClass); background.setBound(true); foreground.setBound(true); font.setBound(true); label.setBound(true); PropertyDescriptor rv[] = {background, foreground, font, label}; return rv; } catch (IntrospectionException e) { throw new Error(e.toString()); } }
- If you leave a descriptor out, that property, event or method will not be exposed. In other words, you can selectively expose properties, events, or methods by leaving out those you don't want exposed.
- If a feature's getter (for example,
getMethodDescriptor()) method returns null, low-level reflection is then used for that feature. This means, for example, that you can explicitly specify properties, and let low-level reflection discover the methods. If you don't override theSimpleBeanInfodefault method, which returns null, low-level reflection will be used for that feature.
- Optionally associate an icon with the target Bean.
The BeanBox displays this icon next to the Bean name in the ToolBox. You can expect builder tools to do the same.public java.awt.Image getIcon(int iconKind) { if (iconKind == BeanInfo.ICON_MONO_16x16 || iconKind == BeanInfo.ICON_COLOR_16x16 ) { java.awt.Image img = loadImage("ExplicitButtonIcon16.gif"); return img; } if (iconKind == BeanInfo.ICON_MONO_32x32 || iconKind == BeanInfo.ICON_COLOR_32x32 ) { java.awt.Image img = loadImage("ExplicitButtonIcon32.gif"); return img; } return null; }
- Specify the target Bean
class, and, if the Bean has a customizer, specify it also.public BeanDescriptor getBeanDescriptor() { return new BeanDescriptor(beanClass, customizerClass); } ... private final static Class beanClass = ExplicitButton.class; private final static Class customizerClass = OurButtonCustomizer.class;Keep the
BeanInfoclass in the same directory as its target class. The BeanBox first searches for a target Bean'sBeanInfoclass in the target Bean's package path. If noBeanInfois found, then the Bean information package search path (maintained by theIntrospector) is searched. The default Bean information search path issun.beans.infos. If noBeanInfoclass is found, then low-level reflection is used to discover a Bean's features.
If you rely on low-level reflection to discover your Bean's features, all those properties, methods, and events that conform to the appropriate design patterns will be exposed in a builder tool. This includes any features in all base classes. If the BeanBox finds an associated
BeanInfoclass, then that information is used instead, and no more base classes are examined using reflection. In other words,BeanInfoinformation overrides low-level reflection information, and prevents base class examination.By using a
BeanInfoclass, you can expose subsets of a particular Bean feature. For example, by not returning a method descriptor for a particular method, that method will not be exposed in a builder tool.When you use a
BeanInfoclass:
- Base class features will not be exposed. You can retrieve base class features by using the
BeanInfo.getAdditionalBeanInfomethod.
- Properties, events, or methods that have no descriptor will not be exposed. For a particular feature, only those items returned in the descriptor array will be exposed. For example, if you return descriptors for all your Bean methods except
foo, thenfoowill not be exposed.
- Low-level reflection will be used for features with getter methods returning null. For example if your
BeanInfoclass contains this method implementation:Then low-level reflection will be used to discover your Bean's public methods.public MethodDescriptor[] getMethodDescriptors() { return null; }
Before examining a Bean, the
Introspectorwill attempt to find aBeanInfoclass associated with the Bean. By default, theIntrospectortakes the target Bean's fully qualified package name, and appends "BeanInfo" to form a new class name. For example, if the target Bean issunw.demo.buttons.ExplicitButton, then theIntrospectorwill attempt to locatesunw.demo.buttons.ExplicitButtonBeanInfo.If that fails, then each package in the
BeanInfosearch path is searched. TheBeanInfosearch path is maintained byIntrospector.setBeanInfoSearchPath()andIntrospector.getBeanInfoSearchPath().
|
|
Start of Tutorial > Start of Trail |
Search
Feedback Form |
Copyright 1995-2004 Sun Microsystems, Inc. All rights reserved.