Delphi Clinic C++Builder Gate Training & Consultancy Delphi Notes Weblog Dr.Bob's Webshop
TDMWeb Kylix Developer's Guide
 JBuilder Java BeansExpress
See Also: JBuilder Papers
by Bob Swart with Hubert A. Klein Ikkink

JavaBeans creation and deployment made easy with JBuilder Java BeansExpress

It's no big secret that I'm a Delphi adict, especially when it comes to VCL Component Building. However, just like Delphi VCL components (who can also be used in C++Builder) and ActiveX controls, it's crystal clear to me that JavaBeans can truly become the components of the future. In fact, as long as they're 100% pure java, JavaBeans can be used in any Java development environment and on any Java supporting Virtual Machine (VM).
In this article we'll see how we can create 100% pure java components, and write our own JavaBeans using Borland JBuilder's Java BeansExpress. First we start doing JavaBeans "the hard way" (i.e. without special support), using the BeanBox to test them. Then, we move on to JBuilder support: Java BeansExpress code snippets and skeletons. And finally, we'll see the enhanced JavaBean support from JBuilder 2 and 3, where we don't have to write any code anymore, and can use Wizards and Dialogs to create the entire JavaBeans code for us.
While you may want to skip to the JBuilder 3 section right away, I personally think it's very important to know how JavaBeans can be written by hand, and what the specific syntax rules are. Once you know "the hard way" to write JavaBeans, you'll be able to truly appreciate the extensive support JBuilder offers us...
Finally, we can use the BeanInsight Wizard to get more detailed information from new and existing JavaBeans (something that will be shown in detail during the session).


0.  Java BDK BeanBox
Before we start to write our first JavaBean, let's first take a look at another basic but useful tool we'll need lateron to test and be able to manipulate JavaBeans without actually having to write a whole new applet or application with them. For this purpose, Sun has included a Bean manipulation program called "BeanBox" in the Beans Development Kit (BDK), which can be obtained from Sun's website or from the CD-ROM of any serious Java or JavaBean book (like Michelle M. Manning's "Teach Yourself Borland JBuilder in 21 Days", published by Sams.net, includes the BDK, for example). For more information about the BDK, BeanBox and JavaBeans in general, you should check out the official JavaBean specification on Sun's website.

The BeanBox in action - as you can see right above - consists of a ToolBox window, which lists all the JavaBeans loaded (in our toolbox) and available for manipulation. The BeanBox itself is a window in which to drop and move/resize the JavaBean itself, while a third window lists the Properties for the currently selected JavaBean - in this case the properties for the ExplicitButton bean. If we click on the value of one of the properties, we may get a Property Editor, in this case for the foreground color.

Of course, this is just a simple example, but it should nevertheless be clear that the BeanBox is a helpful tool for a quick and easy test of new JavaBeans.
In the remainder of this session, however, it will become clear that JBuilder offers even more support for loading and testing JavaBeans, so let's move on to JBuilder now...

JavaBeans
The concept of JavaBeans gives us the ability to create reusable Java software components, that can be used by any Java development environment. Unlike Delphi and C++Builder VCL components, there is no "Bean" base class from which to inherit a JavaBean from; any java class that confirms to the definition is considered a JavaBean. The definition is quite simple: a JavaBean is a public class that includes a public default constructor (with no arguments). A JavaBean can also export properties, events and methods.
The BeanBox, and other Java development environments (such as JBuilder), are able to examine any (unknown) JavaBean and extract information from it to determine the exported properties, methods and events. This process of obtaining information about members of the class is also called "introspection". Additionally, a JavaBean can provide an auxiliary BeanInfo class to provide even more information about the internals of the JavaBean.

Properties
Properties define the attributes of our JavaBean. For example, the backgroundColor property describes the color of the background of the JavaBean.
JavaBean properties can have both a read and a write access method, also known as the getter and setter. A getter method returns the current value of the property; a setter method sets the property to a new value.
Apart from regular properties, JavaBeans can also have indexed (array) properties, and bound or restricted properties.

