IBM®Rational®Application Developer Version 7 引入了几个新的 Java™Server Faces 技术 (JSF) 组件,这些组件使构建丰富的 Web 应用软件变得十分容易。您能使用的是它们之中的 ProgressBar 组件,它可以提供一个表示任务正在运行的可视化的指示。
在这个浏览器中点击一个按钮而不到任何及时的反馈,用户会感到十分沮丧。在不知道正在运行的情况时,用户很可能会不断地点击相同的这个按钮,或者重新下载这个页面,或者关闭这个应用软件。
为避免这样的问题,通常可取的办法是提供一个进度工具条形式的可视反馈,这个工具条根据运行着的任务来移动。当您有一个长期的任务时,这个组件就显得十分方便,要么在这个服务器上,要么在浏览器中,而您不会让用户对这个应用软件是否在工作表示怀疑。
您可以用 JavaScript 或者不同的图象创建一个进度工具条,但是一个 JavaServer Faces 组件可以提供所有您需要的功能。您只需要简单地将它添加到您的任何 Web 页面,而不需要做任何其它执行工作。
要使用 Rational Application Developer ProgressBar 组件,就要完成这些任务:
- 用 Faces Project 配置创建一个 Dynamic Web 项目。
- 创建一个 Web 页面。
- 从绘图板的 Enhanced Faces Components 绘图工具中将 Progress Bar 拖拽到 Web 页面。
这个组件将会显示在这个可视的 Design 视图中,它的一些特性将会显示在 Properties 视图中(参见图 1)。
图 1. 将 ProgressBar 组件添加到一个 Web 页面
ProgressBar 需要简单的 JavaScript 命令来控制它的行为。因此,当您把这个组件添加到 Web 页面,您仍需要添加一些 JavaScript 代码行,这取决于您将如何使用这个 ProgressBar。文章的剩余部分将阐述并示范如何操作这些情况。
Rational Application Developer ProgressBar 组件有两种操作模式:自动操作和手动操作。
- 在自动操作模式中启动以后,这个进度工具条将会不断地更新这个任务的状态,直到使用特殊的时间间隔和百分数增长值使它停止为止。这个工具条可以要么从左到右移动,要么从中央向外面移动。这种模式在这样几种情形下是有用的,您可以知道一项任务何时开始以及何时停止,但是您没法知道任务进展了多远。 在这种模式中,您可以使用两个 JavaScript 命令来控制 ProgressBar:
开始()和stop()。它们的名称都是自我解释型的:您用一个start()命令开始一个进展,用一个stop()命令将它停止。两种方法都可以使用一个字符串参数作为消息文本显示在上面的工具条中。 - 在手动操作模式中,这个进度工具条不会独立地移动。相反,您需要通过使用一个 JavaScript 命令
upDatePercentage(integer)手动更新它的值。您可以提供 0(零)和 100 之间的任何值来来反映完成的百分数(例如,10 表示完成了10%)。当您准确知道任务完成的进度时这种模式是很有用的,它能够在视觉上描绘进展情况(“可视化”这个进展)。
要访问代表 ProgressBar 的 JavaScript 对象,您可以使用在 Rational Application Developer JavaScript 库中可以使用的 getComponentById(id) 帮助方法。例如,如果您想要这个进展在用户点击一个按钮时开始,您可以在一个按钮上添加一个 onclick 事件,使用您在列表 1中所看到的代码。
列表 1.添加一个 onclick 事件到用户界面的按钮上
onclick="hX.getComponentById('form1:bar1').start('Please wait...');" |
您传递到 getComponentById() 功能函数的 ID 是 ProgressBar 的客户 ID,像是由 JSF 发出的,而不是您在 Java™Server Page (JSP) 中分配的组件 ID。根据 ProgressBar 在这个页面的位置,它的客户 ID 将会变化。例如,如果这个
ID 为 bar1 的 ProgressBar 在一个 ID 为 form1 的内部,那么它的客户 ID 将会是 form1:bar, 如先前代码片段中显示的那样(列表 1)。
表格 1列出了 ProgressBar 组件所有可使用的 JavaScript 程序。
表格 1. ProgressBar 组件的 JavaScript 程序
| 方法 | 描述 |
|---|---|
| start(string) | 在自动操作模式中,启动这个进度工具条使它运行,并将消息文本更改为字符串的值。如果您不想要消息,请不要传递参数。 |
| stop(string) | 在自动操作模式中, 停止这个进度工具条的运行,并将消息文本更改为字符串的值。如果您不想要消息,请不要传递参数。 |
| reset() | 将这个工具条的显示值重置为零。 |
| upDatePercentage(integer) | 在手动模式中,将进度工具条的值更新为整数。这个整数必须在0 (零) 和100之间。这个范围之外的值都会分别朝不同的方向分离。 |
| upDateMessage(string) | 更改显示在这个工具条之上的消息。如果您想要清除这个消息,不要传递任何参数。 |
| redraw() | 重置组件,认真考虑对这些属性或者性质的任何更改。无论何时您更改一个属性 (disabled例如) 或者性质 (比如,类型:宽度),都应该联合可见的(), 隐藏(), 重置(), upDatePercentage()以及upDateMessage()方法。 |
| hide() | 隐藏这个进度工具条。 |
| visible() | 使进度工具条可见。 |
| percentageDone | 使当前的进度工具条是只读状态。 使用 upDatePercentage() 来更改值。 |
这篇文章附有一个范例项目文件,称作 ProgressBarSample.zip。它显示了 ProgressBar 在两种模式下的使用以及在不同情景下的使用。下一部分描述了各种样例。
附件中样本项目的 Basic.jsp 页面论证了自动操作和手动操作模式中的 ProgressBar 组件。自动工具条上附有 Start 和 Stop 按钮,手动工具条上附有 Advance 和 Reset 按钮。让我们了解一下这些进度工具条是如何被定义的,以及这些按钮有哪些功能。
自动进度工具条看起来如列表 2 中的 JSP 源代码。
列表 2. 自动 ProgressBar
<hx:progressBar auto="true" timeInterval="500"
proportion="5" id="bar1"
styleClass="progressBar"
message="Automatic progress bar. Press Start to start." />
|
表格 2中显示的 <hx:progressBar> 标记的属性定义了这个工具条在运行时间是如何运转的。
提示:
您可以在这篇文章末尾的如何定制 ProgressBar 组件部分找到 ProgressBar 属性完整的列表。
表格 2. hx:progressBar 标签的属性和运行时间的功能
| 属性 | 运行时操作 |
|---|---|
| auto="start" | ProgressBar 在自动模式中运行 |
| timeInterval="500" | 工具条每500毫秒更新一次 |
| proportion="5" | 工具条每次移动5% |
除此之外,styleClass属性向用户详细说明了工具条外观情况,message属性提供了显示在工具条之上的文本。
进度工具条下面的 Start 和 Stop 按钮是普通的 JSF 按钮,通过onclick事件控制着这个工具条(参见列表 3)。
列表 3.Start 和 Stop 按钮控制器
<hx:commandExButton type="button" value="Start" id="button1"
styleClass="commandExButton" onclick="startPB()"
/>
<hx:commandExButton type="button" value="Stop" id="button2"
styleClass="commandExButton" onclick="stopPB()"
/>
|
重点:
注意这个按钮的类型设置为 button 而不是默认情况的 submit。这是十分重要的,因为您不想这个按钮向服务器提交任何事件;您只不过是想调用这个浏览器中的一个 JavaScript 功能。
列表 4 显示了 JavaScript 开始和停止工具条的功能。
列表 4. JavaScript 功能
function startPB() {
pb=hX.getComponentById('form1:bar1');
pb.start('Press Stop to stop');
}
function stopPB() {
pb=hX.getComponentById('form1:bar1');
pb.stop('Press Start to restart');
pb.reset();
}
|
首先通过使用 getComponentById() 命令,两种功能都有权访问 ProgressBar 目标,然后它们可以在目标执行它们相应的操作。
这个页面中的手动进度工具条十分相似,正如您在列表 5中所看到的。
列表 5.手动 ProgressBar 的基本代码
<hx:progressBar auto="false" id="bar2"
styleClass="progressBar"
message="Manual progress bar. Press Advance to move by 5%. Press Reset to reset to 0%" />
|
注意:
注意这个手动工具条的 auto 属性设置为 false,它既没有使用设置在这个自动工具条上的 timeInterval 也没有使用 proportion 属性。
控制这个手动进度工具条的按钮与列表 5中使用的是一样的,先前是使用列表 6中的 JavaScript 代码来控制这个组件的:
列表 6.JavaScript 代码控制 ProgressBar 组件
function advancePB() {
pb=hX.getComponentById('form1:bar2');
pb.upDatePercentage(pb.percentageDone + 5);
pb.redraw();
}
function resetPB() {
pb=hX.getComponentById('form1:bar2');
pb.upDatePercentage(0);
pb.redraw();
}
|
在这里,您又会执行以下的三个步骤:
- 首先,用
getComponentById()命令找到 ProgressBar 目标。 - 然后通过使用
upDatePercentage命令和指定一个新值来设置这个进展行为。 这个resetPB功能值设置为零,然而,在advancePB命令中,您首先获得一个当前状态(pb.percentageDone) 然后以5%的幅度增加。 - 当您完成这些以后,您需要通过使用
redraw()命令,在这个屏幕中更新这个手动进度工具条。
图 2. 这个阶段的 basic.jsp 页面
这个 basic.jsp 页面很好地演示了 ProgressBar 组件,但是它几乎不能适用于现实状况的 Web 应用软件,因为没有任务来显示进度工具条。在下一个部分中,您将看到更多现实的例子。
从附加的样本项目中打开auto.jsp页面。这个页面有一个发起服务器上时间消耗的按钮。当用户点击这个按钮时,服务器要等待10秒钟来应答这个浏览器。在一个现实的应用软件中,这个服务器可能会忙于询问一个数据库,处理一个路由,或者执行一些类似需要消耗一些时间来完成的工作。即使您不知道这个服务器要花费多长时间来应答,但是您可以让用户明白这个任务正在运行而且需要等待一段时间。
要达到这个目的的方法之一是显示一个自动进度工具条,它会一直运行直到服务器应答以及页面得到刷新为止。这个页面的按钮和这个进度工具条(参见列表 7) 与您先前在 basic.jsp 页面见到的十分相似。
列表 7. 服务器要花费时间来完成的任务的进度工具条的配置
<hx:progressBar
auto="true" timeInterval="50" proportion="1"
id="bar1" styleClass="progressBar"
initHidden="true" />
|
这个标签引起一个自动进度工具条每50毫秒移动1% 。它起初还是隐藏的状态(通过使用 initHidden属性),直到用户点击这个按钮才变的可见。
列表 8. 服务器需要花时间来完成的任务的按钮
<hx:commandExButton type="submit" id="button1"
value="Perform a time consuming action"
styleClass="commandExButton"
onclick="startPB()"
action="#{pc_Auto.doButton1Action}" />
|
这个按钮发起了服务器上的一个按钮 (action 属性) ,同时,在这个浏览器中启动了这个进度工具条(onclick 属性)。它使用显示在列表 9中的 JavaScript 功能来完成。
列表 9.启动这个任务和进度工具条的代码
function startPB() {
pb=hX.getComponentById('form1:bar1');
pb.visible();
pb.start('Please wait while your action is being executed on the server...');
}
|
您已经熟悉了getComponentById() 和 start() 程序。此外,这个按钮调用 visible() 使用户能够看到这个进度工具条。
图 3. 更新 auto.jsp 页面
从这个附加的样本项目中打开 manual.jsp 页面。这个页面示范了一个使用在抽象的面向客户的环境中的 ProgressBar 组件,并且与服务器没有任何交互作用。这样的情景在要求用户执行许多的操作或者步骤的页面中会经常见到,比如填写一个较大的表格或者进行一个测试。
作为一个例子,这个 manual.jsp 页面要求用户解答四个简单的数学公式。一旦其中的一个答案被修改,这个进度工具条将会更新反映有多少答案是正确的,并显示出整个进度。
要构建这个页面,您要使用手动模式中的一个 ProgressBar 组件,与您在 basic.jsp 页面中使用的十分相似(列表 10)。
列表10. 创建一个手动进度工具条
<hx:progressBar auto="false" id="bar1"
styleClass="progressBar"
message="Progress: You completed 0 out of 4 tasks" />
|
每一个输入域都将使用 onkeyup 事件调用一个 JavaScript 功能来更新这个进展工具条(列表 11)。
列表 11. 当 onkeyup 事件发生时更新这个进度工具条
<h:inputText id="text2" styleClass="inputText" size="2"
onkeyup="updatePB()" />
|
JavaScript 代码将通过改变百分数和消息文本来验证答案,并因此对进度工具条进行更新(参见列表 12)。您可以在图 4中观察到结果。
列表 12. JavaScript 更新进度百分数和消息
function updatePB() {
v1=hX.getElementById('form1:text2').value;
v2=hX.getElementById('form1:text4').value;
v3=hX.getElementById('form1:text6').value;
v4=hX.getElementById('form1:text8').value;
done=0;
if(v1=='4') done=done+1;
if(v2=='56') done=done+1;
if(v3=='9') done=done+1;
if(v4=='12') done=done+1;
pb=hX.getComponentById('bar1');
pb.upDatePercentage(done*25);
pb.upDateMessage('Progress: You completed ' + done + ' out of 4 tasks');
pb.redraw();
}
|
图 4. 更新之后的手动模式
在早期的例子中(auto.jsp,图 3),有一个长期运行的面向服务器的任务,而您并不清楚这个任务将花费多长时间来完成,以及这个任务已经进展了多少的情况。因此,使用一个自动的 ProgressBar 是十分恰当的,它将一直保持运行直到服务器完成这项任务。
您经常会发现自己处在不同的情形下,在这种情形下您的面向服务器的代码能够准确地监控事件是怎样运行的,任务已经完成了多少,以及这项任务要花费多长时间才能完成。例如,您可能正在一行一行地处理数据,您可以知道一共有多少行以及您已经处理多少行的情况。在这种情况下,如果浏览器中的工具条能够根据面向服务器的状态进行更新,而不是盲目地运行,这将十分有用。那也就是说,如1000行中已经处理了300行,那么这个工具条将正确地显示30%的百分数。
要实现这个功能,您需要使用 AJAX 技术使这个浏览器与服务器进行通信(异步的 JavaScript 和 XML,通常称作 Ajax)。附加的样本项目中的 ajax.jsp 页面将向您展示如何进行操作。
首先,您要添加一个 ProgressBar 组件,使用您在列表 13中见到的代码。
列表 13. 添加一个 ProgressBar 组件来更新服务器行为
<hx:progressBar auto="false" id="bar1"
styleClass="progressBar"
message="Server reports progress..." />
|
由于您并不想使进度工具条任其自然地保持运行,因此您要人工将 auto 属性设置为 错误的。起初这样做的效果可能并不明显 -- 毕竟,您也没有真正做到每次都人工地进行更新。然而,由于这个进度将通过一个 JavaScript 功能进行设置,因此在这里您的确需要手动模式。
要使服务器能够报告运行任务的状态,您要创建一个保存这些状态(当前进度的百分数)的隐藏的输入域,并将这个域置入可以通过 Ajax 进行更新的一个面板中。
列表 14. 添加一个隐藏的域到 Ajax 面板使服务器进行更新
<h:panelGroup id="group1">
<h:inputHidden id="hidden1"
value="#{pc_Ajax.pbValue}" />
</h:panelGroup>
<hx:ajaxRefreshRequest id="ajaxRefreshRequest1"
target="group1"
oncomplete="movePB()" params="text1" />
|
现在这个隐藏域中的值可以通过使用 Ajax 进行更新。每次当这个浏览器向服务器发送一个 Ajax 请求时,pbValue 属性的获取程序并将被执行,无论返回的值是多少都会被置入这个浏览器中隐藏的域中。在这个样本应用软件中,pbValue 的获取程序仅仅在这个部分保存着一个计数器,并在获取程序调用时计数会增加。在这个页面还有一个 Reset 按钮能够将计数器的值重置为零。
发送一个 Ajax 请求最简单的方法是,当用户点击这个按钮时,按钮就会执行这个任务(参见列表 15)。
列表 15. 列于最大宽度的样本代码
<hx:commandExButton type="button" id="button1"
style="display:none"
styleClass="commandExButton">
<hx:behavior event="onclick" id="behavior1"
behaviorAction="get"
targetAction="group1" />
</hx:commandExButton>
|
切记,这个按钮的目的是在进度工具条上自动激发 Ajax 刷新行为。因此,您可以通过将 style 属性设置为 display:none 来使按钮不可见。为了自动开始 Ajax 刷新的行为,您将在这个按钮上设置一个 JavaScript 计时器(列表 16)。
列表 16. JavaScript 片段在用户界面按钮上安装一个计时器
function poll() {
document.getElementById('form1:button1').click();
}
setInterval("poll();", 1000);
|
JavaScript 片段确保 poll() 功能每秒运行一次。所有的 poll() 功能所执行的行为都是模拟点击按钮的行为。点击行为将 Ajax 请求发送给服务器,服务器返回当前的进度状态,隐藏的域也会随之更新。所有这些行为的发生都不需要用户的交互作用。
当您当前的进度在隐藏的输入域中更新之后,剩余的任务就是更新相应的 ProgressBar 组件。不知您是否注意到,Ajax 标签也有一个与之关联的 JavaScript 功能,如列表 17 所示。
列表 17. 列在最大幅度的样本的代码
<hx:ajaxRefreshRequest id="ajaxRefreshRequest1"
target="group1"
oncomplete="movePB()" params="text1" />
|
这个oncomplete 事件会在服务器每次应答 Ajax 请求的时候运行一次。一旦运行,您就可以获得隐藏域中的值和更新的进度工具条(参见 列表 18)。图 5 在用户界面显示了这个效果。
列表 18. 使用隐藏域中的值来更新进度工具条
function movePB() {
v=hX.getElementById('form1:hidden1').value;
pb=hX.getComponentById('form1:bar1');
pb.upDatePercentage(v);
pb.redraw();
}
|
图 5. ajax.jsp
您可以使用排列在表格 3中的属性来自定义 ProgressBar 组件的行为。
表格 3. 主要的 ProgressBar 属性
| 属性 | 操作 |
|---|---|
| auto | 如果是 true 就是自动模式,如果是false就是手动模式。默认情况下是false。 |
| initHidden | 如果是true,当这个页面最初是显示的状态时,这个工具条就会隐藏。默认情况是false。 |
| message | 这个消息将显示在工具条之上。 |
| outward | 如果是正确的,那么这个进度工具条就会从中央向外移动。如果是 false,这个工具条就会从左向右移动。默认情况是 false。 |
| proportion | 如果是自动模式,工具条上显示的完成总量(进度工具条宽度的百分比)就会在每次更新后增加。默认情况增量是5。 |
| initValue | 在手动模式中,工具条显示的总量(百分数)是最初所显示的。默认情况是0(零)。 |
| timeInterval | 在自动模式中,工具条的时间间隔(频率)是不断更新的。具体到毫秒。默认情况是1000毫秒。 |
进度工具条的显示是由表格 4显示的 CSS 类来控制的。
表格 4. ProgressBar 类
| CSS 类 | 目的 |
|---|---|
| <base> | 这个类的名称可以在 ProgressBar 组件的 styleClass 属性中进行设置。默认的名称为 progressBar。这个类称作整个进度工具条控制(可控制的div)。 |
| <base>-Table | 设计标出进度工具条的表格。 |
| <base>-Message | 设计保存消息文本的区域。 |
| <base>-Bar | 设计移动条。 |
| <base>-Bar_container | 设计包含移动工具条和百分比文本。 |
| <base>-Bar_text | 设计百分比文本。 |
要获得更多关于 Rational Application Developer 最新特性的信息,将它与 Ajax 和 Java 技术一起使用的信息,以及相关的信息,请查看参考资料。
| 描述 | 名字 | 大小 | 下载方法 |
|---|---|---|---|
| Sample ProgressBar application for this article | ProgressBarSample1.zip | 4.9MB | HTTP |
学习
- 您可以参阅本文在 developerWorks 全球网站上的 英文原文。
- “在 Rational Application Developer V7 中利用JSF、AJAX 和Web 服务提高带有预输入字段的 Web 应用程序的可用性”(developerWorks,2007 年 4 月)。
- “IBM Rational Application Developer V7.0 新特性”(developerWorks,2007 年 2 月)。
- “JSF 和 Ajax:使用 Rational Application Developer V7 轻松实现 Web 2.0 应用程序”。Ajax 是当今应用在 Web 上最普遍的技术,因为它是通常所说的 Web 2.0 的基础。不幸的是,创建一个 Ajax 应用软件并不是一件容易的事情,尤其是当您需要将它与另一个框架整合在一起特别不简单,比如 JavaServer™ Framework (JSF)。幸运的是,IBM Rational Application Developer V7 版本为 JSF 组件提供了 Ajax 功能,使得这项工作容易多了。这篇文章说明了如何在 Rational Application Developer V7 中使用 Ajax 和 JSF ,还带领您浏览了将 Ajax 支持添加到现存应用软件中的例子(developerWorks,2007 年 4月)。
- 要获取技术资源,可以访问 developerWorksRational Application Developer 产品资源页面。您将找到技术文档,教程指南,培训资料,下载信息,产品信息等等。
- 订阅developerWorks Rational 专区时事通讯。时刻关注 developerWorks Rational 内容。每隔一周,您将收到关于最新技术资源的更新,以及 Rational Software Delivery Platform 的最佳实践。
- 浏览技术书店寻找一些有关这些以及其它技术课题的书籍。
- 时刻关注 developerWorks 技术活动和网络广播。
获得产品和技术
- 下载 Rational Application Developer 的免费试用版。
- 下载IBM 产品评估版,并了解 DB2®、Lotus®、 Rational®、Tivoli®,以及 WebSphere® 的应用软件开发工具和中间件产品。
讨论
- 查看 developerWorks Blogs ,并参与到developerWorks 社区。
-
Rational Software Architect、 Data Architect、Software Modeler、Application Developer 以及 Web Developer 论坛:提出有关 Rational Application Developer 的问题。
