The following steps can easily be adapted to converting any Java
program or applet into a Bean.
Step 1. Select program to convert
First, select a demo applet or class to convert to a Bean.
For this particular example, you'll be using NervousText.
Step 2. Change applets to standalone Window objects
While it's possible to make applets into Beans, it's a little easier to
convert standalone Window objects or components. To see
an example of an applet that is a Bean, look at the source code for
the Juggler Bean distributed with the Beans Development Toolkit (BDK).
To change NervousText into a standalone window object,
edit the line declaring the NervousText class. In the JDK 1.1
distribution, it reads
public class NervousText extends java.applet.Applet
implements Runnable {
Instead of making NervousText a subclass of Applet, make it a subclass
of Panel:
public class NervousText extends Panel
implements Runnable {
Step 3. Add AWT and Beans import
and package
statements
Add the following important statement after import java.awt.Font;
:
import java.awt.*;
There are many ways to bundle a Bean to be loaded into the
BeanBox, or to be loaded by other builder tools. The most effective
way to manage the different Beans you'll be creating is to define
them to be part of a package, and then build a JAR file based on
the directory structure implicitly defined by the package name.
Since you're going to be testing the various versions of the
NervousText Bean in the BeanBox, you'll need to add a package
statement indicating the location of the Java class files that make up
the Bean. The package reflects the subsystem where you plan
to store your class files locally, and not necessarily where the
BeanBox expects to find the actual class files. Once you have bundled
the set of classes making up a Bean in a JAR file, you can place the
JAR file in the default location where the BeanBox looks for JAR files
when the BeanBox is initialized. The demo Beans for the NervousText
example Beans in this lesson are declared as part of the
sun.beanbox.beans
package.
You could define your own package and corresponding
subdirectories, but it's convenient to use this package. Add
the following package statement before the first import
statement, import java.awt.Graphics;
:
package sun.beanbox.beans;
The beginning of the file should now look like this:
package sun.beanbox.beans;
import java.awt.event.*;
import java.awt.Graphics;
import java.awt.Font;
import java.awt.*;
public class NervousText01 extends Panel implements
Runnable, MouseListener {
...
Step 4. Add a constructor
When converting applets to Window objects, you no longer need the
init
method, but you will need a constructor, if one is
not already defined. In the case of NervousText, you can change
the line declaring the
init
method to a constructor, by renaming the
method and removing the return type from the method declaration. Change:
public void init() {
to:
public NervousText() {
The constructor now looks like this
public NervousText() {
addMouseListener(this);
s = getParameter("text");
if (s == null) {
s = "HotJava";
}
separated = new char [s.length()];
s.getChars(0,s.length(),separated,0);
resize((s.length()+1)*15, 50);
setFont(new Font("TimesRoman",Font.BOLD,36));
}
Step 5. Adapt applet parameters
Since NervousText is no longer an applet, it can't call getParameter
to get the text it is going to display. In some cases you'll have
to add a line or two to hard code parameters that were formerly
passed to applets. In the case of NervousText, you'll see a
conditional test that hard codes the text displayed in the
event that a parameter argument is not supplied.
if (s == null) {
s = "HotJava";
}
By commenting out the line immediately preceding this, you'll
assure that the value of s
is always set to
"HotJava".
public void init() {
...
// s = getParameter("text");
if (s == null) {
s = "HotJava";
}
...
}
Step 6. Start the component's thread
When NervousText was an applet, its start method was called
automatically by the browser (or appletviewer) whenever a page
referencing the applet was loaded. The start method invokes
the primary thread for the applet or, in this case, the
Window Object. You'll have to call start manually to
set its thread running
Add the following line at the end of constructor NervousText, just
after setFont
statement.
start();
The constuctor should now look like this:
public NervousText01() {
addMouseListener(this);
// s = getParameter("text");
if (s == null) {
//s = "HotJava";
s = "Nervous bean";
}
separated = new char [s.length()];
s.getChars(0,s.length(),separated,0);
resize((s.length()+1)*15, 50);
setFont(new Font("TimesRoman",Font.BOLD,36));
start();
}
Step 6. Add properties and support for introspection
It would be nice if users of the NervousText Bean could customize the
text it displays when they are building new applications. You can
enable builder tools to give users the option to change the text
displayed by NervousText by adding a text property. Adding the methods
getText
and setText
allows you to change the
String value of the jittering text. Add these methods after the
NervousText
constructor.
public void setText(String newstring){
s=new String(newstring);
separated= new char[s.length()];
s.getChars(0,s.length(),separated,0);
}
public String getText(){
return(s);
}
Step 7. Define preferred size and minimum Size for the Bean
Strictly speaking, you do not need to define both preferredSize and
minimumSize call back methods for the Bean. If these methods are
defined, builder tools (such as the BeanBox) will call them to
determine how the Bean should be drawn. Add
a preferredSize method to indicate the initalial size of the Bean.
The difference between preferredSize and minimumSize is that
if minimumSize is defined and preferredSize is not, the size of
the Bean can be changed later on inside the builder tool. If
preferredSize is set, the Bean will remain a fixed size. You'll
see an example version of NervousText using minimumSize later in
the lesson.
The Bean's preferredSize is called from the BeanBox at
the time a user selects the Bean from the menu of
available Beans to be placed in the top-level container.
Add the following preferredSize
code after the
gettext
method that you just added.
public Dimension preferredSize() {
return (new Dimension(150,150));
}
Step 8. Remove extraneous event handlers
Some event-handler routines that make sense for applets, no longer
make sense once the applet is turned into a Bean. Within
NervousText, comment out the mouseDown
action
event handler as it will interfere with the operation of the BeanBox.
public void mousePressed(MouseEvent e) {
/*
e.consume();
if (threadSuspended) {
killme.resume();
}
else {
killme.suspend();
}
threadSuspended = !threadSuspended;
*/
}
Now the mouse-down handler is defined, but it no longer performs any
action. Specifically, a mouse-down event no longer kills the thread
and stops the nervous text from jittering.
Step 8. Test the Bean in the BeanBox
You can now add the NervousText component from the Toolbox into the
panel and change the text parameter in the PropertySheet automatically
associated with the Bean by the builder tool.
If you have a full Beans-enabled development environment,
such as JBuilder, or Mojo, you can test your Bean using them.
If not, you can use the BeanBox. When using the BeanBox, it is
easiest to package the Bean as a JAR (Java Archive File) and then
load the JAR into the BeanBox. To do this you have to use a manifest
file to define the contents of the JAR so the BeanBox or builder tool
knows how to use each of the files contained in the JAR. For example,
the following commands will create a temporary manifest file,
which can be used to build a JAR file.
echo "Manifest-Version: 1.0" > manifest.tmp
echo "" >> manifest.tmp
echo "Name: sun/beanbox/beans/NervousText01.class"
>> manifest.tmp
echo "Java-bean: True" >> manifest.tmp
jar cfm NervousText01.jar manifest.tmp
sun/beanbox/beans/NervousText01.class
/bin/rm manifest.tmp
cp -p NervousText01.jar
/home_gvoss/work97/06/bdk/beans/jars
The resulting manifest file looks like this:
Manifest-Version: 1.0
Name: sun/beanbox/beans/NervousText01.class
Java-bean: True
This manifest indicates the JAR contains a single Java class
file, NervousText01.class which is a Bean. You know that the
class is a Bean because of the following line in the manifest:
Java-bean: True
Assuming you have installed the Beans Development Kit (BDK) in
a directory defined as BDK_HOME, the BeanBox will look in a
directory called BDK_HOME/beans/jars
for the JARS defining the initial Beans it will display in
its Bean menu.
Compile the source with the -d flag to make sure classes are
placed in the proper subdirectories for the package.
javac -d . NervousText01.java
The dot following the -d
flag indicates the the package root is the
current directory. The class file for the package
sun.Beanbox.beans
will be created in the ./sun/beanbox/beans
directory. When the class is compiled and the manifest is created,
build the the JAR as follows.
jar cfm NervousText01.jar manifest.tmp
sun/beanbox/beans/NervousText01.class
You can now remove the temporary manifest file and copy the JAR file
to the JAR directory for the BeanBox.
rm manifest.tmp
cp -p NervousText01.jar BDK_HOME/beans/jars
After copying the JAR file to the BeanBox jars directory, you
can start the BeanBox and NervousText01 will appear in the menu
of available Beans.
Program Source Code
The makefile
for this lesson automates source code
compilation, JAR file construction, and copying of JAR files to the
appropriate BeanBox directory. You'll have to edit several of the
variables in the makefile to indicate the location of your JDK 1.1
and BDK installation directories.
You may want to look at the final source file for
NervousText Bean, Version 01
to verify the changes you have made to the original NervousText.java
file.