December 2006 [Revision number: V1-1] |
|
|
This tutorial shows you how to use NetBeans Visual Web Pack 5.5
to build a web application that uses the sample Java BluePrints AJAX Progress Bar component.
The tutorial shows several uses of the Progress Bar. First, you configure the Progress Bar for a determinate
use case. In this case, the Progress Bar shows the percentage of progress as the task is completed. Next, you
configure the Progress Bar for an indeterminate use case. Here, the Progress Bar indicates only that a task is
under way, and not the percentage of progress completed, because the extent of the progress is unknown. Finally,
you configure the Progress Bar to handle a failed task.
|
Contents
|
|
 |
This tutorial works with the following resources
NetBeans Visual Web Pack 5.5 works with all supported servers and works
with both the Java EE 1.4 and Java EE 5 platforms. This tutorial
illustrates the Visual Web Pack features that work with the resources
check marked in the following table. For detailed information about the
supported servers and Java EE platform, see NetBeans
Visual Web Pack 5.5 Installation Instructions.
Application Server |
Sun Java System Application Server 9
Tomcat
JBoss
BEA WebLogic |
JavaServer Faces Components/
Java EE Platform |
1.2 with Java EE 5*
1.1 with J2EE 1.4
|
Travel Database |
Not Required |
BluePrints AJAX Component Library |
Required |
* Only the Sun Java System Application Server supports Java EE 5
Setting Up the Application
You begin this tutorial by importing the Java BluePrints AJAX components into the IDE.
You then create a project and add two files, SimpleTask.java and pb.js . SimpleTask.java
simulates a server-side task that is performed in a separate thread. Whenever the user starts (or resumes) the task, the start
method in SimpleTask.java spawns a new thread, which alternately sleeps and increments a counter.
The file pb.js contains functions that are called by the JavaScript-related properties of the components in the
application. These properties include the onComplete and onFail properties of the Progress Bar,
the onClick property of the Buttons, and the onSubmit property of the Form.
- Download and import the latest
version of the AJAX components if you have not already done so.
- Download
SimpleTask.java and
pb.js and save them to your file system.
Create a new visual web application project and name it ProgressBarExample .
ProgressBarExample's initial Page opens in the Visual Designer.
Add SimpleTask.java to the project as follows:
- From the main menu, choose File > Add Existing Item > Java Source. Navigate to the directory in which you
saved
SimpleTask.java . Select the file and click Add.
In the Projects window, expand Source Packages >
progressbarexample. Double-click the SimpleTask.java node to open the
file in the Java Editor.
The following package statement is added at the top of the file:
package progressbarexample;
Add the pb.js JavaScript file to the project as follows:
- Choose File > Add Existing Item > Other (all files). Navigate to and select
pb.js , and then click Add.
- In the Projects window, drag
pb.js from Source Packages > progressbarexample to Web Pages > resources.
Modifying the Session Bean
Next you add and configure a property for the project's Session Bean.
- Open Page1 in the Visual Designer.
In the Outline window, right-click SessionBean1 and choose Add > Property.
Note: If the Add menu is not activated when you first open the pop-up menu,
close the menu and right-click the SessionBean1 node a second time to activate the Add submenu.
In the New Property Pattern dialog box, set the Name to taskMap , the Type to
HashMap (note that the Name and Type fields are case sensitive), and the Mode to Read Only
as shown in the following figure. Click OK.
Figure 1: New Property Pattern Dialog Box |
-
Right-click the SessionBean1 node and choose Edit Java Source from the pop-up menu.
Error annotations appear in the code indicating that the HashMap class is not found.
Right-click anywhere in SessionBean1.java and choose Fix Imports from the pop-up
menu to automatically add the following import statement: import java.util.HashMap;
Append the following lines of code (in bold) to the SessionBean1.init method.
Code Sample 1: SessionBean1 Property |
public void init() {
// Perform initializations inherited from our superclass
super.init();
// Perform application initialization that must complete
// *before* managed components are initialized
// TODO - add your own initialiation code here
Creator-managed Component Initialization
// Perform application initialization that must complete
// *after* managed components are initialized
// TODO - add your own initialization code here
taskMap = new HashMap();
taskMap.put("progressBar1", new SimpleTask("progressBar1",
241, 100, false));
} |
This code populates the taskMap property by constructing a HashMap and adding a new SimpleTask instance to the HashMap.
Creating a Determinate Progress Bar
You use a determinate Progress Bar in cases where you can
determine the percentage of progress of a task as the task completes.
In this section, you design a page that includes a determinate Progress
Bar and two Buttons. The first Button starts, pauses, and resumes the
task associated with the Progress Bar, while the second Button stops
the task. The following figure shows how the page looks:
Figure 2: Progress Page Design |
-
In the Projects window, right-click the ProgressBarExample
> Component Libraries node and choose Add Component Library from the
pop-up menu. Select BluePrints AJAX Components and click Add Component
Library.
The IDE copies the component library into the project and adds the components to the Palette.
- Open Page1 in the Visual Designer.
-
Open the BluePrints AJAX Components section of the Palette
and drag a Progress Bar component onto the page. For this tutorial, use
the default id property of progressBar1 .
Note: The Progress Bar should display as shown in Figure 2 above. If the Progress Bar displays incorrectly,
right-click in the Visual Designer and choose Refresh from the pop-up menu.
- Drag a Grid Panel component from the Layout section of the Palette to the right of the Progress Bar.
- Set the
id property of the Grid Panel to controlPanel and the columns property to 2 .
Drag two Button components from the Basic section of the Palette onto the Grid Panel.
Make sure the outline of the Grid Layout component
is a solid blue line when you drop the Button components.
Set the following properties for the first Button:
border="0" height="2" width="1"> |
id
|
variableControl
|
text
|
Start
|
onClick
|
handleVariableControlOnClick(this, 'form1:progressBar1', false)
|
The handleVariableControlOnClick function makes JavaScript calls to start, pause, or resume the Progress Bar when the user clicks the Button.
Set the following properties for the second Button:
|
id
|
stopControl
|
text
|
Cancel
|
onClick
|
handleStopControlOnClick('form1:variableControl', 'form1:progressBar1')
|
The handleStopControlOnClick function makes a JavaScript call to stop the Progress Bar.
In the Outline window, select form1 . In the Properties window, set the form's onSubmit property to
return handleFormOnSubmit() .
This JavaScript function prevents the page from being submitted
when the user clicks either of the two Buttons.
From the Advanced section of the Palette, drag a Script component onto the page.
The Outline window shows script1 in the Page1 section. This non-visual
component declares a script element in the rendered HTML markup.
- In the Properties window, set the Script's
url property to /resources/pb.js . Note that this property
requires the leading slash (/ ).
Adding Code to the Progress Bar
In this section, you add four methods to the project's Java code. These methods perform the following actions and become
Events properties of the Progress Bar component:
- Start or resume the task indicated in the AJAX request
- Pause the task indicated in the AJAX request
- Stop the task indicated in the AJAX request
- Extract the component
id (for example, progressBar1) of the Progress Bar that sent the AJAX request
Open Page1 in the Java Editor and add the following code (in bold) after the destroy() method.
Code Sample 2: Additional Progress Bar Methods |
public void destroy() {
}
/**
* Start or resume the task indicated in the AJAX request.
*/
public void startOrResumeTask(FacesContext context) {
String taskId = getTaskIdFromAJAXRequest(context);
SimpleTask task = (SimpleTask)getSessionBean1().getTaskMap().get(taskId);
Map paramMap = context.getExternalContext().getRequestParameterMap();
String doomed = (String)paramMap.get("doomed");
task.start(Boolean.parseBoolean(doomed));
}
/**
* Pause the task indicated in the AJAX request.
*/
public void pauseTask(FacesContext context) {
String taskId = getTaskIdFromAJAXRequest(context);
SimpleTask task = (SimpleTask)getSessionBean1().getTaskMap().get(taskId);
task.pause();
}
/**
* Stop the task indicated in the AJAX request.
*/
public void stopTask(FacesContext context) {
String taskId = getTaskIdFromAJAXRequest(context);
SimpleTask task = (SimpleTask)getSessionBean1().getTaskMap().get(taskId);
task.cancel();
}
/**
* Extract the component id (for instance, "progressBar1") of the
* progress bar that sent the AJAX request.
*/
private String getTaskIdFromAJAXRequest(FacesContext context) {
Map paramMap = context.getExternalContext().getRequestParameterMap();
String progressBarClientId = (String)paramMap.get("bpui_progressbar_clientId");
if (progressBarClientId == null) {
throw new NullPointerException();
}
//get portion from last colon forward
int lastColon = progressBarClientId.lastIndexOf(NamingContainer.SEPARATOR_CHAR);
if (lastColon == -1) {
return progressBarClientId;
}
String taskId = progressBarClientId.substring(lastColon + 1);
return taskId;
}
|
When the Progress Bar sends AJAX requests to the server, it includes its client id in the
bpui_progressbar_clientId request parameter. AJAX requests to start,
pause, resume, or stop the task call the startOrResumeTask ,
pauseTask , or stopTask method in the application's page bean.
These methods call the getTaskIdFromAJAXRequest method,
which extracts the component id (such as progressBar1 )
from the bpui_progressbar_clientId request parameter.
The methods use the component id to retrieve a
SimpleTask instance from the taskMap and call
the task's start , pause , or cancel method.
Right-click in the Page1 source code and choose Fix Imports from the pop-up menu.
The IDE adds the following import statements to fix Class not found errors:
import java.util.Map;
import javax.faces.component.NamingContainer;
import javax.faces.context.FacesContext;
Return to the Design view for Page1 and set the following
properties on the Progress Bar component:
|
stopOperation
|
stopTask()
|
resumeOperation
|
startOrResumeTask()
|
startOperation
|
startOrResumeTask()
|
pauseOperation
|
pauseTask()
|
onComplete
|
function() {handleProgressBarOnComplete('form1:variableControl');}
|
As noted earlier, the handleVariableControlOnClick and
handleStopControlOnClick functions make calls to start, pause,
resume, or stop the Progress Bar when the user clicks one of the Buttons.
When such client-side scripting calls are made on the Progress Bar, an
AJAX request is sent to the server. As a result, the method
specified for the startOperation , pauseOperation ,
resumeOperation , or stopOperation is called.
The handleProgressBarOnComplete function changes the text of the first Button to "Start," in case the user wants to restart the task.
Note: In some cases, the IDE might insert an extra startOrResumeTask method in the code, which prevents the code
from compiling. To fix the error, remove the extra method.
Open the JSP view for Page1 and add the interval , percentage , failed , and percentageText
properties of progressBar1 as shown in bold below:
Code Sample 3: Properties for progressBar1 |
<bp:progressBar binding="#{Page1.progressBar1}" id="progressBar1"
interval="#{SessionBean1.taskMap.progressBar1.interval}"
percentage="#{SessionBean1.taskMap.progressBar1.percentage}"
failed="#{SessionBean1.taskMap.progressBar1.failed}"
percentageText="#{SessionBean1.taskMap.progressBar1.percentageText}"
onComplete="function() ...
resumeOperation=... |
These properties of the Progress Bar are bound to the corresponding
properties of the SimpleTask instance keyed on
progressBar1 in the taskMap .
You add this code directly to the JSP source due to limitations in the Property Editors.
Build and run the application. Click the Start button to start the task.
The Progress Bar fills as the operation progresses and the text message continually updates to indicate the percentage
of progress completed (for example, 25%).
The Start button changes to Pause.
- Continue exploring the application by clicking the Pause button (which changes to Resume) and the Cancel button.
Doing More #1: Adding an Indeterminate Progress Bar
In this section, you add an indeterminate Progress Bar, which uses motion to show that a task is under way instead
of filling the bar to show the percentage of the progress completed. An indeterminate Progress Bar is good for providing
feedback in cases where you cannot determine the amount of progress being made as the task completes. The page you build
in this section should look like the following figure:
Figure 3: Adding an Indeterminate Progress Bar |
Open the Design view of Page 1. Copy the Progress Bar and Grid
Panel components and paste the copies below the original components.
Note: This section of the tutorial uses the default id properties of progressBar2 , controlPanel1 ,
variableControl1 , and stopControl1 for these components.
Select the new Progress Bar component and change the onComplete property so that it points to variableControl1 :
function() {handleProgressBarOnComplete('form1:variableControl1');}
Select the new Start button and change the onClick property so that it points to progressBar2 :
handleVariableControlOnClick(this, 'form1:progressBar2', false)
Select the new Cancel button and change the onClick property to point to variableControl1 and
progressBar2 :
handleStopControlOnClick('form1:variableControl1', 'form1:progressBar2')
-
Open the JSP view for Page1. Find the code for progressBar2, which appears after the occurrence of the line </h:panelGrid> .
Modify the four properties of progressBar2 (shown in bold) so that they refer to progressBar2.
Code Sample 4: Properties for progressBar2 |
</h:panelGrid>
<bp:progressBar binding="#{Page1.progressBar2}"
failed="#{SessionBean1.taskMap.progressBar2.failed}" id="progressBar2"
interval="#{SessionBean1.taskMap.progressBar2.interval}"
onComplete="function() ...
percentage="#{SessionBean1.taskMap.progressBar2.percentage}"
percentageText="#{SessionBean1.taskMap.progressBar2.percentageText}"
resumeOperation=... |
Due to space constraints, several lines in the code above have been split into two lines.
Open the SessionBean1.java file and append the following line to the SessionBean1.init method.
taskMap.put("progressBar2", new SimpleTask("progressBar2", 241, 100, true));
This code adds a new SimpleTask instance to the taskMap . The second Progress Bar monitors this task. The parameter true ,
which is passed to the SimpleTask constructor, establishes that the task is indeterminate.
Build and run the project. Click the Start button you added in this section to start the indeterminate task.
A small rectangle moves left to right and a text messages displays "(time remaining unknown)"until the task completes.
Continue exploring the application by clicking the Pause,
Resume, and Cancel buttons. The following figure shows the two Progress
Bars in action.
Figure 4: Progress Bars in Action |
Doing More #2: Simulating a Failed Task
Here you modify the Progress Bar components to display a failed task.
- Open the Design view of Page1.
Change the onClick property for the variableControl button (the first Start button) so that it uses true
instead of false :
handleVariableControlOnClick(this, 'form1:progressBar1', true)
This code causes a request parameter called doomed to be sent in the AJAX request with a value of true .
The startOrResumeTask method in the page bean retrieves this parameter and passes it as an argument to SimpleTask's
start method.
Change the onClick property for the variableControl1 button (the second Start button) so that it uses true
instead of false :
handleVariableControlOnClick(this, 'form1:progressBar2', true)
Set the onFail property for progressBar1 to:
function() {handleProgressBarOnFail('form1:variableControl');}
The handleProgressBarOnFail function changes the first Button's text to "Start" when the task fails, in case the user
wants to restart the task.
Set the onFail property for progressBar2 to:
function() {handleProgressBarOnFail('form1:variableControl1');}
Build and run the project. This time the first Progress Bar fails at 25%. The second Progress Bar also fails,
although the text message does not show a percentage, because the task is indeterminate.
Doing More #3: Changing the Style of the Progress Bar
Finally, you change the style of the Progress Bar in your project's stylesheet.css file.
- Open the style sheet from the Projects window by double-clicking
the ProgressBarExample > Web Pages > resources >
stylesheet.css node.
Add the following code in bold, which changes the color and font of the Progress Bar, and then save the file.
Code Sample 5: Style Sheet Code to Set Progress Bar Color |
.bpui_progressbar_portionComplete {
background: blue !important;
}
.bpui_progressbar_portionRemaining {
background: lightgrey !important;
}
.bpui_progressbar_percentageText {
color: blue;
font-size: 14px;
font-weight: bold;
}
.bpui_progressbar_barArea {
height: 9px !important;
} |
Open the Design view of Page1 to see the changes to the Progress Bar, shown in the following figure.
Figure 5: Stylized Progress Bar |
Summary
Following are the highlights of the Progress Bar component:
- The Progress Bar supports both determinate and indeterminate
use cases. The Progress Bar interprets a percentage of -1 as
indeterminate.
- The Progress Bar supports start, pause, resume, and stop functionality through the
startOperation , pauseOperation , resumeOperation , and stopOperation events, which can be bound to methods in the page bean.
- The Progress Bar supports task failure with a boolean
failed property that can be bound.
- The Progress Bar supports custom scripting through several advanced properties, including
onComplete and onFail . You can consolidate custom JavaScript into a .js file and include a Script component that refers to the file.
- The Progress Bar supports custom styling.
Here are some tips for using the Progress Bar component, which are shown in this tutorial:
- Maintain a Map of task objects in session scope, with a different Progress Bar monitoring each task.
- Support long-running tasks in a separate thread. You can write a class that represents a particular task using
SimpleTask.java as a model. SimpleTask.java
maintains a reference to a Thread, exposes methods to start (or
resume), pause, or cancel the task, and has properties indicating the
polling interval, percentage, text, and whether the task has failed.
See Also:
Copyright and Trademark Notice
|