Events
JavaBeans events come in two flavours: events to fire (from within our JavaBeans) and events to listen to (being fired by others to our JavaBean). The syntax to these events is actually quite complex, and therefore I'd like to propose that we delay looking at the syntax specifics until we have experienced the power of the Java BeansExpress Wizard of JBuilder 3, which is now able to automatically generate the code for events-to-be-fired as well as events-to-listen-to.


1.  JBuilder: BeansExpress
Before we really start building JavaBeans with JBuilder, first of all a little reminder: using JBuilder we can only add a JavaBean to an open project, so first we need to start an empty project (like a Panel as "underground" for our new JavaBean) or open an existing project to work with.
Then, we can select File | New and go to the BeansExpress tab:

As we can see, a number of example JavaBean skeletons and tools are already available here, such as the Ok Cancel Bean which demonstrates how a compound UI component can be structured from existing components and the DB Bean for database UI JavaBeans, with which we can browse a database for example. Bean Info can be used to create a BeanInfo class to correspond with an existing class in the current project (to provide more information about the internals of a JavaBean, as we saw earlier), and finally New Event Bean can be used to create a new event.
During the session at the conference I may show one or more examples of these JavaBean skeletons as well. But let's just click on New Bean for now, which results in a new JavaBean component added to our current project. JBuilder BeansExpress automatically creates the NewBean class that is added to our project. If we click on the Design tab in the JBuilder IDE, we can drag and drop existing components (beans) on the Panel to create the UI and behaviour that we want the JavaBean to have.

First Example
Let's drop a Label (label1) and a TextField (textField1) on the panel, and create a new control that consists of the Label on the left and the TextField on the right. Such a combination is useful in many situations, and always helpful to have (it avoids having to align the controls manually, for example).
We may want to expose the actual text of the Label as a property to the outside world (i.e. the developer at design-time), so it can be set and changed from within a Java development environment (or the BeanBox, for example). This means we have to specify a new property. Fortunately, the Java BeansExpress already provides us with an example property, named "example" of the type String. All we need to do is change the name from "example" to "label" in order to illustrate that the property is meant to set the text of the (internal) Label bean.

  // Example properties
  private String label = "Example label";

  public void setLabel(String s)
  {
    label = s;
    label1.setText(label);
  }
  public String getLabel()
  {
    return label;
  }
Note that the "label" property is private, but connected to the internal "label1" bean by using a pair of getLabel and setLabel methods.

Test
Now that we've finished coding our first JavaBean, it's time to build the Bean and check and fix our syntax errors. Select Build | Rebuild "LabelTextfield.java" . If you don't get a clean compile, check your JavaBean source code against the following:

package drbob42.bean;

import java.awt.*;
import java.awt.event.*;
import borland.jbcl.layout.*;
import borland.jbcl.control.*;
import borland.jbcl.view.*;
import borland.jbcl.util.BlackBox;

public class LabelTextField extends BeanPanel implements BlackBox {
  BevelPanel bevelPanel1 = new BevelPanel();
  BorderLayout borderLayout1 = new BorderLayout();
  Label label1 = new Label();
  TextField textField1 = new TextField();
  GridLayout gridLayout1 = new GridLayout();

  public LabelTextField()
  {
    try
    {
      jbInit();
    }
    catch (Exception ex)
    {
      e.printStackTrace();
    }
    setLabel("Example label text");
  }

  private void jbInit() throws Exception
  {
    this.setSize(new Dimension(351, 25));
    gridLayout1.setColumns(2);
    bevelPanel1.setLayout(gridLayout1);
    this.setLayout(borderLayout1);
    this.add(bevelPanel1, BorderLayout.CENTER);
    bevelPanel1.add(label1, null);
    bevelPanel1.add(textField1, null);
  }

  // Example properties
  private String label = "Example label";

  public void setLabel(String s)
  {
    label = s;
    label1.setText(label);
  }
  public String getLabel()
  {
    return label;
  }
}
Once we get a clean compile, we can deploy and install our new JavaBean in the JBuilder Component Palette (see also the "JBuilder 3" section), or test it in the BeanBox as can be seen below:

Note that apart from the font, the foregound/background color and the name of the Bean, we also see the published property "label", which corresponds to the text of the Label sub-Bean in the combined LabelTextField. However, since we only published the "label" property, it's not possible, for example, to access the contents (the text) of the TextField sub-Bean. So we are in effect unable to set or modify the text of the TextField inside this new JavaBean.
Of course, it's really easy to fix this problem; we just have to publish another property of type String, this time connected to the text property of the TextField sub-Bean. Since this involves no new steps, I leave it as an excercise to the reader.

Data-Aware Example
As another example (similar to the "DB Bean" code snippet), drop a navigatorControl (borland.jbcl.control.NavigatorControl) and a gridControl (borland.jbcl.control.GridControl) on the Panel, and make sure the navigatorControl is on top and the gridControl is right under it. These two form a new JavaBean combination that might be quite useful to have for quick inspection of the contents of a database. And although this particular example has been done many times, it is still very insightful to see how to connect the two sub-JavaBeans together, and "publish" a single property to the outside world, as we'll see shortly.
Of course, at this time, both the navigatorControl and the gridControl have a separate dataSet property. So, in order to really integrate these JavaBeans into one new JavaBean, we must make one dataSet property with a Get and Set method that internally links to the dataSet property of the navigatorControl and the gridControl.

Fortunately, the JBuilder Java BeansExpress (using the "New Bean" code snippet) has again created an example property for us, named example (of type String). We can use this example code again, and modify it for our own needs to represent the required dataSet property as follows:

  // new JavaBean property
  private DataSet dataSet;

  public void setDataSet(DataSet s)
  {
    dataSet = s;
    navigatorControl1.setDataSet(s);
    gridControl1.setDataSet(s);
  }
  public DataSet getDataSet()
  {
    return dataSet;
  }
This time, we need to add one more line:
  import borland.jbcl.dataset.DataSet;
To ensure that we can actually use the jbcl.dataset.DataSet type in our new JavaBean (without compiler errors).

Note that the dataSet property itself is private, so users of this JavaBean must access it through the public getDataSet and setDataSet methods. This ensures us that whenever the value of dataSet is changed, the setDataSet method must be called, which takes care of setting the dataSet values for the navigatorControl and gridControl at the same time.

Now that we've finished coding our second JavaBean, it's time to build the Bean again and check and fix our syntax errors. Select Build | Rebuild "LabelTextfield.java" . Once we get a clean compile again, we can deploy and install our new JavaBean in the JBuilder Component Palette.
But before we actually do that, let's see how JBuilder 2 and 3 extend the support for writing JavaBeans even further...


2.  JBuilder: JavaBean Wizard
Apart from the BeansExpress tab, JBuilder 3 also features a JavaBean Wizard which will generate a JavaBean skeleton for us. Just select File | New and select the first icon in the New tab to start the "JavaBean" Wizard:

Note the icon to generate an Enterprise JavaBean (for Enterprise JavaBeans, please check out the BorCon98 pre-conference tutorial by Hubert Klein Ikkink).
Since we didn't start with an existing open project, we need to create a new one, so in that case the Project Wizard is started for (and before) the JavaBean Wizard.

