本教程介绍了如何通过 Sun Java Studio Creator 的集成开发环境 (Integrated Development Environment, IDE) 构建一个使用 Java BluePrints AJAX 进度栏组件样例的 Web 应用程序。此外,本教程还介绍了一些进度栏的应用实例。首先,您需要为可以确定任务进度的用例配置进度栏。在本例中,进度栏将通过百分比来表示任务的完成进度。接下来,您需要为任务进度不确定的用例配置进度栏。对于这种情况,进度栏并不使用百分比来表示任务的完成进度,而只表示某项任务正在进行当中,这是因为此任务的进度情况是未知的。最后,您需要配置一个用于处理失败任务的进度栏。 通过 IDE 中提供的样例 Java BluePrints AJAX 组件,可以帮助您了解 AJAX 技术并能很好地说明 AJAX 是如何与 Java Studio Creator IDE 结合使用的。有关 AJAX 技术的相关说明,请参见 AJAX 和 Sun Java Studio Creator 2。 |
| 目录
|
![[spacer]](/im/a.gif) |
 |
设置应用程序
在本教程中,首先将 Java BluePrints AJAX 组件导入到 IDE 中。然后创建一个项目,并添加两个文件:SimpleTask.java 和 pb.js。SimpleTask.java 将模拟一个在单独线程中执行的服务器端任务。无论用户何时启动(或重新启动)此任务,SimpleTask.java 中的 start 方法都会产生一个新的线程,该线程或者休眠,或者递增计数器的值。pb.js 文件包含了一些函数,供应用程序中与 JavaScript 相关的组件属性调用。这些属性包括进度栏的 onComplete 和 onFail 属性、按钮的 onClick 属性和表单的 onSubmit 属性。
- 下载并导入最新版本的 AJAX 组件(如果您尚未执行此操作)。
注意:本教程使用了最新版本的进度栏组件。要了解您是否使用了最新的版本,请将组件拖至页面上并在其“属性”窗口的“事件”类别下验证是否存在 pauseOperation 和 resumeOperation 属性。
- 下载
SimpleTask.java 和 pb.js 并将它们保存到您的文件系统中。
- 创建一个新的 Web 应用程序项目,并将其命名为
ProgressBarExample。 将在可视设计器中打开 ProgressBarExample 的初始页。
- 按照以下操作,将
SimpleTask.java 添加到项目中:
- 在主菜单中,选择“文件”>“添加现有项”>“Java 源代码”。导航至您保存
SimpleTask.java 所在的目录。选中该文件并单击“添加”。IDE 会将 SimpleTask 类添加到 ProgressBarExample 包中。
- 在“项目”窗口中双击 SimpleTask.java 节点,将以下包语句添加到源代码中:
package progressbarexample;
- 在主菜单中,选择“生成”>“编译 "SimpleTask.java"”。
- 关闭项目,然后再重新打开项目。执行此步骤后才可以在设计时使用
SimpleTask 类。
- 按照以下操作,将
pb.js JavaScript 文件添加到项目中:
- 选择“文件”>“添加现有项”>“其他(所有文件)”。导航并选择
pb.js,然后单击“添加”。在“项目”窗口中,您会注意到 pb.js 位于“源包”> "progressbarexample" 节点下。
- 右键单击
pb.js,然后从弹出式菜单中选择“剪切”。
- 展开“Web 页”节点,右键单击 "resources" 节点并选择“粘贴”。
pb.js 文件会被移动至“Web 页”> "resources" 节点下。
修改会话 Bean
接下来,您将添加并配置该项目的会话 Bean 属性。
- 如有必要,请在可视设计器中打开 Page1,这样“概要”窗口就会处于可见状态。
- 在“概要”窗口中,右键单击 "SessionBean1" 节点,然后选择“添加”>“属性”。
- 对于出现的“新建属性模式”对话框,在“名称”文本框中键入
taskMap,在“类型”文本框中键入 HashMap(请注意“名称”和“类型”字段是区分大小写的),并将“模式”设置为只读,如下图所示。单击“确定”。
图 1:“新建属性模式”对话框 |
- 双击 "SessionBean1" 节点可打开源文件。
代码中出现的错误标注表明未找到 HashMap 类。
- 在
SessionBean1.java 中的任意位置单击鼠标右键,并从弹出式菜单中选择“修复导入”以自动添加下列 import 语句:
import java.util.HashMap;
- 将下面以粗体显示的代码行附加到
SessionBean1.init 方法的结尾处。
| 代码样例 1:SessionBean1 属性 |
public void init() {
// 执行从超类继承的初始化
super.init();
// 执行必须在初始化受管组件
// *之前*完成的应用程序初始化
// 待做事项 - 在此处添加您自己的初始化代码
Creator 管理的组件初始化
// 执行必须在初始化受管组件
// *之后*完成的应用程序初始化
// 待做事项 - 在此处添加您自己的初始化代码
taskMap = new HashMap();
taskMap.put("progressBar1", new SimpleTask("progressBar1",
241, 100, false));
} |
此代码通过构造 HashMap 并将一个新的 SimpleTask 实例添加到 HashMap 中,来填充 taskMap 属性。
创建一个任务进度确定的进度栏
如果您可以确定完成任务的百分比进度,则使用任务进度确定的进度栏。在本部分,您将设计一个包含任务进度确定的进度栏和两个按钮的页面。第一个按钮用于启动、暂停和重新启动与进度栏相关的任务,第二个按钮用于停止该任务。页面如下所示:
图 2:进度页的设计 |
- 在可视设计器中打开 Page1。
- 从组件面板的 "BluePrints AJAX Components" 类别中,将一个 "Progress Bar" 组件拖至页面上。在本教程中,将使用
progressBar1 这一缺省的 id 属性。
注意:"Progress Bar" 组件应如上图 2 中所示。如果 "Progress Bar" 组件显示不正确,请在可视设计器中单击鼠标右键并从弹出式菜单中选择“刷新”。
- 从组件面板的“布局”类别中拖动一个“网格面板”组件,将其放置在 "Progress Bar" 组件的右侧。将“网格面板”的
id 属性设置为 controlPanel,并将 columns 属性设置为 2。
- 从组件面板的“基本”类别中拖动两个“按钮”组件放置到“网格面板”上。请确保在放置“按钮”组件时,“网格面板”组件的外框呈蓝色实线。
- 为第一个按钮设置以下属性:
 |
