Using the Data Toolbox Controls

While the app Wizard was easy to use, the output was less than spectacular in appearance and difficult to customize. Another approach is to use the DataSource and DataBinder objects contained in the WFC Controls section of the Toolbox.

The manual approach presented at the beginning of this chapter allowed you to completely control output, but it was difficult to program. The completely automated app Wizard approach was easy to use, but inflexible in its output. The Toolbox method shown here is a compromise. While slightly more complicated than the fully automated approach, it's much simpler than the totally manual method and still allows you almost total control of the output.

Problem

The problem this demonstration app solves is similar to the problem solved by the ManualADO app: allow the user to navigate back and forth through the Customers table using two buttons. Because of the way that the DataBinder object works, however, this time the ContactFirstName, ContactLastName, and PhoneNumber fields must appear in separate edit boxes as they did in the AutoADO example.

Forms Designer Work

The Forms Designer work for this app consists of two different types of tasks. The first type of forms work involves the manipulation of conventional controls; the second type involves the DataSource and DataBinder controls.

Conventional controls

Create a normal Windows app project (don't use the app Wizard this time). Name the project ToolboxADO. Open the Form1.java file in the Forms Designer.

Rename the form by changing the text property to Toolbox ADO. Now add three Label controls containing the text Customer First Name, Customer Last Name, and Telephone Number. Place the labels so they are equally spaced vertically and aligned horizontally on the left side of the form.

Add an Edit control to the right of each label. Align the three Edit controls horizontally. Name them firstNameEdit, lastNameEdit, and phoneNumberEdit. Set the readOnly property to true for each.

Add two buttons below the Label and Edit controls. Label the left button Previous and change its name property to previousButton; label the right button Next and change its name property to nextButton. Double-click each button to create the event handlers that we'll need later.

Resize the form until it accommodates the controls without excessive space on either side. This time, as a change, rather than anchor the controls to the different edges of the form, set the form's borderStyle property to Fixed Toolwindow. This will retain the appearance of the form by rendering it nonresizeable.

Creating a file DSN

It's easier to define a DSN to which the DataSource object can refer before you start creating the DataSource object. To create a DSN, start by opening the Windows Control Panel.

Double-click the ODBC (32bit) icon to bring up the ODBC Data Source Administrator. Select the User DSN tab, and select MS Access 97 Database as the type of DSN to create.

Now select the File DSN tab. Select the Add button to create a new DSN for our database. The first window to appear is the Create New Data Source window, which lists all of the ODBC Data Drivers that are installed on your system. Select Microsoft Access Driver (*.mdb); this is the ODBC driver for .mdb files like ours. (If this driver isn't available, it's because you didn't select it when you installed Visual J Plus Plus.) Choose Next and enter MyCompany.dsn as the name of the DSN to create. Now choose Next to see a summary of your choices, and then choose Finish to complete the creation of the DSN.

An Access DSN must be attached to an Access database. After you've created the DSN, the ODBC Microsoft Access 97 Setup window appears. Choose Select to specify the database file to attach to this DSN. Use the Select Database window to navigate to MyCompany.mdb, as shown in Figure 12-7. Choose MyCompany.mdb and then choose OK to attach the database to the DSN.

Screenshot

Screenshot-7. The Select Database window of the ODBC Microsoft Access 97 Setup editor.

Finally, choose OK to close the ODBC Microsoft Access 97 Setup window.

You can now see on the File DSN tab of the ODBC Data Source Administrator that MyCompany.dsn has been defined. Choose OK to close the ODBC Data Source Administrator. You can now close the Control Panel.

DataSource control

Drag a DataSource control from the Toolbox and drop it onto the form. (The data controls are at the bottom of the WFC Controls list of Toolbox controls.) Rename the object to dataSource.

Click the three dots to the right of the connectionString property to display the Data Link Properties window. Now choose the Provider tab. From the OLE DB Provider(s) list, select Microsoft OLE DB Provider For ODBC Drivers. On the Connection tab, choose the Use Connection String option. Now choose the Build button to reveal a list of DSNs, including MyCompany.dsn, in the Select Data Source window. Select MyCompany.dsn and choose OK. The ODBC Microsoft Access 97 Setup window is displayed again, giving you a second chance to select a database. Since you've already attached a database to the DSN, choose OK to close the window.

Before exiting the Data Link Properties window, you should choose the Test Connection button on the Connection tab to test the connection to the MyCompany.mdb database. If the connection is good, a message box appears indicating that the test connection succeeded. With the connectionString property setting established, select OK to exit the Data Link Properties window.

Now choose the commandText property and enter the following SQL command:

SELECT ContactFirstName, ContactLastName, PhoneNumber FROM Customers

DataBinder control

Drag a DataBinder control from the Toolbox and drop it onto the form. Rename the object to dataBinder. Change the dataSource property to dataSource.

NOTE
You can use the drop-down list for the dataSource property and select from a list (of one) of data sources defined in the form.

To set up the data bindings, click the value box for the bindings property. Click the three dots to the right of the box to open up the DataBinding Editor. Choose the Add button three times to add three data bindings, and then choose OK. (The DataBinding Editor is really not much of an editor—it's more of a creator. The editing is done back in the Properties window of the DataBinding object.)

You'll notice that the bindings property has a plus sign to its left. Choose the plus sign to reveal the three binding objects. Click the plus sign for each binding object (not the plus sign in front of the All property) to reveal its properties. Under the binding0 property, click the fieldName property. Notice that a small arrow appears in the value field immediately to the right. Click the arrow to reveal the field names within the Customers table. Select ContactFirstName. Now click the target property. From the drop-down list, select firstNameEdit. Finally, select text as the propertyName. Repeat the process for binding1, this time selecting ContactLastName, lastNameEdit, and text. Repeat the process one last time for binding2 by selecting PhoneNumber, phoneNumberEdit, and text.

When you're finished, your dataBinder Properties window should look like Figure 12-8.

Screenshot

Screenshot-8. The completed properties for the DataBinder object for the ToolboxADO app.

NOTE
As you create each binding, the corresponding value for the first record in the database appears in the form's Edit control. For example, as soon as you tie the ContactFirstName field to the firstNameEdit object and set the text property, the name Stephen appears in the top Edit control.

Test the controls

Before continuing any further, test the data controls you have established by saving, compiling, and executing the ToolboxADO app. The program should display the first record in the database, as shown in Figure 12-9.

Screenshot

Screenshot-9. The ToolboxADO app with the Toolbox data controls established.

Building the event handler methods

Open the form in the Forms Designer again. Open the active properties of the Properties window. Now select the phoneNumberEdit object and double-click the textChanged property. The resulting method will read the contents of the phoneNumberEdit object whenever the contents change, and update the value to the standard U.S. (xxx) xxx-xxxx format.

Code

With the Toolbox data controls doing most of the work, all that is left is to write the button event handlers to call Recordset.moveNext() and Recordset.movePrevious(), and the phone number display code, much like we did back in ManualADO:

import com.ms.wfc.app.*;
import com.ms.wfc.core.*;
import com.ms.wfc.ui.*;
import com.ms.wfc.data.*;
import com.ms.wfc.data.ui.*;
/**
 * This class can take a variable number of parameters on the command
 * line. Program execution begins with the main() method. The class
 * constructor is not invoked unless an object of type 'Form1' is
 * created in the main() method.
 */
public class Form1 extends Form
{
 public Form1()
 {
 // Required for Visual J Plus Plus Form Designer support
 initForm(); // make sure that the first field is updated
 phoneNumberEdit_textChanged(null, null);
 }
 /**
 * Form1 overrides dispose so it can clean up the
 * component list.
 */
 public void dispose()
 {
 super.dispose();
 components.dispose();
 }
 /**
 * Update the phone number passed in as a string to appear
 * in the standard U.S. format of (xxx) xxx-xxxx.
 */
 private String updatePhone(String s)
 {
 // if it's not the right number of digits
 // (including if it's already been updated)…
 if (s.length() != 10)
 {
 // then don't update
 return s;
 }
 // break the phone number up into parts
 String s1 = s.substring(0, 3);
 String s2 = s.substring(3, 6);
 String s3 = s.substring(6, 10);
 // now put it back together again with punctuation
 s = "(" + s1 + ") " + s2 + "-" + s3;
 // and return to caller
 return s;
 }
 /**
 * Navigate backward in the Customers table.
 */
 private void previousButton_click(Object source, Event e)
 {
 // get the recordset
 Recordset rs = dataSource.getRecordset();
 // if the database is empty…
 if (rs.getDataMemberCount() == 0)
 {
 // return without action
 return;
 }
 // move to the next record
 rs.movePrevious();
 // if at end-of-file…
 if (rs.getBOF())
 {
 // move back to the first record
 rs.moveFirst();
 }
 }
 /**
 * Navigate forward in the Customers table.
 */
 private void nextButton_click(Object source, Event e)
 {
 // get the recordset
 Recordset rs = dataSource.getRecordset();
 // if the database is empty…
 if (rs.getDataMemberCount() == 0)
 {
 // return without action
 return;
 }
 // move to the next record
 rs.moveNext();
 // if at end-of-file…
 if (rs.getEOF())
 {
 // move back to the last record
 rs.moveLast();
 }
 }
 /**
 * Invoked when the phone number edit box is updated by the
 * DataBinder; update the phone number to the (xxx) xxx-xxxx format.
 */
 private void phoneNumberEdit_textChanged(Object source, Event e)
 {
 // get the contents of the phone number edit box
 String s = phoneNumberEdit.getText();
 // update the phone number s = updatePhone(s);
 // and put it back into the edit box
 phoneNumberEdit.setText(s);
 }
 /**
 * NOTE: The following code is required by the Visual J Plus Plus form
 * designer. It can be modified using the form editor. Do not
 * modify it using the code editor.
 */
 Container components = new Container();
 Label label1 = new Label();
 Label label2 = new Label();
 Label label3 = new Label();
 Edit firstNameEdit = new Edit();
 Edit lastNameEdit = new Edit();
 Edit phoneNumberEdit = new Edit();
 Button previousButton = new Button();
 Button nextButton = new Button();
 com.ms.wfc.data.ui.DataSource dataSource = new com.ms.wfc.data.ui.DataSource(components);
 com.ms.wfc.data.ui.DataBinder dataBinder = new com.ms.wfc.data.ui.DataBinder(components);
 private void initForm()
 {
 // …create by Forms Designer…
 }
 /**
 * The main entry point for the app. *
 * @param args Array of parameters passed to the app
 * via the command line.
 */
 public static void main(String args[])
 {
 app.run(new Form1());
 }
}


ToolboxADO.java must import the wfc.data and wfc.data.ui packages—in addition to those packages already imported by the Windows app Wizard—in order to gain access to the DataBinder and DataSource classes. The program accesses the Customers database table through the DataSource class. The connection between the DataSource class and the database was established when we added the DataSource control to the app form in the Forms Designer and initialized the control. The connection between the DataSource control and the individual fields was created by the DataBinding control, which also came from the Toolbox.

The updatePhone() method here is identical to the updatePhone() method in the ManualADO program. This routine takes a phone number written as a string of numbers and converts it into the U.S. standard (xxx) xxx-xxxx format.

The previousButton_click() method is invoked when the user chooses the Previous button. This method begins by retrieving the Recordset object from the DataSource. If the recordset isn't empty, then previousButton_click() calls movePrevious() to move the current record pointer back one record. If a beginning-of-file condition is encountered, then the function moves the current record pointer back to the beginning of the recordset. The process is similar for the nextButton_click() method, only the method calls moveNext() rather than movePrevious() and checks for an end-of-file condition.

When the user chooses the Previous or Next button, the DataBinder object attached to the Recordset object automatically detects that the current record pointer has moved. The DataBinder object automatically updates the edit boxes that are bound to the Recordset by means of the DataBinding objects.

Customizing edit box output

The updatePhone() method isn't really necessary to the execution of the program; however, it demonstrates how you can insert your program into the data binding update process to customize output to the edit boxes. Without updatePhone(), a phone number is displayed as a 10-digit integer: 1234567890.

The phoneNumberEdit_textChanged() method is invoked whenever the contents of the phoneNumberEdit control object change. Since phoneNumberEdit is read-only, the contents change only when the previousButton_click() or the nextButton_click() methods update the customer data. The phoneNumberEdit_textChanged() method retrieves the string contents of the phoneNumberEdit object, calls updatePhone() to convert the string into the proper format, and then saves the resulting string back into the object. The Form1() constructor calls phoneNumberEdit_textChanged() to convert the phone number of the first record displayed.

Results

Screenshot-10 shows the results of executing ToolboxADO. The output doesn't differ significantly from the results of the ManualADO program, even though the ToolboxADO program is much easier to generate (once you get used to the Forms Designer steps). ToolboxADO isn't quite as easy to create as the wizard-generated AutoADO program, but the output from ToolboxADO is considerably more attractive and flexible than the output generated by the wizard.

Screenshot

Screenshot-10. The output of ToolboxADO is much like that of ManualADO with less work. Comments