The JavaBean Wizard offers us a few choices to specify the initial skeleton source code. Specifically, we see that we can select the base class to inherit our new JavaBean from (from a drop-down combobox), and we can even decide to only list the core JDK and swing classes (so we don't need to deploy lots of other classes and frameworks).
After we selected the options and click on the OK button, the Wizard will disappear and a new project is opened with the initial Java source code for Bean1. Note that this code will be dynamically generated, and not simply copied from source code snippets as the JBuilder JavaBeans express did before.

In the screenshot below, there are a number of tabs below the source code editor that require our attention. The current tab ("Source") shows the source code of the JavaBean. We can always go back here to see what has been generated so far (but note that we don't need to write a single line of Java code from now on).
The second tab ("Design") shows the visual design of the JavaBean. This is the place where we can drag-and-drop other JavaBeans (like the label and textField, or the navigatorControl and gridControl).
The third tab ("Bean") is the most important tab for the remainder of this article. This is the place where we can customise the generate JavaBean.
The last tab ("Doc") is the place where the JavaBean documentation will end up. To learn more about the way how JBuilder uses documentation files generated by JavaDoc, check out the new JavaDoc Wizard and Hubert Klein Ikkinks article entitled Create documentation for your own Java classes, also published on Mr.Haki's JBuilder Machine.

Like I said, the third tab ("Bean") is the place where we can customise the generate JavaBean. There are five sub-tabs, with "general" options, "properties", "BeanInfo", "events" and finally a place to specify "property editors".

In the general page, we can specify if our JavaBean should Support Serialization. This means that our JavaBean has the ablity to read and write itself from and to a stream. Quite useful if you want to store the values of properties (i.e. persistence).

Moving on to the "Properties" tab, we see the good-old sample property of type String listed here. Also note the getSample() and setSample(String) methods in the lower-left pane of the IDE here:

If we click on the "Add Property" button, we can specify the name and type of a new property, including the type of this property (note that it seems that JBuilder only supports regular, bound and restricted properties, but no indexed properties. Actually, it does support them, but just doesn't generate the source code for them).
Let's specify a property called "Hubert" (the name of my co-webmaster) of type String, with a Getter and Setter method, meaning we can read and write the property value from a (visual) Java development environment like JBuilder.
Once we click on the OK button, new source code will be added to the JavaBean (check the "Source" tab to see the results), and the list of properties will be updated accordingly.

Apart from adding new properties, we can also remove exising properties when we click on the "Remove Property" button (to remove the currently selected property).
Once we click on the OK button (why don't we get a "Yes" and "No" button instead of an "OK" and "Cancel" button here?) the property and source code will be removed, and the list of properties will be updated accordingly.

After having added a new String property named Hubert and having removed the Sample property, the list of properties is listed as follows. Note the new getHubert() and setHubert(String) methods.

The third sub-tab of the "Beans" tab gives us the ability to add "BeanInfo" to our new JavaBean. Here, we can generate BeanInfo, specify a Display name and short description, and even specify the icons to use when we install the new JavaBean in the JBuilder Component Palette, for example.

The fourth sub-tab called "Events" is the one I promised you earlier in this session. This is the place where JBuilder 3 shines very brightly. Here, we get two columns of events. One for events that our JavaBean can fire, and one for events that our JavaBean needs to listen to:

All we need to do is click on any of the checkboxes, and JBuilder 3 will automatically generate the event source code.
For example, if we click on the "Action" event in the "Fire these types of events" column, we can see that a number of methods have been added to the source code (also compare the left panes of the above and below screenshot):

Specifically, if we go back to the "Source" tab, we see the generated source code for the methods removeActionListener, AddActionListener and fireActionPerformed:

Similary, we can click on the Focus event in the "Listen to these types of events" column, which will result in the focusGained and focusLost methods, as can be seen already in the left pane:

In the "Source" tab, we can enter our own custom event handling code in the implementation section of these two events handlers:

JavaBean Deployment
We can optionally decide to deploy our new JavaBean using the Deployment Wizard. Select Wizards | Deployment Wizard , set the selection to our NewBean.java file and click on Finish (we can exclude the JBCL and JGL classes if we're sure they're already installed on the target machine):

Note that we can create ZIP and JAR files, both normal and compressed (it may take some time to compress them).

JBuilder Component Palette
To place our new JavaBean onto JBuilder's Component Palette, we need to select Tools | Configure Palette | Add from Package. We can either add a JavaBean from a package (Zip or JAR) or from a source package. In this case, let's just add our Untitled1.jar jar archive, select the untitled1.Bean1 JavaBean, and click on Install:

... and now we have our new JavaBean on our component Palette:

JBuilder JavaBean Usage
We can use the new JavaBean from the Component Palette in a new project, just like any other JavaBean:

Finally, we can use the BeanInsight Wizard to get more detailed information from new and existing JavaBeans (something that will be shown in detail during the session).


Conclusion
JavaBeans are the building blocks of Java applets and applications. Building JavaBeans is a serious task, for which JBuilder 3 offers great support with the Java BeansExpress Wizard, Code Snippets and the "Bean" Dialogs.
From properties to events, installation, deployment and usage, JBuilder 3 brings us the best there is in JavaBean development.


This webpage © 1997-2010 by Bob Swart (aka Dr.Bob - www.drbob42.com). All Rights Reserved.