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.
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 |
---|---|
|
|
|
|
Explicit cast |
|
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.
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.
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.