JavaData & JavaHow to Use the JavaBean API Library

How to Use the JavaBean API Library

JavaBean is a paradigm of specified norms that define reusable software component design. Any Java class is a potential bean, provided they follow the specification laid by the specification guideline. The rules are simple and straightforward as we shall see down the line. Apart from these norms, there is a Java bean API library that helps in the process of transforming a POJO into a bean component and in realizing the introspection mechanism subsequently. The list of library APIs are contained in the java.beans package. Once a Java bean is created, it can be plugged in as an independent entity to an application that requires the service defined by the component. This article shall discuss some of the key aspects of transforming a POJO into a bean component and how the JavaBean API library helps in the process.

JavaBean and Library Classes

Can we not create every Java class as a bean? Yes, we can, but it will not make sense under all circumstances. Beans usually are appropriate for creating visual software components that are manipulated and customized to meet specific requirements. For example, think of a visual component such as a frame or button, whose shape and color can be customized according to our needs. (Recall how you can drag-drop and use components such as JButton, JList, and so forth, and change its properties in NetBeans). So, those Java classes are perfect to be re-christened as a JavaBean from POJO. Class libraries, on the other hand, are POJOs that provide functionalities for programmers. They do not have, rather they do not require, visual manipulation. For example, the JDBC API classes are library classes that do not require visual manipulation. But, you always can make a database access bean on top of the JDBC classes, and in that case it would better be created as a JavaBean component, so that it can be used/reused at any time. There are some specific advantages and disadvantages of a Java bean:

Advantages

  • Beans are persistable and can be stored and retrieved back from permanent storage.
  • A bean can be customized and manipulated by some auxiliary software.
  • We can control what properties, methods, and events are to be exposed to the application that wants to use it.
  • A bean can not only be registered to receive events send by another object, but also generate events.

Disadvantages

  • The benefits of immutable objects are absent in beans because they are by default mutable.
  • Because every Java bean must have a no-argument constructor (nullary constructor), this may lead to an object being instantiated in an invalid state.
  • Bean classes contain much boilerplate code because, as per specification, most or all private properties must be exposed through public getters and setters. This often leads to writing many unnecessary codes.

The Standard

Firstly, to create a JavaBean, the following basic rules are to be maintained in a Java class. These rules are actually conventions that must be adhered to because other libraries, when using this component, expect these rules are maintained.

  • All private properties deemed to be accessed programmatically must be accessible through a public getter and setter method. For example, if salary is a property of an Employee class, it must be exposed through the getSalary and setSalary methods.
  • It doesn’t matter how many polymorphic constructor are supplied, but a bean class must have a public no-argument constructor.
  • A bean class must be serializable; or, in other words, must implement a java.io.Serializable or java.io.Externalizable interface. This provides the ability of persistence to a bean component.

A class that deviates from the rules will not be a bean because JavaBean is a standard. Once you follow the rules and design the class appropriately, the user who also knows the standard can appropriately fit the component into their application easily. This is the goal of JavaBean—to create reusable software components.

Important Features

There are three important features associated with JavaBeans:

  • Properties: Named attributes associated with a bean
  • Methods: POJO methods of which the bean can choose to expose a subset of its public types.
  • Events: Notify other components if something interesting occurs.

JavaBean API

The package java.beans contains a set of classes and interfaces that provide many functionalities related to creating components based on JavaBeans architecture. These classes are used by beans at runtime. For example, the PropertyChangeEvent class is used to fire property and vetoable change events.

JavaBeans component architecture also provides support for a long-term persistence model. This enables beans to be saved in XML format. The read scheme with persistence is pretty straightforward and does not require any special knowledge in the process. The write scheme is a bit tricky at times and requires special knowledge about the bean’s type. If the bean’s state is exposed using a nullary constructor, properties using public getters and setters, no special knowledge is required. Otherwise, the bean requires a custom object, called a persistence delegate, to handle the process of writing out beans of a particular type.

The classes that inherit java.awt.Component or its descendents, automatically own persistence delegates. Otherwise, we can use a DefaultPersistenceDelegate instance or create our own subclass of PersistenceDelegate to support the scheme.

The JavaBean APIs are meant to be used by the bean editor, which provides the environment to customize and manipulate the properties of a bean component.

Some interfaces and classes commonly used are as follows.

