Previous | Next | Trail Map | JavaBeans Tutorial | Writing Advanced Beans


Using BeanInfo


The following documentation will help you learn about the BeanInfo class:

A Bean can implicitly expose its properties, events, and methods by conforming to design patterns which are recognized by low-level reflection. Alternatively, a Bean can explicitly expose features in a separate, associated class that implements the BeanInfo interface. You can use the BeanInfo interface (or its convenience class SimpleBeanInfo) to explicitly expose design time information for JavaBeans-enabled builder tools.

By using an associated BeanInfo class you can

BeanInfo defines methods that return descriptors for each property, method, or event that is to be exposed in a builder tool. Here's the prototypes for these methods:

PropertyDescriptor[] getPropertyDescriptors();
MethodDescriptor[]   getMethodDescriptors();
EventSetDescriptor[] getEventSetDescriptors();
Each of these methods returns an array of descriptors for each item that is to be exposed in a builder tool.

Creating a BeanInfo Class

We'll use the ExplicitButtonBeanInfo to illustrate BeanInfo class creation. Here are the general steps to make a BeanInfo class:

  1. Name your BeanInfo class. You must append the string "BeanInfo" to the target class name. If the target class name is ExplicitButton, then its associated Bean information class must be named ExplicitButtonBeanInfo
  2. Subclass the SimpleBeanInfo class. This is a convenience class the implements BeanInfo methods to return null, or an equivalent noop value.
         public class ExplicitButtonBeanInfo extends SimpleBeanInfo {
         
    Using this class saves you from implementing all the BeanInfo methods; you only have to override those methods you need.
  3. Override the methods you need to specify and return the properties, methods, or events that you want. ExplicitButtonBeanInfo overrides the getPropertyDescriptors() method to return four properties:
         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());
            }
         }        
         
    There are two important things to note here:
    • If you leave a descriptor out, that property, event or method not described 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 method returns null, low-level reflection is used for that feature. So you can explicitly specify properties, for example, and let low-level reflection discover the methods. If you don't override the SimpleBeanInfo default method, which returns null, low-level reflection will be used for that feature.
  4. Optionally associate an icon with the target Bean.
          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;
          }
         
    The BeanBox displays this icon next to the Bean name in the ToolBox. You can expect builder tools to do similar.
  5. Specify the target Bean class, and, if the Bean has a customizer, specify it:
         public BeanDescriptor getBeanDescriptor() {
            return new BeanDescriptor(beanClass, customizerClass);
         }
         ...
         private final static Class beanClass = ExplicitButton.class;
         private final static Class customizerClass = OurButtonCustomizer.class;
         

Keep the BeanInfo class in the same directory as it's target class. The BeanBox first searches for a target Bean's BeanInfo class in the target Bean's package path. If no BeanInfo is found, then the Bean information package search path (maintained by the Introspector) is searched. The default Bean information search path is sun.beans.infos. If no BeanInfo class is found, then low-level reflection is used to discover a Bean's features.

Using BeanInfo to Control What Features are Exposed

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 BeanInfo class, then that information is used instead, and no more base classes are examined using reflection. In other words, BeanInfo information overrides low-level reflection information, and prevents base class examination.

By using a BeanInfo class, 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 BeanInfo class

Feature Descriptors

BeanInfo classes contain descriptors that precisely describe the target Bean's features. The BDK implements the following descriptor classes:

The BeanInfo interface declares methods that return arrays of the above descriptors.


Previous | Next | Trail Map | JavaBeans Tutorial | Writing Advanced Beans