Java in a Nutshell

Previous Chapter 10
Java Beans
Next
 

10.5 Specifying Bean Information

The YesNoDialog class itself and the AnswerEvent and AnswerListener classes it relies on are all a required part of our bean. When an application that uses the bean is shipped, it has to include all three of these class files. There are other kinds of classes, however, that are often bundled with a bean that are not intended for use by the application developer. These classes are used by the beanbox tool that manipulates the bean. The bean class itself does not refer to any of these auxiliary beanbox classes so that it is not dependent on them and they do not have to be shipped with the bean in finished products.

The first of these optional, auxiliary classes is a BeanInfo class. As explained earlier, a beanbox discovers the properties, events, and methods exported by a bean through "introspection" based on the Java Reflection API. A bean developer who wants to provide additional information about a bean, or who wants to refine the (somewhat rough) information available through introspection, should define a class that implements the BeanInfo interface to provide that information. A BeanInfo class typically subclasses SimpleBeanInfo, which provides a no-op implementation of the BeanInfo interface. When you only want to override one or two methods, it is easier to subclass SimpleBeanInfo than to implement BeanInfo directly. Beanbox tools rely on a naming convention in order to find the BeanInfo class for a given bean: a BeanInfo class should have the same name as the bean, with the string "BeanInfo" appended. Example 10.5 shows an implementation of the YesNoDialogBeanInfo class.

This BeanInfo class specifies a number of pieces of information for our bean:

Besides specifying this information, a BeanInfo class can also provide information about the events it generates and specify a default event. The various FeatureDescriptor objects used to provide information about such things as properties and methods can also include other information not provided by YesNoDialogBeanInfo, such as a localized display name that is distinct from the programmatic name.

Example 10.5: The YesNoDialogBeanInfo Class

package oreilly.beans.yesno;
import java.beans.*;
import java.lang.reflect.*;
import java.awt.*;
/** The BeanInfo class for the YesNoDialog bean. */
public class YesNoDialogBeanInfo extends SimpleBeanInfo {
  /** Return an icon for the bean.  We should really check the kind argument
   *  to see what size icon the beanbox wants, but since we only have one
   *  icon to offer, we just return it and let the beanbox deal with it. */
  public Image getIcon(int kind) {
    return loadImage("YesNoDialogIcon.gif");
  }
  /** Return a descriptor for the bean itself.  It specifies a customizer
   *  for the bean class.  We could also add a description string here. */
  public BeanDescriptor getBeanDescriptor() {
    return new BeanDescriptor(YesNoDialog.class, YesNoDialogCustomizer.class);
  }
  /** This is a convenience routine for creating PropertyDescriptor objects. */
  public static PropertyDescriptor property(String name, String description)
       throws IntrospectionException
  {
    PropertyDescriptor p = new PropertyDescriptor(name, YesNoDialog.class);
    p.setShortDescription(description);
    return p;
  }
  /** This method returns an array of PropertyDescriptor objects that specify
   *  additional information about the properties supported by the bean.
   *  By explicitly specifying property descriptors, we are able to provide
   *  simple help strings for each property; these would not be available to
   *  the beanbox through simple introspection.  We are also able to register
   *  special property editors for two of the properties.
   */
  public PropertyDescriptor[] getPropertyDescriptors() {
    try {
      PropertyDescriptor[] props = {
        property("title", "The string that appears in the dialog title bar"),
        property("message", "The string that appears in the dialog body"),
        property("yesLabel", "The label for the 'Yes' button, if any"),
        property("noLabel", "The label for the 'No' button, if any"),
        property("cancelLabel", "The label for the 'Cancel' button, if any"),
        property("alignment", "The alignment of the message text"),
        property("font", "The font to use for message and buttons"),
        property("background", "The background color for the dialog"),
        property("foreground", "The text color for message and buttons")
      };
      props[1].setPropertyEditorClass(YesNoDialogMessageEditor.class);
      props[5].setPropertyEditorClass(YesNoDialogAlignmentEditor.class);
      return props;
    }
    catch (IntrospectionException e) {return super.getPropertyDescriptors(); }
  }
  /** The message property is most often customized; make it the default. */
  public int getDefaultPropertyIndex() { return 1; }
  /** This is a convenience method for creating MethodDescriptors.  Note that
   *  it assumes we are talking about methods with no arguments. */
  public static MethodDescriptor method(String name, String description)
       throws NoSuchMethodException, SecurityException {
    Method m = YesNoDialog.class.getMethod(name, new Class[] {});
    MethodDescriptor md = new MethodDescriptor(m);
    md.setShortDescription(description);
    return md;
  }
  /** This method returns an array of method descriptors for the supported
   *  methods of a bean. This allows us to provide useful description strings,
   *  but it also allows us to filter out non-useful methods like wait()
   *  and notify() that the bean inherits and which might otherwise be
   *  displayed by the beanbox.
   */
  public MethodDescriptor[] getMethodDescriptors() {
    try {
      MethodDescriptor[] methods = {
        method("display", "Pop up the dialog; make it visible")
      };
      return methods;
    }
    catch (Exception e) {
      return super.getMethodDescriptors();
    }
  }
}


Previous Home Next
Custom Events Book Index Defining a Simple Property Editor

Java in a Nutshell Java Language Reference Java AWT Java Fundamental Classes Exploring Java