Interface Description
AppletInitializer Methods of this interface are particularly useful for initializing applet beans.
BeanInfo This interface is used in the process of introspection about the events, methods, and properties of a Bean.
Customizer This interface helps in providing a GUI interface. This GUI interface may be used to manipulate and configure beans.
DesignMode Methods in this interface help in finding out if the bean is operating in the design mode.
ExceptionListener Methods of this interface are called when an exception occurs.
PropertyChangeListener A method of this interface is invoked when a bounded property change is triggered.
PropertyEditor A Java class that implements this interface is able to change and display property values.
VetoableChangeListener This is an event listener interface and contains a method for events to notify as soon as a constrained property is changed.
Visibility Methods in this interface helps the bean to execute in an environment where a GUI is unavailable.

 

 

Class Description
BeanDescriptor A BeanDescriptor provides global information about a “bean”, including its Java class, its displayName, and so on.
Beans This class provides some general purpose bean control methods.
PropertyChangeEvent A “PropertyChange” event gets delivered whenever a bean changes a “bound” or “constrained” property.
SimpleBeanInfo This is a support class to make it easier for people to provide BeanInfo classes.
VetoableChangeSuport This is a utility class that can be used by beans that support constrained properties.
Introspector The Introspector class provides a standard way for tools to learn about the properties, events, and methods supported by a target Java Bean.
EventHandler The EventHandler class provides support for dynamically generating event listeners whose methods execute a simple statement involving an incoming event object and a target object.
FeatureDescriptor The FeatureDescriptor class is the common baseclass for PropertyDescriptor, EventSetDescriptor, MethodDescriptor, and the like.
Statement A Statement object represents a primitive statement in which a single method is applied to a target and a set of arguments—as in “a.setFoo(b)”.

Refer to the java.beans package of the Java API Documentation for an extended list and more information.

A Quick Example

package greetbean;

import java.awt.Color;
import java.awt.Font;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.Serializable;
import javax.swing.JLabel;

public class GreetBean extends JLabel implements
   Serializable {

   private final String greet = "Hi there! ";
   transient private Color color;
   private final MouseHandler handler;

   public GreetBean() {
      handler = new MouseHandler();
      registerMouseEvents();
   }

   private void registerMouseEvents() {
      addMouseListener(handler);
      addMouseMotionListener(handler);
   }

   public String getGreet() {
      return this.getText();
   }

   public void setGreet(String greet) {
      this.setText(greet);
   }

   public Color getColor() {
      return color;
   }

   public void setColor(Color color) {
      this.color = color;
   }

   private void changeColor() {
      int red = (int) (255 * Math.random());
      int green = (int) (255 * Math.random());
      int blue = (int) (255 * Math.random());
      setColor(new Color(red, green, blue));
      setFont(new Font("Serif", 1, 14));
      setForeground(getColor());

   }

   private class MouseHandler implements MouseListener,
      MouseMotionListener {

      @Override
      public void mouseClicked(MouseEvent e) {
         setText(String.format(greet + " Mouse clicked at [%d,%d]",
            e.getX(), e.getY()));
         changeColor();
      }

      @Override
      public void mousePressed(MouseEvent e) {
         setText(String.format(greet + " Mouse pressed at [%d,%d]",
            e.getX(), e.getY()));
         changeColor();
      }

      @Override
      public void mouseReleased(MouseEvent e) {
         setText(String.format(greet + " Mouse released at [%d,%d]",
            e.getX(), e.getY()));
         changeColor();
      }

      @Override
      public void mouseEntered(MouseEvent e) {
         setText(String.format(greet + " Mouse entered at [%d,%d]",
            e.getX(), e.getY()));
         changeColor();
      }

      @Override
      public void mouseExited(MouseEvent e) {
         setText(String.format(greet + " Mouse exited at [%d,%d]",
            e.getX(), e.getY()));
         changeColor();
      }

      @Override
      public void mouseDragged(MouseEvent e) {
         setText(String.format(greet + " Mouse dragged at [%d,%d]",
            e.getX(), e.getY()));
         changeColor();
      }

      @Override
      public void mouseMoved(MouseEvent e) {
         setText(String.format(greet + " Mouse moved at [%d,%d]",
            e.getX(), e.getY()));
         changeColor();
      }

   }
}

