Welcome!

Java Authors: Maureen O'Gara, Liz McMillan, Walter H. Pinson, III, Yakov Werde, Tony Bishop

Related Topics: Java

Java: Article

Building Pure Java Apps Using Visual Studio

How to mix cats and dogs

Inputting Data: The Wizard Control and the Data Sources
Now let's substitute a stub page to allow users to input a good deal of data using the Wizard control. Using Smart Tag, add two Wizard steps and customize appearance using the Auto Format feature (see Figure 2).

To populate the first step of the control, drag the Label and Calendar controls from the Toolbox, which the speaker will use to select the date. Let's insert another Label and a DropDownList used to select the host city from the corresponding table in the SQL Server 2005 Express database using Data Sources.

To use the SQL Server 2005 Express data source from a Java application server, we'll enable the use of TCP/IP instead of the Named Pipes (see Figure 3). In the Data Source Wizard, click the Advanced button. From the connection properties, choose TCP/IP under Network Library. Note that Integrated Security is automatically set to False. Click on Test Connection to ensure that everything works correctly. When the time comes to deploy on a non-Windows platform, one last change has to be made: substitute the named instance of SQL Server with the IP address of the database server. To do this, you'll have to open the Web.Config file and replace Data Source=.\SqlExpress with Data Source=<ip address>\ SqlExpress.

Finally, add a TextBox so the total number of JavaDay participants can be input. The result is shown in Figure 4.

Travel Expenses Using External Java Classes
We're not going to fill in the second page of the Wizard control with data. Instead, we'll use a series of labels that contain the speaker's travel expenses that are on the first page. In a real-world application, the travel expense database would most likely be populated by another application, or better still by several applications: one hosted by the travel agency, another by the hotel chain where the speaker resides, yet another hosted by the restaurant chain where the speaker eats, and so forth. So why not add a "touch of realism" to JDExpenses?

The data pertaining to travel expenses are in fact sourced from another application, JDTravel, provided by the agency that takes care of the logistics for this event. The application's source code is in Listing 1.

There's no denying it: this is not a typical .NET application. In fact, we created it with the lean educational version of NetBeans 5.0, BlueJ (http://edu.netbeans.org/bluej/). The public method calculateExpenses takes care of an array of integers containing the speaker expenses, retrieving them from a HashMap and using a surname passed on as a parameter as the key. The HashMap is returned by an internal method, getExpensesByERP. While this method simply populates the HashMap with a series of value puts assigned in a hard-coded manner, its name hints at a deeper notion: if the map were really produced by a complex application, such as an ERP, the wrapper calculateExpenses method would make the results available in our .NET application.

To enable and use application classes, right-click the project name in the Solution Explorer and choose Add Java Reference. Click the Browse tab and select the BlueJ JAR - JDTravel.jar - in the file system, executing the build of the JDTravel project (see Figure 5). To make the project internally consistent, I added the JAR to a new ext (external) folder of the Visual Studio JDExpenses project. Adding the JAR to the project references is a little time-consuming, and if we look at the reference properties when the job is done (Figure 6) we'll realize why: Grasshopper records the JAR as if it were a native .NET assembly, assigning values to many of the properties of a "common" assembly.

To be able to use the TravelExpenses class, an instance of it must be created in the transition to the wizard's second page. In practical terms, we must handle the Wizard control's NextButtonClick event; we'll use the LoadExpenses handler method. In the page's code-behind, add the following directive:

using JDTravel;

Then, create an instance of the class, as well as a private variable that will receive the array of integers returned by the calculateExpenses method:

private TravelExpenses ExpensesJD = new TravelExpenses();
private int[] expenses;

Go back to ExpensesManagement.aspx and in the Design mode move to the second step of the Wizard control by selecting the Various expenses item defined in the control's menu. Bear in mind that before the compilation stage, you'll have to reselect the first Wizard step, and then the execution will begin from the page highlighted during compilation. Then, add three labels that will show the user's travel, room, and board expenses as shown in Listing 2 and populate them using the following code:

protected void LoadExpenses(object sender, WizardNavigationEventArgs e)
{
    expenses = ExpensesJD.calculateExpenses(this.ddlSpeaker.SelectedValue);
    this.lblTravelExpenses.Text = "Travel expenses: " +
expenses[0].ToString() + " dollars";
    this.lblLodgingExpenses.Text = "Lodging expenses: " +
expenses[1].ToString() + " dollars";
    this.lblBoardExpenses.Text = "Board expenses: " +
expenses[2].ToString() + " dollars";
}

Notice what actually happened when the expenses variable was assigned its value: a Java array, which is an instance of java.lang.reflect.Array, was transformed into an array, which is to say an instance of System.Array implemented .NET's ICollection. It would be rather difficult to achieve this transformation in such an efficient way if we resorted to the Web Services as an integration technology.

Cross-Platform Debugger
To view Grasshopper's integrated debugger in action, insert a breakpoint in the row in which the expenses variable received its value. As usual, click on the gray bar beside the row numbers and launch the application by pressing F5. As expected, the code flow will be suspended at the breakpoint and we'll be able to use all our familiar debugging tools: call stack, local variables window, and Step Over, as well as verify the value of a variable by mouse-over (see Figure 7).

As a final task for the ExpensesManagement element, we need to handle the data gathered in the Wizard control. This control doesn't execute the data POST, not even in the type-safe form of the ASP.NET 2.0 cross-page posting (http://msdn2.microsoft.com/en-us/library/ms178139.aspx). Rather, it reveals the FinishButtonClick event, where we'll execute not only the persistence of the inputted data, but the management of the state as well. The most suitable device among those offered by ASP.NET 2.0 for a self-contained and cross-platform application is the Session object. So we'll add this call to the event handler - OnFinishButtonClick="WizardDataManagement" - and write the persistence code in ExpensesManagement.aspx.cs, as shown in Listing 3.


More Stories By Philippe Cohen

Philippe Cohen is the vice president of products for Mainsoft Corporation, where he is responsible for overseeing product management, R&D, and support teams for Mainsoft's product suite.

More Stories By Paolo de Nictolis

Paolo de Nictolis is an Italian Web developer, a technical contributor to MSDN and UGI.NET, and a freelance IT journalist.

Comments (1) View Comments

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


Most Recent Comments
jnsoneji 10/31/07 10:12:51 PM EDT

Trackback Added: http://jnsoneji.spaces.live.com/Blog/cns!37E7335732E61C89!256.entry; Building Pure Java Apps Using Visual Studio