id
|
variableControl
|
text
|
Start
|
onClick
|
handleVariableControlOnClick(this, 'form1:progressBar1', false)
|
handleVariableControlOnClick 函数将调用 JavaScript 以便在用户单击按钮时启动、暂停和重新启动进度栏。
- 为第二个按钮设置以下属性:
 |
id
|
stopControl
|
text
|
Cancel
|
onClick
|
handleStopControlOnClick('form1:variableControl', 'form1:progressBar1')
|
handleStopControlOnClick 函数将调用 JavaScript 来停止进度栏的运行。
- 在“概要”窗口中,选中
form1。在“属性”窗口中,将表单的 onSubmit 属性设置为 return handleFormOnSubmit()。 此 JavaScript 函数会在用户单击其中任一按钮时阻止提交页面。
- 从组件面板的“高级”类别中,将一个 "Script" 组件拖至页面上。
“概要”窗口将在 "Page1" 部分的下面显示 "script1"。这一不可见的组件用于在呈现的 HTML 标记中声明 script 元素。
- 在“属性”窗口中,将 "Script" 组件的
url 属性设置为 /resources/pb.js。请注意此属性需要一个前导的正斜杠 (/)。
为进度栏添加代码
在本部分,您将为项目的 Java 源代码添加四个方法。这些方法用于执行以下操作并成为 "Progress Bar" 组件的“事件”属性。
- 启动或重新启动 AJAX 请求中指示的任务。
- 暂停 AJAX 请求中指示的任务。
- 停止 AJAX 请求中指示的任务。
- 提取发送 AJAX 请求的 "Progress Bar" 组件的
id(例如,progressBar1)。
- 在 Java 编辑器中打开 Page1,并在
destroy() 方法后添加下面以粗体显示的代码。
| 代码样例 2:其他进度栏方法 |
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;
} }
|
在进度栏向服务器发送 AJAX 请求时,它会将其客户端 ID 包含在 bpui_progressbar_clientId 请求参数中。启动、暂停、重新启动或停止任务的 AJAX 请求将调用应用程序页面 Bean 的 startOrResumeTask、pauseTask 或 stopTask 方法。这些方法会调用 getTaskIdFromAjaxRequest 方法,该方法将提取 bpui_progressbar_clientId 请求参数中的组件 id(如 progressBar1)。这些方法使用组件 id 来检索 taskMap 中的 SimpleTask 实例,然后调用此任务的 start、pause 或 cancel 方法。
- 在 Page1 的源代码中单击鼠标右键,然后从弹出式菜单中选择“修复导入”。
IDE 将添加以下 import 语句来修复“找不到类”的错误:
import java.util.Map;
import javax.faces.component.NamingContainer;
import javax.faces.context.FacesContext;
- 返回到 Page1 的设计视图,为 "Progress Bar" 组件设置以下属性:
 |
