Sample: CustomerInfo
Objectives
This sample illustrates how to build an application using visual composition.
Description
This sample illustrates using features of visual composition for the following
tasks:
This package is full of beans! It contains two nonvisual beans, Address
and Customer, that represent a model of data and two views for those beans,
AddressView and CustomerView. The Address bean is referenced in the AddressView.
Address is also used as a property in the Customer bean. The CustomerView
contains an AddressView within its view and references a Customer bean.
The CustomerInfo sample, which extends java.awt.Frame, brings these models
and views together. It also uses another sample bean: an ObjectList that
looks like a java.awt.List but uses and maintains any object, not just
strings.
Running the CustomerInfo Sample
To run this sample:
-
Select the CustomerInfo class from the Projects page.
-
Select the Run button on the tool bar.
To build the CustomerInfo sample
The classes that are part of the CustomerInfo sample should be built in
the following order:
-
Address
-
AddressView
-
Customer
-
CustomerView
-
CustomerInfo
Building the Address class
-
Create the Address class as follows:
-
From the Projects page of the Workbench
-
Select the package where you will save this sample
-
Select the Create Class button on the tool bar
-
Class name = Address
-
Superclass = java.lang.Object
-
Deselect the Compose the class visually check box
-
Click Next
-
Modifier: public
-
Create method stubs for the recommended items plus: equals and toString
-
Click Add to choose an interface for this class to implement
-
Select the Cloneable interface
-
Click Close
-
Click Finish
-
Add some properties:
You will create properties that will be used to store address information.
-
Select the BeanInfo page
-
Click the Create Property Feature button on the tool bar
-
Property name = street
-
Property type = java.lang.String
-
Options: Readable, Writable, and bound
-
Click Finish
-
Click the Create Property Feature button on the tool bar.
You will create three more property features for city, state, and zipCode
with the same characteristics as street
-
Property names = city, state, zipCode
-
Property type = java.lang.String
-
Options: Readable, Writable, and bound
-
Click Finish
-
Add some methods:
-
The Address bean that you are creating is going to be used in an application
that manages many customers with unique addresses. It will need to
be able to copy address information from a customer instance into an address
instance, and clone address information for use in a customer instance.
You will create two methods for these purposes: clone and copyFrom.
-
Select the Methods page
-
Select the Create Method or Constructor button on the tool bar
-
Select Create a new method
-
Method name = java.lang.Object clone()
-
Click Next
-
Modifiers: public
-
Click Add to choose an exception that this method may throw
-
Select the CloneNotSupportedException interface
-
Click Close
-
Click Finish
-
Select the Create Method or Constructor button on the tool bar
-
Select Create a new method
-
Method name = void copyFrom(Address source)
-
Click Next
-
Modifiers: public
-
Click Finish
-
Copy source code from the sample provided with the product. Locate
the Address class provided with the product samples, and for methods clone,
copyFrom, equals, and toString do the following:
-
Copy the code in the sample method
-
In your method, delete the existing source code
-
Paste the copied code
-
Save the method
-
Add method features:
The clone and copyFrom methods need to be part of the Address bean's
public interface, so you will identify these methods as bean features.
-
Select the BeanInfo page
-
Select Features from the menu bar
-
Select Add Available Features
-
Select the "clone" and "copyFrom" methods from the list
-
Click Ok
You could have created the clone and copyFrom methods from the BeanInfo
page. They would have been defined as method features, and you could
have avoided this last step.
Now you can close the class browser for the Address class.
Building the AddressView class
-
Create the AddressView class as follows:
-
From the Projects page of the Workbench
-
Select the package where you will save this sample
-
Select the Create Class button on the tool bar
-
Class name = AddressView
-
Superclass = java.awt.Panel
-
Select the Compose the class visually check box
-
Click Finish
-
The Visual Composition page of the class browser
will be displayed, where you can build the user interface as follows:
-
Set properties for AddressView
-
layout = GridBagLayout
-
constraints -> width = 350, height = 100
-
Change the palette category to AWT
-
Drop three Label beans in a vertical column. Set properties for the Labels
-
text for each Label (from top to bottom) =
-
constraints -> fill = HORIZONTAL, anchor = WEST
-
Drop three TextField beans in a vertical column beside the labels. Set
properties
-
for the top two TextFields
-
constraints -> fill = HORIZONTAL, gridwidth = 3, weightX = 1.0
-
for the bottom TextField
-
constraints -> insets right = 20
-
columns = 2
-
Drop a Label to the right of TextField3. Set properties for Label4
-
Drop a Textfield beside Label4. Set properties for Textfield4
-
constraints -> anchor = WEST
-
columns = 11
-
Add a nonvisual bean
The nonvisual Address bean will be used as a variable that will reference
specific instances of Address as needed.
-
Drop a variable on the free-form surface
-
Select Choose Bean from the palette
-
Bean Type = Variable
-
Interface/Class name = your_package_name.Address
-
Click OK
-
Place the bean on the free-form surface beside the AddressView panel
-
Promote a feature
Address1 needs to be accessible when AddressView is being used within
another bean. Feature promotion exposes
properties of beans that are embedded within other beans. In this
case Address1 is contained within AddressView. To access Address1
when AddressView is embedded in a composite bean, you will promote the
"this" property of Address1.
-
Select Address1
-
Click mouse button 2
-
Select Promote bean feature
-
Select the "this" property of the variable and click >> to add the feature
-
Click OK
-
Make connections to set properties and invoke methods as follows (see Connection
Syntax ):
-
The values in Address1 should change as the user enters values into the
TextFields. Since the TextField's "text" property is not defined
as "bound", you will need to identify the "textValueChanged" event as the
trigger event that will cause the values in Address1 to be updated when
"text" in the TextFields changes. The properties in Address1 are
defined as "bound", so changes in their values will result in changes to
"text" in the TextFields. The direction of property-to-property
connections is important in that it determines which bean will be initialized
(the target) from the other (the source).
-
Property-to-property connection
-
Source: Address1 street/property
-
Target: TextField1 text/property
-
Target event: textValueChanged
-
Property-to-property connection
-
Source: Address1 city/property
-
Target: TextField2 text/property
-
Target event: textValueChanged
-
Property-to-property connection
-
Source: Address1 state/property
-
Target: TextField3 text/property
-
Target event: textValueChanged
-
Property-to-property connection
-
Source: Address1 zipCode/property
-
Target: TextField4 text/property
-
Target event: textValueChanged
-
Save the bean and exit:
-
Select Bean from the menu bar
-
Select Save Bean
-
Close the Visual Composition Editor
You have just created a reusable view that can be used to display and edit
an Address. Just drop the AddressView in a visual bean. Also drop an Address
and connect the Address bean to the address attribute of the AddressView
bean.
Building the Customer class
-
Create the Customer class as follows:
-
From the Projects page of the Workbench
-
Select the package where you will save this sample
-
Select the Create Class button on the tool bar
-
Class name = Customer
-
Superclass = java.lang.Object
-
Deselect the Compose the class visually check box
-
Click Next
-
Modifier: public
-
Create method stubs for the recommended items plus: equals and toString
-
Click Add to choose an interface for this class to implement
-
Select the Cloneable interface
-
Click OK
-
Click Finish
-
Add some properties:
-
Create properties that will store customer information.
-
Select the BeanInfo page
-
Press the Create Property Feature button
on the tool bar
-
Property name = name
-
Property type = java.lang.String
-
Options: Readable, Writable, and bound
-
Click Finish
-
Press the Create Property Feature button on the tool bar
-
Property name = phone
-
Property type = java.lang.String
-
Options: Readable, Writable, and bound
-
Click Finish
-
Press the Create Property Feature button on the tool bar
-
Property name = address
-
Property type = <<your_package_name>>.Address
-
Options: Readable, Writable, and bound
-
Click Finish
-
Add some methods:
The Customer bean that you are creating is going to be used in an application
that manages many customers. It will need to be able to copy customer
information from a customer instance, and clone customer information for
use in a customer instance. You will create two methods for these
purposes: clone and copyFrom.
-
Select the Methods page
-
Select the Create Method or Constructor button on the tool bar
-
Select Create a new method
-
Method name = java.lang.Object clone()
-
Click Next
-
Modifiers: public
-
Click Add to choose an exception that this method may throw
-
Select the CloneNotSupportedException interface
-
Click Close
-
Click Finish
-
Select the Create Method or Constructor button on the tool bar
-
Select Create a new method
-
Method name = void copyFrom(Customer source)
-
Click Next
-
Modifiers: public
-
Click Finish
-
Copy source code from the samples provided with the product. Locate
the Customer class provided with the product samples, and for methods clone,
copyFrom, equals, and toString do the following:
-
Copy the code in the sample method
-
In your method, delete the existing source code
-
Paste the copied code
-
Save the method
-
Add method features:
The clone and copyFrom methods need to be part of the Customer bean's
public interface, so you will identify these methods as bean features.
-
Select the BeanInfo page
-
Select Features from the menu bar
-
Select Add Available Features
-
Select the clone and copyFrom methods from the list
-
Click Ok
You could have created the clone and copyFrom methods from the BeanInfo
page. They would have been defined as method features, and you could
have avoided this last step.
Now you can close the class browser for Customer.
Building the CustomerView
class
-
Create the CustomerView class as follows:
-
From the Projects page of the Workbench
-
Select the package where you will save this sample
-
Select the Create Class button on the tool bar
-
Class name = CustomerView
-
Superclass = java.awt.Panel
-
Select the Compose the class visually check box
-
Click Finish
-
The Visual Composition page of the class browser will be displayed, where
you can build the user interface as follows:
-
Set properties for CustomerView:
-
layout = GridBagLayout
-
constraints -> width = 450, height = 200
-
Change to the AWT category on the palette
-
Drop three Label beans in a vertical column. Set properties for the Labels
-
text for each Label (from top to bottom) =
-
constraints -> fill = HORIZONTAL, anchor = WEST
-
Drop a TextField bean next to the first and third labels. Set properties
for the TextFields
-
constraints -> fill = HORIZONTAL, weightX = 1.0
-
Select Choose Bean from the palette
-
Bean Type = Class
-
Class name = your package name.AddressView
-
Click OK
-
Place the AddressView beside Label2
-
Set properties for AddressView1
-
constraints -> fill = HORIZONTAL, weightX = 1.0, insets top = 4, insets
bottom = 4
-
Add a nonvisual bean:
The nonvisual Customer bean will be used as a variable that will reference
specific instances of Customer as needed.
-
Drop a variable on the free-form surface
-
Select Choose Bean from the palette
-
Bean Type = Variable
-
Interface/Class name = your_package_name.Customer
-
Click OK
-
Place the bean on the free-form surface beside the CustomerView panel
-
Promote a feature
Customer1 needs to be accessible when CustomerView is being used within
another bean, so feature promotion will be used.
-
Select Customer1
-
Click mouse button 2
-
Select Promote Bean Feature
-
Select the "this" property of the variable and click >> to add the feature
-
Click OK
-
Make connections to set properties and invoke methods as follows (see Connection
Syntax ):
-
The values in Customer1 need to change as the user enters values into the
TextFields. Since the TextField's text property is not defined as
bound, you will need to identify the textValueChanged event as the trigger
event that will cause the values in Customer1 to be updated when text in
the TextFields changes. The properties in Customer1 are defined as
bound, so changes in their values will result in changes to text in the
TextFields.
-
Property-to-property connection
-
Source: Customer1 name/property
-
Target: TextField1 text/property
-
Target event: textValueChanged
-
Property-to-property connection
-
Source: Customer1 phone/property
-
Target: TextField2 text/property
-
Target event: textValueChanged
-
The address property for Customer1 and AddressView1 need to stay in sync.
The address property was defined as bound, so a change in the value of
either bean's address property will result in the value of the other one
being changed.
-
Property-to-property connection
-
Source: Customer1 address/property
-
Target: AddressView1 address1This/property
-
Reorder the tabbing sequence:
As a user tabs through the fields in the
CustomerView the flow should be from the name, to the address, to the phone
number. To change the current tabbing order do the following:
-
Select the CustomerView panel
-
Click mouse button 2
-
Select Set Tabbing
-
Select Show Tab Tags (the tabbing order is now visible as numbers
by the TextFields)
-
Press and hold mouse button 2 over the "2" and drag it to the textfield
marked with tag "3"
-
Save the bean and exit:
-
Select Bean from the menu bar
-
Select Save Bean
-
Close the Visual Composition Editor
You have just created a reusable view that can be used to display and edit
a Customer. Just drop the CustomerView in a visual bean. Also drop a Customer
and connect the Customer bean to the customer attribute of the CustomerView
bean.
Building the CustomerInfo
class
-
Create the CustomerInfo class as follows:
-
From the Projects page of the Workbench
-
Select the package where you will save this sample
-
Select the Create Class button on the tool bar
-
Class name = CustomerInfo
-
Superclass = java.awt.Frame
-
Select the Compose the class visually check box
-
Click Finish
-
The Visual Composition page of the class browser will be displayed, where
you can build the user interface as follows:
-
Set properties for the ContentsPane in CustomerInfo
-
layout = GridBagLayout
-
background = LightGray
-
Set properties for CustomerInfo
-
title = Customer Information
-
constraints -> width = 500, height = 400
-
Change the category on the palette to AWT
-
Drop a Label bean in the ContentsPane of CustomerInfo. Set properties for
Label1
-
constraints -> fill = HORIZONTAL, insets left = 5
-
text = Press New to create a customer,
-
Drop another Label bean to the right of Label1. Set properties for Label2
-
constraints -> fill = HORIZONTAL, insets left = 5
-
text = or select a customer and press Update or Delete
-
Drop a com.ibm.ivj.examples.vc.utilitybeans.ObjectList bean below Label1.
Set properties for ObjectList1
-
constraints -> fill = BOTH, gridWidth = 2,insets top = 10, insets bottom
= 10, insets right = 10, insets left = 10, weightX = 1.0, weightY = 1.0
-
beanName = CustomerList
-
Drop a your package name.CustomerView bean below CustomerList.
Set properties for CustomerView1
-
constraints -> fill = HORIZONTAL, gridWidth = 2,weightX = 1.0, insets
left = 20, insets right = 20
-
Drop a Panel on the free-form surface. Set properties for Panel1
-
layout = FlowLayout
-
constraints -> width = 200, height = 35
-
Drop three Button beans onto Panel1. Set properties for the Buttons
-
labels (from left to right) =
-
beanName (from left to right) =
-
NewButton
-
UpdateButton
-
DeleteButton
Set this property for UpdateButton and DeleteButton
-
Move Panel1 into CustomerInfo below CustomerView1. Set properties
for Panel1
-
constraints -> anchor = EAST, gridWidth = 2,insets top = 10, insets bottom
= 10, insets right = 10, insets left = 10
-
Save the bean
-
Select Bean from the menu bar
-
Select Save Bean
-
Add a nonvisual bean:
An instance of the nonvisual Customer bean will be needed.
-
Drop an object on the free-form surface
-
Select Choose Bean from the palette
-
Bean Type = Class
-
Class name = your_package_name.Customer
-
Click OK
-
Place the bean on the free-form surface at the upper right side of the
CustomerInfo frame
-
Add a method:
The state of CustomerList will be used to determine whether the NewButton
or DeleteButton buttons should be enabled. They should only be enabled
if there is something selected in CustomerList. You will create a
method named setButtonState(). If CustomerList selectedIndex
is greater than or equal to zero an item is selected and the NewButton
and DeleteButton buttons should be enabled. Otherwise they should be disabled.
To create the setButtonState method:
-
Select the Methods page
-
Select the Create Method or Constructor button on the tool bar
-
Select Create a new method
-
Method name = void setButtonState()
-
Click Next
-
Modifier: protected
-
Click Finish
-
Locate the CustomerInfo class in the samples
-
Copy the code from setButtonState in the sample method
-
In your method, delete the existing source code
-
Paste the copied code
-
Save the method
-
Make connections to set properties and invoke methods as follows (see Connection
Syntax ):
-
Select the Visual Composition page
-
The information entered in CustomerView should be saved in Customer1.
-
Property-to-property connection
-
Source: Customer1 this/property
-
Target: CustomerView customer1This/property
The direction of property-to-property connections determines which
property will be used to initialize the other. In this case, the
customer1This property represents the promoted this property of a Customer
variable (from CustomerView) and so this should be set from the this property
of the Customer1 bean
-
The next series of connections identify actions that should be taken when
certain events occur.
-
Event-to-method connection
-
Source: NewButton actionPerformed /event
-
Target: CustomerList addObject/method
-
Method parameter: java.lang.Object
-
Parameter source: object
-
Parameter target: Customer1 clone/method
When NewButton is pressed, a clone of Customer1 is added to CustomerList.
-
Event-to-method connection
-
Source: UpdateButton actionPerformed/event
-
Target: CustomerList replaceObject/method
-
Method parameter: java.lang.Object
-
Parameter source: object
-
Parameter target: Customer1 clone/method
-
Method parameter: int
-
Parameter source: index
-
Parameter target: CustomerList selectedIndex/property
When the UpdateButton is pressed, the selected item in CustomerList
is replaced with a clone of Customer1. The old version will be garbage
collected.
-
Event-to-method connection
-
Source: CustomerList itemStateChanged/event
-
Target: Customer1 copyFrom/method
-
Method parameter: Customer
-
Parameter source: source
-
Parameter target: CustomerList selectedObject/property
When a Customer object is selected in CustomerList, the properties
of the selected item will be used to replace those in Customer1.
-
Event-to-Code connection
-
Source: DeleteButton actionPerformed/event
-
Target: CODE showMessageBox/method
When the DeleteButton is pressed, a JOptionPane is displayed requesting
confirmation before deleting anything. To make this connection:
-
Locate the CustomerInfo class provided with the product samples
-
Copy its code for the showMessageBox method to the clipboard
-
Select the DeleteButton actionPerformed event as the source for the connection
-
Click on the free-form surface
-
Select Event to Code
-
Leave actionPerformed as the event and <new method> selected as the
Method name
-
Delete the source code in the Event-to-Code window and replace it with
the showMessageBox method source code from the clipboard
-
Use Ctrl+S to save the method
-
Deselect the Pass event data checkbox
-
Click OK
-
Result: int
-
Result source: normalResult
-
Result target: CODE messageBoxAction/method
Once an option has been selected from the JOptionPane, messageBoxAction
will perform the required action. To make this connection:
-
Locate the CustomerInfo class provided with the product samples
-
Copy its code for the messageBoxAction method to the clipboard
-
Select the normalResult as the source for the connection
-
Click on the free-form surface
-
Select Event to Code
-
Leave normalResult as the event and <new method> selected as the Method
name
-
Delete the source code in the Event-to-Code window and replace it with
the messageBoxAction method source code from the clipboard
-
Use Ctrl+S to save the method
-
Deselect the Pass event data checkbox
-
Click OK
-
The next connections use the setButtonState method that you created to
enable or disable NewButton and DeleteButton as appropriate.
-
Event-to-Code connection
-
Source: CustomerList1 itemStateChanged/event
-
Target: CODE setButtonState/method
When there is a change in the state of CustomerList1, the state of
the Update and Delete buttons is reevaluated by the setButtonState method.
-
Event-to-Code connection
-
Source: UpdateButton actionPerformed/event
-
Target: CODE setButtonState/method
When the Update button is pressed, the state of the Update and Delete
buttons is reevaluated by the setButtonState method.
As beans are added to the Visual Composition Editor, the Class Path is
updated to include any referenced classes and their projects. In
this sample a JOptionPane is referenced in code, but is not dropped in
the Visual Composition Editor so the appropriate project is not included
in the Class Path. To let VisualAge determine which projects are
required and to update the Class Path accordingly, do the following:
-
Select Bean from the Menu bar
-
Select Run
-
Select Check class path
-
Click Compute now
-
Click OK
The sample is now complete and ready to run!