BeanInfo Interface

A bean builder typically uses the introspection process to discover features (such as properties, methods, and events). In this case, the bean builder exposes all the features to the outside world.

We can also expose the bean’s features by using an associated class explicitly. By doing this we obtain the following benefits:

  • Hide features we do not want to disclose
  • Provide more information about bean features
  • Associate an icon with the target bean
  • Group bean features into different categories such as normal and advanced groups
  • Specify a customizer class
  • Expose some bean features explicitly using Java reflection API

The features of a bean are exposed using a separate special class. This class must implement the Beaninfo interface. The Beaninfo interface defines several methods that can be used to inspect properties, methods, and events of a bean. The following is the declaration of the Beaninfo interface:

public interface java.beans.BeanInfo{

public       static  final    int    ICON_COLOR_16x16;

public       static  final    int    ICON_COLOR_32x32;

public       static  final    int    ICON_MONO_16x16;

public       static  final    int    ICON_MONO_32x32;

public abstract java.beans.BeanDescriptor getBeanDescriptor();

public abstract java.beans.EventSetDescriptor[] getEventSetDescriptors();

public abstract int getDefaultEventIndex();

public abstract java.beans.PropertyDescriptor[] getPropertyDescriptors();

public abstract int getDefaultPropertyIndex();

public abstract java.beans.MethodDescriptor[] getMethodDescriptors();

public abstract java.beans.BeanInfo[] getAdditionalBeanInfo();

public abstract java.awt.Image getIcon(int);

}

 

The BeanInfo interface uses several descriptor classes, each of which describes specific features. The following is a list of descriptors:

  • BeanDescriptor—This descriptor class describes the bean’s name, type, and its customizer class, if any.
  • PropertyDescriptor—This descriptor encapsulates the target bean’s properties.
  • MethodDescriptor—This descriptor encapsulates the target bean’s methods.
  • EventsetDescriptor—This descriptor encapsulates the events that the target bean can fire.

Let us now write a BeanInfo class that describes the features of a bean. For this purpose, we shall first write a bean and show how the BeanBox extracts information from this bean. Consider the following bean class:

//Person.java

public class Person {

private String name = ”B. S. Roy”;

private String address = ”Narayanpur, Kol-136”;

private String PAN = “AGCPR8830P”;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getAddress() {

return address;

}

public String getPAN() {

return PAN;

}

public void setPAN(String PAN) {

this.PAN = PAN;

}

public void setAddress(String address) {

this.address = address;

}

}

The bean Person has three properties: name, address, and pan. Each of the three properties has a get and a set method. Compile this bean using the following command:

java Person.java

Create a class file, Person.class. Create a manifest file, manifest_person.mf, as follows:

Manifest-Version: 1.0

Name: Person.class

Java-Bean: True

Place this file in the same directory as Person.class. Now, create a jar file, person.jar, using the following command:

jar cvfm person.jar manifest_person.mf Person.class

It typically generates the following output:

added manifest

adding: Person.class(in = 754) (out= 410)(deflated 45%)

The bean is now ready to test and use. Load the person.jar file in the Bean Box. Create an instance of the Person bean and view its properties. It looks as shown in Figure 26.6.

As you can see, BeanBox shows all the properties of the Person bean. Suppose we do not disclose the pan property of the Person bean, as it is sensitive information. For that purpose, we can write the Beaninfo class. The following is the source code of the Beaninfo class.

//PersonBeanInfo.java

import java.beans.*;

public class PersonBeanInfo extends SimpleBeanInfo {

private Class personClass = Person.class;

public PropertyDescriptor[] getPropertyDescriptors() {

PropertyDescriptor name = null, address = null, PAN = null;

try {

name = new PropertyDescriptor(“name”, personClass);

name.setDisplayName(”Name:”);

name.setPreferred(true);

address = new PropertyDescriptor(“address”, personClass);

address.setDisplayName(”Address:”);

address.setPreferred(true);

} catch (IntrospectionException e) {}

PropertyDescriptor[] result = {name, address};

return result;

}

}

To write a Beaninfo class, we need to give a name. The name of each Beaninfo class follows a naming rule. The name of the Beaninfo class of the target bean X must have the name XBeaninfo. For example, the name of the Beaninfo class of our Person bean must be PersonBeaninfo. The string “BeanInfo” is appended to the target bean class name.

Since the Beaninfo interface implements several methods, we have to implement all of them. Alternatively, a Beaninfo class can be created by sub-classing the simpieBeaninfo class. The simpieBeaninfo class is a convenient base class for the Beaninfo classes. It implements all the methods, but all are empty. So, the SimpieBeaninfo class does not disclose any property of the method at all. We can override a specific method, where we want to return specific information. Since we want to hide the PAN property, we have overridden only the getPropertyDescriptors() method. In this method, we have returned an array of only three properties.

Now, modify the manifest file, manifest_person.mf, as follows:

Manifest-Version: 1.0

Name: Person.class

Java-Bean: True

Name: PersonBeanInfo.class

Java-Bean: False

Create the person.jar file as shown in Figure 26.7.

Load the jar file in BeanBox and create a Person bean. You can see that only three properties are shown. The result is shown in Figure 26.8.

We can also associate an icon with the bean. Override the geticon() method as follows:

public java.awt.Image getIcon(int iconKind) {

if (iconKind == BeanInfo.ICON_MONO_16x16 ||

iconKind == BeanInfo.ICON_COLOR_16x16 ) {

java.awt.Image img = loadImageCperson16.gif”);

return img;

}

if (iconKind == BeanInfo.ICON_MONO_32x32 ||

iconKind == BeanInfo.ICON_COLOR_32x32 ) {

java.awt.Image img = loadImageCperson32.gif”);

return img;

}

return null;

}

The BeanBox displays the icon in the toolbox before the bean name. The following important points can be noted:

  • If we do not include a descriptor, that property, method, or event will not be exposed. So, we can selectively expose properties, methods, or events by excluding those we do not want disclosed.
  • If a feature’s get (for example, getMethodDescriptor()) method returns null, low-level Java reflection API is then used to extract that feature. This means that developer-defined as well as low-level reflection can both be used to discover the methods. If default methods of the simpieBeaninfo class, which return null, are not overridden, low-level reflection is used for that feature.

Source: Uttam Kumar Roy (2015), Advanced Java programming, Oxford University Press.

Leave a Reply

Your email address will not be published. Required fields are marked *