pauseOperation
|
pauseTask()
|
resumeOperation
|
startOrResumeTask()
|
startOperation
|
startOrResumeTask()
|
stopOperation
|
stopTask()
|
onComplete
|
function() {handleProgressBarOnComplete('form1:variableControl');}
|
如上文所述,handleVariableControlOnClick 和 handleStopControlOnClick 函数在用户单击上述任一按钮时会发出调用来启动、暂停、重新启动或停止进度栏。在对进度栏执行此类客户端脚本调用的同时,会将 AJAX 请求发送到服务器中。结果是:将调用特定于 startOperation、pauseOperation、resumeOperation 或 stopOperation 的方法。
handleProgressBarOnComplete 函数会将第一个按钮的文本内容改为 "Start",以便用户可以重新启动该任务。
- 打开 Page1 的 JSP 视图,然后添加 progressBar1 的
interval、percentage、failed 和 percentageText 属性,如以下粗体内容所示:
| 代码样例 3:ProgressBar1 的属性 |
<ui:form binding="#{Page1.form1}" id="form1" onSubmit="return handleFormOnSubmit()">
<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=... |
进度栏的这些属性与 SimpleTask 实例的相应属性进行了绑定,其中 SimpleTask 实例由 taskMap 中的 progressBar1 来控制。由于属性编辑器的局限性,您只能将这些代码直接添加到 JSP 源代码中。
- 生成并运行该应用程序。单击 "Start" 按钮启动任务。
进度栏将随着任务的进展情况填充进度,并且文本消息也会随之不断地更新以表示任务完成的进度百分比(例如 25%)。"Start" 按钮会变为 "Pause"。
-
单击 "Pause" 按钮(会变为 "Resume")和 "Cancel" 按钮,继续观察应用程序的运行情况。
执行更多的操作 #1:添加一个任务进度不确定的进度栏
在本部分,您将添加一个任务进度并不确定的进度栏,它通过移动的方式来表示任务正在进行中,而不是通过填充进度栏来显示任务完成的百分比情况。如果您无法确定任务完成的具体进度情况,则使用任务进度不确定的进度栏是一种较好的方式。本部分构建的页面应如下图所示:
图 3:添加一个任务进度不确定的进度栏 |
- 打开 Page1 的设计视图。复制 "Progress Bar" 和“网格面板”组件并将它们粘贴到原组件的下方。
注意:此部分的教程将使用这些组件的缺省 id 属性:progressBar2、controlPanel1、variableControl1 和 stopControl1。
- 选中新的 "Progress Bar" 组件并更改
onComplete 属性,使其指向 variableControl1: function() {handleProgressBarOnComplete('form1:variableControl1');}
- 选中新的 "Start" 按钮并更改
onClick 属性,使其指向 progressBar2: handleVariableControlOnClick(this, 'form1:progressBar2', false)
- 选中新的 "Cancel" 按钮并更改
onClick 属性,使其指向 variableControl1 和 progressBar2: handleStopControlOnClick('form1:variableControl1', 'form1:progressBar2')
- 打开 Page1 的 JSP 视图。找到 progressBar2 的代码,该代码位于第一次出现
</h:panelGrid> 行的后面。修改 progressBar2 的四个属性(以粗体显示),使它们与 progressBar2 关联。
| 代码样例 4: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=... |
由于空间的限制,上述代码中的某些行已被分成两行来表示。
- 打开
SessionBean1.java 文件,在 SessionBean1.init 方法的结尾处附加以下行: taskMap.put("progressBar2", new SimpleTask("progressBar2", 241, 100, true)); 此代码会将新的 SimpleTask 实例添加到 taskMap 中。第二个进度栏将监视该任务。参数 true 将传递至 SimpleTask 构造函数,表明这是一个进度不确定的任务。
- 生成并运行该项目。单击本部分添加的 "Start" 按钮来启动进度不确定的任务。
一个小的矩形框将从左向右移动,并出现一条文本消息 "(time remaining unknown)"(时间未知),直至任务完成为止。
- 单击 "Pause"、"Resume" 和 "Cancel" 按钮,继续观察应用程序的运行情况。下图显示了正在运行的两个进度栏。
图 4:运行中的进度栏 |
执行更多的操作 #2:模拟一个失败的任务
下面您可以修改进度栏组件来显示一个失败的任务。
- 打开 Page1 的设计视图。
- 更改 variableControl 按钮(第一个 "Start" 按钮)的
onClick 属性,以便它使用 true 而不是 false: handleVariableControlOnClick(this, 'form1:progressBar1', true) 通过此代码,一个名为 doomed 的请求参数将以 true 值的方式随 AJAX 请求一起发送。页面 Bean 中的 startOrResumeTask 方法将检索该参数并将其作为一个参数传递给 SimpleTask start 方法。
- 更改 variableControl1 按钮(第二个 "Start" 按钮)的
onClick 属性,以便它使用 true 而不是 false: handleVariableControlOnClick(this, 'form1:progressBar2', true)
- 为 progressBar1 设置
onFail 属性: function() {handleProgressBarOnFail('form1:variableControl');} handleProgressBarOnFail 函数会在任务失败时将第一个按钮的文本内容更改为 "Start",以便用户可以重新启动该任务。
- 为 progressBar2 设置
onFail 属性: function() {handleProgressBarOnFail('form1:variableControl1');}
- 生成并运行项目。
此时第一个进度栏在进度达到 25% 时运行失败。第二个进度栏表示的是一个进度不确定的任务,虽然其文本消息未说明任务进度的百分比,但它也同样运行失败了。
执行更多的操作 #3:更改进度栏的样式
最后,您将在项目的 stylesheet.css 文件中更改进度栏的样式。
- 通过在“项目”窗口中双击 "ProgressBarExample" >“Web 页”> "resources" 下的 "stylesheet.css" 节点,可以打开样式表。
- 添加下面以粗体显示的代码(将会更改进度栏的颜色和字体),然后保存文件。
| 代码样例 5:用于设置进度栏颜色的样式表代码 |
.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;
} |
- 打开 Page1 的设计视图以查看进度栏的变化,如下图所示。
图 5:运行中样式更改后的进度栏 |
小结
现将进度栏组件的重要功能归纳如下:
- 进度栏组件既支持任务进度确定的用例,也支持任务进度不确定的用例。进度栏组件会将 -1% 解释为不确定的任务进度。
- 通过
startOperation、pauseOperation、resumeOperation 和 stopOperation 事件(将其与页面 Bean 中的方法绑定),进度栏组件支持启动、暂停、重新启动和停止功能。
- 通过一个可绑定的布尔型
failed 属性,进度栏组件还提供任务失败支持。
- 通过
onComplete 和 onFail 等一些高级的属性,进度栏组件支持定制的脚本功能。您可以将定制的 JavaScript 合并到 .js 文件中,然后使用一个引用该文件的 Script 组件。
- 同时,进度栏组件还提供样式定制支持。
以下是本教程提供的有关使用进度栏组件的一些提示:
- 在会话范围内维持一个任务对象的映射,即一个进度栏监视一项任务。
- 支持长时间运行的任务使用单独的线程。您可以将
SimpleTask.java 作为模型编写用于表示特定任务的类。SimpleTask.java 维持了对线程的引用,并通过方法调用来启动(或重新启动)、暂停和取消任务,此外,它还具有表示轮询时间间隔、进度百分比、文本内容以及任务是否失败的属性。
另请参见:
更多的开发者资源:
有关为开发者提供的更多教程、文章、提示、论坛、更新和专家建议,请访问 Sun Developer Network (SDN) 上的 Java Studio Creator 开发者资源,网址为 http://gceclub.sun.com.cn/prodtech/javatools/jscreator/。
此页的最新修改时间:2006 年 7 月 17 日
|