Listing 1: GreetBean.java

package greetbean;

import java.awt.Image;
import java.beans.BeanDescriptor;
import java.beans.BeanInfo;
import java.beans.EventSetDescriptor;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.beans.SimpleBeanInfo;

public class GreetBeanInfo extends SimpleBeanInfo {

   private final static Class BEAN = GreetBean.class;

   @Override
   public PropertyDescriptor[] getPropertyDescriptors() {
      try {
         PropertyDescriptor greet = new
            PropertyDescriptor("greet", BEAN);
         PropertyDescriptor color = new
            PropertyDescriptor("color", BEAN);

         PropertyDescriptor[] pd = {greet, color};
         return pd;

      } catch (IntrospectionException ex) {
         throw new Error(ex.toString());
      }
   }

   @Override
   public BeanDescriptor getBeanDescriptor() {
      BeanDescriptor bd = new BeanDescriptor(BEAN);
      bd.setShortDescription("Customizable greetings bean");
      bd.setDisplayName("Greetings");
      return bd;
   }

   @Override
   public Image getIcon(int it) {
      if (it == BeanInfo.ICON_COLOR_16x16) {
         System.out.println("Getting image...");
         return loadImage("../images/icons16x16/icon.png");
      }
      return null;
   }

   @Override
   public EventSetDescriptor[] getEventSetDescriptors() {
      try {
         return Introspector.getBeanInfo(BEAN).getEventSetDescriptors();
      } catch (IntrospectionException e) {
         return null;
      }
   }
}

Listing 2: GreetBeanInfo.java

package greetbean;

import java.beans.BeanDescriptor;
import java.beans.BeanInfo;
import java.beans.EventSetDescriptor;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;

public class GreetBeanIntrospect {

   public static void main(String[] args) {
      try {
         BeanInfo info = Introspector.getBeanInfo(GreetBean.class);
         System.out.println("-------------PROPERTIES-----------------");
         for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
            System.out.println(pd.getName());
         }

         System.out.println("-----------BEAN DESCRIPTOR-------------");
         BeanDescriptor bd = info.getBeanDescriptor();
         System.out.println(bd.getDisplayName());
         System.out.println(bd.getShortDescription());

         System.out.println("--------------EVENTS----------------");
         for (EventSetDescriptor ed : info.getEventSetDescriptors()) {
            System.out.println(ed.getName());
         }

      } catch (IntrospectionException ex) {

      }

   }

}

Listing 3: GreetBeanIntrospect.java

Compile & Run

Once the jar file of the bean is created after compilation, run to see if the bean information such as properties, descriptors events, and so forth with the help of introspection mechanism (as described in GreetBeanIntrospect.java) is present.

However, you might want use the bean (after the jar is created) in an another application. It may be done in the following way:

Use NetBeans to Create a Java Application

  1. Include a JFrame form.
  2. Open the recently included JFrame in the design mode.
  3. Click Tools→Palette→Swing/AWT Components. A Palette Managerwindow will appear.

    Bean1
    Figure 1: The Palette Manager window

  1. Select Add from JAR…” or “Add from Project” appropriately and include GreetBean as shown above. Make sure to add the component in the palette category of beans in one of the subsequent windows that will appear. Lastly, close Palette Manager window.
  2. Observe that GreetBeanappears in the list of beans in the palette list of NetBeans IDE.

    Bean2
    Figure 2: GreetBeans appears in the list of beans

  1. Simple, drag and drop the bean in the JFrame, as shown in Figure 2.
  2. That’s it. Now, run the JFrame file and observe the color and text change as you move and click the mouse over the bean at runtime.

    Bean3
    Figure 3: Observing the color and text changing

Conclusion

Java beans are actually re-christened POJOs that are designed according to the component architecture defined by JavaBean specification. Software components leverage clean and reusable code and should be used under appropriate circumstances and not indiscriminately. This article provided a glimpse of the usage of JavaBean APIs and how they are actually implemented. Consult the Java API Documentation for details and information of the APIs and their usages.

References

Get the Free Newsletter!
Subscribe to Developer Insider for top news, trends & analysis
This email address is invalid.
Get the Free Newsletter!
Subscribe to Developer Insider for top news, trends & analysis
This email address is invalid.

Latest Posts

Related Stories