Note: This workshop
requires that the following products are installed:
|
Section 1 - Create the J2EE Application Client
Project
___ 1. Look at the current project structure for WBOnline
a. Start WebSphere Studio Application Developer 5.0 (if not already started).
b. Open a J2EE Perspective and expand the WBOnlineEAR Project.
You'll note that there are currently two modules in the WBOnline Enterprise Application: WBOnlineEJB (EJB Project) and WBOnline (Web Project).
![]()
As you can see, WBOnlineEAR does not yet have an Application Client project. Since we are going to be building a Swing Java Application, we want to create it in an enterprise application client project.
___ 2. Create the WBOnlineClient J2EE Application Client Project
Note: Why should we build this Swing application as a J2EE Application Client?
Benefits of using J2EE application clients instead of regular Java applications include:
- Ability to run inside a server container, providing richer APIs.
- Use of the java:comp namespace to indirectly reference EJB beans.
- Use of J2EE security, including authentication and server-specific functions, which might include features such as single-sign-on.
- Guaranteed Java 2 platform APIs available, as well as container extensions.
- Simple JNDI lookup, because initial context properties are picked up from the container.
- Packaged like other J2EE components, providing portability, easy deployment, and clean packaging. This also supports the J2EE notion of a deployer being able to modify the deployment information in order to move to a different server without changing code.
a. From the J2EE Perspecitve, highlight the WBOnlineEAR Enterprise Application, click mouse button 2, and choose New->Application Client Project from the pop-up menu.
b. From the Application Client project creation wizard, select the Create J2EE 1.3 Application Client project radio-button.
Click the Next> button.
c. From the Application Client project page of the Create Application Client Wizard, specify the following
Parameter
Value
Project Name
WBOnlineClient
Enterprise application Project
click the Existing radio-button
Existing project name
Click the Browse... button and select WBOnlineEAR
![]()
Click the Next> button.
d. From the Module Dependencies page of the Create Application Client Wizard, check WBOnlineEJB.jar and WBOnlineUtility.jar .
![]()
___ 3. Create the com.wbo.client package
Note: Since our Application Client will use EJBs in our EJB project, we want the manifest.mf runtime classpath and the build path to be set correctly.
Click the Finish button to create the Enterprise Application Project.
e. If a Repair Server Configuration dialog appears, click the OK button.
When complete, you should notice WBOnlineClient has been added to the WBOnlineEAR Enterprise Application (as shown below)
![]()
a. Open (or switch to) a Java Perspective.___ 4. Create the WBAcctList Java Application
b. From the Java Perspective, expand the WBOnlineClient project and select the appClientModule folder.
c. With appClientModule selected, click mouse button 2, and choose New->Package from the pop-up menu.
d. From the Java Package Wizard, specify a package name of com.wbo.client .
Click the Finish button to create the package.
![]()
a. With the com.wbo.client package selected, click mouse button 2, and choose New->Class from the pop-up menu.
b. From the Java Class wizard, specify the following:
Parameter
Value
Name
WBAcctList
Superclass
javax.swing.JFrame
What method stubs would you like to create?
check the public static void main(String[] args) and
Inherited abstract methods checkboxes.
![]()
Click the Finish button to create the WBAcctList Java class. This will be the main class for our Swing application.Section 2 - Customizing the Java Visual Editor (JVE)
You'll notice that when WBAcctList.java was created, it opened in a standard Java Editor. To open the JVE, we simply need to switch editors for this file. Before we do this, we might want to customize the JVE before opening it.
There are several different views that open when launching the Java Visual Editor. By default the Palette, Visual Editor and Source Editor open as shown in the image below.
![]()
The developer can customize which views are displayed and how they are displayed in the JVE.
___ 1. Configure JVE Options
a. Choose Window->Preferences from the menu.Section 3 - Using the JVE to build the GUI
b. From the Preferences dialog, expand Java in the left hand pane and select Visual Editor.
Note: This page allows a developer to customize the JVE layout. If you are content with the defaults you can skip the next step.
My recommendations:
- If you are doing a JVE demo, leave the defaults so both the Visual Editor and Source editor are visible at the same time (makes for a more powerful demo)
- If you are going to be building an application, I like changing the defaults so there is more screen "real-estate" space to work in the Java Visual Editor.
c. From the Preferences dialog, click the On separate notebook tabs radio button. (Note: This will put the Visual Editor and the Source Editor in two different pages in a notebook.
![]()
Click the OK button to apply the changes.
a. Close the Java Editor for WBAcctList.java .___ 2. Customize the JFrame layout.
b. From the Package Explorer, highlight WBAcctList.java , click mouse button 2, and chose Open With->Visual Editor from the pop-up menu.
In a few moments the JVE should open with a view similar to this:
![]()
a. Using the Java Visual Editor, expand the JFrame so it looks something like this:
![]()
Notice that as you change the size of the JFrame visually, the properties (shown in the Properties view) for the JFrame size property change as well
![]()
The '>' marker indicates which properties have been changed from the defaults.
b. Switch from the Design view to the Source view by clicking on the Source tab in the notebook.
![]()
c. Look at the initialize() method. notice that the initialize method invokes the setSize method with the size of the JFrame.
d. Change the initialize() method and change the code so it looks similar to this:
private void initialize() {
this.setContentPane(getIvjContentPane());
this.setSize(350,250);
}
Note: Do not hit Ctrl+S to save the changes yet.
e. Switch back to the Design View.
You'll notice that the properties for the JFrame have been updated to the new size and the JFrame in the JVE has been changed as well. This is a very important feature with the JVE. The developer can work either in Design or Source mode and all code changes are synchonized between the visuals and source code!
Note: How did the visuals change even though you didn't explicitly save the file?
There is a background thread which parses the source code and refreshes the visuals. In the Preferences view for the Java Visual Editor, there is a Source Synchronization Delay parameter:
![]()
This parameter defines how long to wait before parsing the source and refreshing the visuals. If you plan on doing a lot of source code work, I recommend increasing this parameter value.
f. From the Properties view for JFrame, modify the title property with a value of WBOnline - Get Customer.___ 3. Add a JTable to the Swing Application
g. From the Properties view, change focus from title to visible.
Notice that the Visuals are automatically updated in the JVE based on the change made in the Properties view.
![]()
h. Switch to the Source view.
i. Change the initialize() method so it looks like this:
private void initialize() {
this.setContentPane(getIvjContentPane());
this.setSize(350,250);
this.setTitle("WBOnline - Get Customer Account List ");
}
j. Switch back to the Design view to see that the visuals have been updated based on your source code change.
a. From the Java Beans view, expand this in the tree view (Note: This represents WBAcctList which is a subclass of JFrame).___ 4. Add a JPanel to the Swing Application
![]()
b. Select ivjContentPane from the Java Beans view.
Note: The Java Beans list provides an easy way to select an object in the Visual Editor. As you start laying components in the Visual Editor, it may be hard to drop a component in a container in the Visual Editor.
Using the Java Beans list makes it easy to:
- see what visual components contain other visual components (e.g. a JPanel contains a JList and JButton).
- Select a visual component.
- Drop a component in the right container.
c. Look at the Properties view for ivjContentPane. You will notice that the layout is currently set (as a default) as BorderLayout.
![]()
d. Using the Palette, drop a JTable on JScrollPane (found in the Swing Components category) in the Center of ivjContentPane (as shown below)
![]()
The application should now look similar to this:
![]()
Our next step is to add a JPanel to hold the components which allow a person to enter a customer number and click a button.to get the account list.Section 4 - Adding the GUI Logic
a. From the Palette, select a JPanel (found in the Swing Containers category) and drop it in on the ivjContentPane in the Java Beans view. (as shown below)
![]()
b. Look at the Properties view for the JPanel and verify the constraint is set to North .
![]()
c. From the Palette, select a JLabel (found in the Swing Components category) and drop it in on the JPanel you just added.
d. From the Palette, select a JTextField (found in the Swing Components category) and drop it in on the JPanel (to the right of the JLabel).
Note: By default, a JPanel uses a Flow Layout. This is why the components are laying out as they are when you drop them on the JPanel.
e. From the Palette, select a JButton (found in the Swing Components category) and drop it in on the JPanel (to the right of the JTextField).
The JVE should look similar to this:
![]()
f. From the JVE, select the JLabel.
g. From the Properties view, change the text property value to Enter Customer #:
h From the JVE, select the JTextField.
i. From the Properties view, change the preferredSize property value to 60,19.
j. From the JVE, select the JButton.
k. From the Properties view, change the text property value to Get Account List.
When complete the, the UI of WBAcctList should look similar to this:
![]()
a. Switch back the Source view___ 2. Add the Event Handler code for the JButton
b. Using cut-and-paste or typing in the code, modify the main() method for this Java application so it looks like this:
public static void main(String[] args) {
try {
WBAcctList aWBAcctList;
aWBAcctList = new WBAcctList();
aWBAcctList.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent e) {
System.exit(0);
};
});
aWBAcctList.show();
java.awt.Insets insets = aWBAcctList.getInsets();
aWBAcctList.setSize(
aWBAcctList.getWidth() + insets.left + insets.right,
aWBAcctList.getHeight() + insets.top + insets.bottom);
aWBAcctList.setVisible(true);
} catch (Throwable exception) {
System.err.println("Exception occurred in main() of javax.swing.JFrame");
exception.printStackTrace(System.out);
}
}
Note: Event handling code may be generated for the developer in a future release of the Java Visual Editor.
a. From the Source view, add a new inner class for the handling the Action Event for the JButton by adding the following code. Note: you can add this code immediately after the line:
public class WBAcctList extends JFrame {
class IvjEventHandler implements java.awt.event.ActionListener {
public void actionPerformed(java.awt.event.ActionEvent e) {
if (e.getSource() == ivjJButton)
getAcctList(new Integer(ivjJTextField.getText()).intValue());
};
};
private IvjEventHandler ivjEventHandler = new IvjEventHandler();
b. Modify the getIvjJButton() method so it looks similar to this:
private javax.swing.JButton getIvjJButton() {
if (ivjJButton == null) {
ivjJButton = new javax.swing.JButton();
ivjJButton.setText("Get Account List");
ivjJButton.addActionListener(ivjEventHandler);
}
return ivjJButton;
}
c. Create a new method in WBAcctList called getAcctList. The method should look like this:___ 3. Execute the WBAcctList Java Application
private void getAcctList(int i) {
System.out.println("Button pressed. Customer # " + i);
}
Note: We'll be adding the real logic to the getAcctList() method in a subsequent step.
d. Hit Ctrl+S to save the code changes.
a. From the Java Perspective, click Run->Run... drop-down from the toolbar menu.Section 5 - Using the Swing Table Model Classes
![]()
b. From the Launch Configurations dialog, make sure Java Application is selected in the left-hand pane and click the New button.
c. Click the Run button to run WBAcctList. Verify that the application starts.
d. Enter a Customer # of 1 and click the Get Account List Button.
e. Check the Console view to verify that an output message is displayed. This verifies we have properly built the event handling for the JButton in this application..
.
f. Close the WBAcctList Java Application
___ 2. Analyzing WBAcctListTableModel.java
Note: Since the purpose of this lab is not to train you on how JTables and Table Models work, we will import a prebuilt model so you won't be building a TableModel from scratch.
We will analyze the Table Model code so you have an idea about how it works.
a. Using Drag and Drop or File->Import, import WBAcctListTableModel.java and WBAcctListController.java from the \WS50STEW\hands-on\JVE subdirectory to the com.wbo.client package in the WBOnlineClient project.
![]()
Let's think about design a moment and review a few facts before we begin:
- JTables use a Model/View architecture so that a developer must create a TableModel class that extends the AbstractTableModel class. WBAcctListTableModel is our implementation which is a subclass of AbstractTableModel.
a. Open WBAcctListTableModel.java in a Java Editor. Before looking at the code let's look at the outline view of this class:___ 3. Analyzing WBAcctListController.java
![]()
The methods marked with a triangle are abstract methods defined in the superclass AbstractTableModel. These methods are implemented in our class WBAcctListTableModel. Most of these methods are called by the JTable to display data from the model. The purpose of these methods are described below:
The actual data for our Table is stored in a field called data which is a Vector. What is actually stored in the Vector are objects of type AccountData. AccountData is a class we've used in WBOnline. It is simply a light-weight data object which contains account number and balance.
- isCellEditable: This method returns true if the cell in the table at position (x, y) is editable. You'll see that our implementation returns false because our table is read only.
- getColumnClass: This method returns the class of the object for a given column (e.g. Column 1 holds a java.lang.Integer, Column 2 holds java.math.BigDecimal classes)
- getRowCount: Returns an int which represents how many rows are in the table
- getColumnName: Returns a String for a given column
- getColumnCount: Returns an int which represents the number of columns in the table.
- getValueAt: This is one of the most important methods. This returns the actual data for the table at a position (x,y). The JTable will call this method for each row and column (based on the values it gets back from the getRowCount/getColumnCount methods) defined in the JTable.
b. Close WBAcctListTableModel.java.
a. Open WBAcctListController.java in a Java editor.
WBAcctListController represents the controller in this MVC Application. You'll notice that there are two methods in WBAcctListController
- getAcctList is the public method that is invoked which will use the AccountActivity Session EJB (and the remote method getAccountDataForCustomer) in WBOnline to get a list of Accounts based on the customer number.
- mapAccountDataToVector is a private method that is invoked from getAcctList. This method takes the AccountData (returned from the Session EJB) and adds the data to a vector (which is used in the WBAcctListTableModel)
With this design, the Model (WBAcctListTableModel) and the View (WBAcctList) are encapsulated from how the actual data is accessed (in this case EJBs). We could change the design of WBAcctListController to return account information from some other mechanisem (perhaps JDBC) without affecting either the Model or the View.___ 5. Add the logic to retrieve the data from our EJBs (using WBAcctListController) and populate the TableModel.
Note: Ideally, we would use Events to notify changes between the view and the model. We've chosen not to use events to simplify the code in this example.
b. Close WBAcctListController.java.
a.Switch to the Java Visual Editor for WBAcctList.java and switch to the Source view.Section 6 - Testing the J2EE Client Application
b. Create a new field in WBAcctList as shown below:
private WBAcctListTableModel ivjJTableModel = null;c.Modify the getIvjTable() method so it looks like this:
private javax.swing.JTable getIvjJTable() {
if (ivjJTable == null) {
ivjJTable = new javax.swing.JTable();
ivjJTableModel = new WBAcctListTableModel();
}
return ivjJTable;
}
d. Modify the getAcctList() method so it looks like this:
private void getAcctList(int i) {
try {
WBAcctListController c = new WBAcctListController();
c.getAcctList(i,ivjJTableModel);
ivjJTable.setModel(ivjJTableModel);
ivjJTable.repaint();
} catch (Exception e) {
e.printStackTrace();
}
}
e. Hit Ctrl+S to save the changes.
f. Close the Java Visual Editor for WBAcctList.java.
a. Switch to a J2EE Perspective and J2EE View.
b. Expand Application Modules and double-click WBOnlineClient to open the Client Deployment Descriptor editor.
c. Click the Edit... button in the Main Class section.
![]()
A JAR Dependency Editor should open.
d. From the JAR Dependency editor, click the Browse... button in the Main Class section.
e. From the Type Selection dialog, select WBAcctList.___ 2. Start the WebSphere v5 Unit Test Server.
![]()
Click the OK button.
f. Hit Ctrl+S to save the changes in JAR Dependency Editor.
g. Close the JAR Dependency editor
h. From the Client Deployment Descriptor Editor, click the Refresh button in the Main Class section.
.
Note: The Main-Class parameter will define the main class (in the J2EE client manifest file) to invoke when running the application as a J2EE Client.
i. Close the Client Deployment Descriptor editor
a. Open (or switch to) to a Server Perspective.___4. Start WBAcctList as a J2EE Client Application.
b. From the Servers view, Highlight the WebSphere v5 Unit Test server, click mouse button 2, and choose Start from the pop-up menu.
c. Wait a few moments until you see the message:
WSVR0001I: Server server1 open for e-businessdisplayed in the console.
a. Switch back to a Java Perspective.Section 7 - Optional - Making The GUI Multi-threaded
b. From the Package Explorer view, highlight WBAcctList.java and choose the Run->Run... drop-down from the toolbar menu.
![]()
c. From the Launch Configurations dialog, choose WebSphere V5 Application Client from the left hand pane.
d. Click the New button.
e. Change the Configuration Name from New_Configuration to WBAcctList - J2EE Client Application.
f. Change the Enterprise Application to WBOnlineEAR ( Note: Use the Drop-down list)
g. Click the Apply button.
![]()
h. Click the Run button to launch WBAcctList as a J2EE Client Application.
In a few moments, you should see some console messages displayed indicating the J2EE Client Environment is starting. Once the J2EE Client Environment is initialized, our WBAcctList Swing Application should start.
![]()
i. Enter a Customer # of 1 and click the Get Account List button.
After a few moments, you should see the following results displayed:
![]()
Note: SwingWorker is documented
at
http://java.sun.com/products/jfc/tsc/articles/threads/update.html |
. a. Using Drag and Drop or File->Import, add SwingWorker.java from the \WS50STEW\hands-on\JVE subdirectory to the com.wbo.client package in the WBOnlineClient project.___ 2. Modify the getAcctList() method in WBAcctList to use a separate thread.
![]()
a. Open WBAcctList.java in the JVE___ 3. Run the WBAcctList J2EE Client Application.
b. Switch to the Source view.
c. Using cut-and-paste modify the getAcctList() method so it looks like this: (Note: This code uses an inner class)
private void getAcctList(int i) {
final int cust_num = i;
final SwingWorker worker = new SwingWorker() {
public Object construct() {
WBAcctListController c = new WBAcctListController();
c.getAcctList(cust_num, ivjJTableModel);
return null;
}
public void finished() {
ivjJTable.setModel(ivjJTableModel);
ivjJTable.repaint();
}
};
worker.start();
}
c. Hit Ctrl+S to save the changes.
a. Run WBAcctList as a J2EE Client Application again.Congratulations, you've completed the JVE Lab for WebSphere Studio Application Developer 5.0.
b. Specify a customer # of 1 and click the Get Account List button.
The results should be returned as before. This time the time consuming task is run on a background thread!
Note: How can you tell it is run on a background thread?
- Using the debugger, you can monitor the application and see multiple threads being used in the application
- You might not have noticed this, but when you pressed the Get Account List button in the non-thread version of WBAcctList, the button stayed depressed and the UI was unresponsive until the account list was returned. In the threaded version, you'll notice the button and the UI are responsive as SOON as the button is pressed.