Hand-Coding with Beans

So far, we’ve seen how to create and use Beans within a Bean application builder environment. That is the primary role of a Java Bean in development. But Beans are not limited to being used by automated tools. There’s no reason we can’t use Beans in handwritten code. You might use a builder to assemble Beans for the user interface of your application and then load that serialized Bean collection in your own code. We’ll give an example of that in a moment.

Bean Instantiation and Type Management

Beans are an abstraction over simple Java classes. They add, by convention, features that are not part of the Java language. To enable these additional capabilities of JavaBeans we have to use some special tools that take the place of basic language operations. Specifically, when working with Beans, we need replacements for three basic Java operations: creating an object with new, checking the type of an object with the instanceof operator, and casting a type with a cast expression. In place of these, use the corresponding static methods of the java.beans.Beans class, shown in Table 19.1.

Table 19-1. Methods of the java.beans.Beans Class

Operator

Equivalent

New

Beans.instantiate(classloader, name)

Instanceof

Beans.isInstanceOf(object, class)

Explicit cast

Beans.getInstanceOf(object, class)

Beans.instantiate( ) is the new operation for Beans. It takes a class loader and the name of a Bean class or serialized Bean as arguments. Its advantage over the new operator is that it can also load Beans from a serialized form. If you use intantiate( ), you don’t have to specify in advance whether you will provide the Bean as a class or as a serialized object. This feature will become more important in the future; upcoming releases may allow the use of XML as an alternative serialization format for beans. If you use instantiate( ), you won’t care whether serialized objects are provided in the standard Java format, some new XML format, or something even newer that we haven’t heard of yet.

Beans.isInstanceOf( ) and Beans.getInstanceOf( ) do the jobs of checking a Bean’s type and casting it to a new type. In the future these methods may be used to let Beans take control of this behavior, providing different “views” of themselves.

Working with Serialized Beans

Remember the tip calculator we developed a few sections back? We asked you to serialize the BeanBox container and save it. As we mentioned earlier, BeanBox is a Bean itself. We can therefore pull the serialized BeanBox along with all of our previous work into another application and use it just as we had left it. We’ll assume that you saved the serialized BeanBox in a file called tipcalc.ser.

Compile the following small application:

//file: BackFromTheDead.java
import java.awt.Component;
import javax.swing.*; 
import java.beans.*; 
 
public class BackFromTheDead extends JFrame { 
 
  public BackFromTheDead( ) { 
    super("Revived Beans!"); 
    try { 
      Object bean = Beans.instantiate(  
        getClass().getClassLoader( ), "tipcalc" ); 
 
      if ( Beans.isInstanceOf(bean, Component.class) ) { 
        Component comp = (Component)
          Beans.getInstanceOf(bean, Component.class); 
        getContentPane( ).add("Center", comp); 
      } else {
          System.out.println("Bean is not a Component..."); 
      }
    }

    catch ( java.io.IOException e1 ) { 
      System.out.println("Error loading the serialized object");
    }

    catch ( ClassNotFoundException e2 ) { 
      System.out.println(
         "Can't find the class that goes with the object");
    } 
  } 
 
  public static void main(String [] args) { 
    JFrame f = new BackFromTheDead( );
    f.pack( );
    f.setVisible(true);
  } 
}

Run this program, making sure that all the BeanBox classes and associated JAR files, including our magicbeans.jar file, are in your class path. (We need only those classes since we are loading a BeanBox itself in this example—we don’t need them in general to load other serialized beans or collections of Beans.) You should see the restored BeanBox, just as you left it, as shown in Figure 19.10.

The restored BeanBox

Figure 19-10. The restored BeanBox

Note

At the time of this writing, there are some bugs in the BDK, which may prevent you from loading the serialized BeanBox as we described in the previous example. If you have trouble, just substitute another serialized bean in place of tipcalc.ser. (Use the Serialize Component command in the BeanBox to save one of the other Beans, rather than the BeanBox itself). The example will load and display any serialized Bean that is a kind of Component.

In BackFromTheDead, we use Beans.instantiate( ) to load our serialized Bean by name. Then we check to see whether it is a GUI component using Beans.isInstanceOf( ). (It is, because the BeanBox itself is a subclass of java.awt.Panel.) Finally, we cast the instantiated object to a Component with Beans.getInstanceOf( ) and add it to our application’s JFrame. Notice that we still need a static Java cast to turn the Object returned by getInstanceOf( ) into a Component. This cast may seem gratuitous, but it is the bridge between the dynamic Beans lookup of the type and the static, compile-time view of the type.

One important question remains: how does instantiate( ) find a Bean using the argument tipcalc? First, it appends the extension .ser to form the filename tipcalc.ser. If it can find this file anywhere along the class path, it loads it as a serialized Bean. It also needs the serialized Bean’s original .class file; the name of that file is included in the serialized object and usually doesn’t have any relation to the name of the serialized object. (In this case, instantiate( ) would look for BeanBox.class and the classes for the components in the BeanBox.)

If the .ser file doesn’t exist, instantiate( ) appends .class to the name (in this case, yielding tipcalc.class) and looks for a class file. In this case, instantiate( ) instantiates the Bean like any other object—that is, with the new operator.

Get Learning Java now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.