ProgressBar的值
IBM®Rational®Application Developer版本7引入了几个新的Java™Server Faces技术(JSF)组件,这些组件使构建富Web应用程序变得更加容易。 其中有一个ProgressBar组件,您可以使用该组件以直观的方式指示任务正在运行。
对于用户而言,单击浏览器中的按钮而没有立即获得任何反馈可能会非常令人沮丧。 不知道发生了什么,用户可能会尝试一次又一次单击同一按钮,或者重新加载页面,或者关闭应用程序。
为了避免此类问题,通常建议以进度条的形式提供视觉反馈,该进度条会根据正在运行的任务的进度进行移动。 当您在服务器或浏览器中执行长期任务时,此组件非常方便,并且您不想让用户怀疑应用程序是否正常运行。
您可以使用JavaScript或其他图像创建进度条,但是JavaServer Faces组件提供了所需的所有功能。 您可以简单地将其添加到您的任何网页中,而无需执行任何实现工作。
如何添加ProgressBar
要使用Rational Application Developer ProgressBar组件,请完成以下任务:
- 使用Faces Project配置创建一个动态Web项目。
- 创建一个网页。
- 将进度条从面板的“ Enhanced Faces Components”抽屉中拖动到Web页面上。
该组件将在“ 设计”视图中可见,并且其属性将在“ 属性”视图中可用(请参见图1)。
图1.将ProgressBar组件添加到网页
ProgressBar需要简单JavaScript代码来控制其行为。 因此,在将组件放到Web页面上之后,还需要添加几行JavaScript,具体取决于您将如何使用ProgressBar。 本文的其余部分将说明并演示如何执行此操作。
ProgressBar如何工作
Rational Application Developer ProgressBar组件具有两种操作模式:自动和手动。
- 在自动模式下启动后,进度栏将继续更新任务的状态,直到使用指定的时间间隔和百分比增量值将其停止为止。 条可以从左向右或从中心向外移动。 在您知道任务何时开始和停止但无法知道任务进行了多长时间的情况下,此模式很有用。 在这种模式下,您可以使用两个JavaScript调用来控制ProgressBar:
start()
和stop()
。 它们的名称不言而喻:您可以通过start()
调用来启动进度条,而通过stop()
调用来stop()
进度条。 两种方法都可以将字符串参数用作条上方显示的消息文本。 - 在手动模式下,进度条不会独立移动。 相反,您必须使用JavaScript调用
upDatePercentage(integer)
手动更新其值。 您可以提供介于0(零)和100之间的任何值以反映完成百分比(例如,10表示完成百分比为10)。 当您确切地知道任务已进行了多长时间并且可以直观地表示进度(“可视化”进度)时,此模式很有用。
要访问代表ProgressBarJavaScript对象,可以使用Rational Application Developer JavaScript库中可用的getComponentById(id)
帮助方法。 例如,如果希望用户单击按钮时启动进度条,则可以使用清单1中的代码向按钮添加onclick
事件。
清单1.将onclick事件添加到用户界面按钮
onclick="hX.getComponentById('form1:bar1').start('Please wait...');"
传递给getComponentById()
函数的ID是JSF发出的ProgressBar的客户机ID,而不是您在Java™Server Page(JSP)中分配的组件ID。 根据ProgressBar在页面上的位置,其客户端ID将更改。 例如,如果ID为bar1
的ProgressBar位于ID为form1
的表单内,则其客户ID将为form1:bar
,如前面的代码片段(清单1)所示。
表1列出了ProgressBar组件的所有可用JavaScript方法。
表1. ProgressBar组件JavaScript方法
方法 | 描述 |
---|---|
开始(字符串) | 在自动模式下,启动进度条运行,并将消息文本更改为字符串的值。 如果您不想要消息,请不要传递参数。 |
停止(字符串) | 在自动模式下,停止进度条运行,并将消息文本更改为字符串值。 如果您不想要消息,请不要传递参数。 |
重启() | 将条形图的显示值重置为零。 |
upDatePercentage(整数) | 在手动模式下,将进度条更新为整数值。 整数值必须介于0(零)和100之间。超出此范围的值将分别向上或向下取整。 |
upDateMessage(string) | 更改在栏上方显示的消息。 如果要清除消息,则不传递任何参数。 |
redraw() | 考虑到对属性或属性所做的任何更改,重新绘制组件。 每当您更改属性(例如disabled )或属性(例如style:width )时使用。 应与visible(), hide(), reset(), upDatePercentage() 和upDateMessage() 方法结合使用。 |
隐藏() | 隐藏进度条。 |
可见() | 使进度条可见。 |
完成百分比 | 保留当前的进度条值,并且是只读的。 使用 upDatePercentage() 更改值。 |
本文附带一个示例项目文件,名为ProgressBarSample.zip 。 它显示了在两种模式下以及在不同场景下对ProgressBar的使用。 下一节将介绍每个示例。
Basic ProgressBar示例
随附的示例项目中的Basic.jsp页面演示了自动和手动模式下的ProgressBar组件。 自动栏上有“开始”和“停止”按钮,而手动栏上有“前进”和“重置”按钮。 让我们看看如何定义这些进度条以及按钮的作用。
在自动模式下使用ProgressBar组件
自动进度条看起来像JSP源代码中的清单2。
清单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 =“开始” | ProgressBar以自动模式运行 |
timeInterval =“ 500” | 条每500毫秒更新一次 |
比例=“ 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对象,然后在该对象上执行相应的操作。
在手动模式下使用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.控制ProgressBar组件JavaScript代码
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" />
每个输入字段都调用一个JavaScript函数来通过使用onkeyup
事件来更新进度条(清单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.更新后的手动模式
使用Ajax监视服务器端任务的进度
在较早的示例( auto.jsp , 图3 )中,有一个长时间运行的服务器端任务,并且您不知道任务完成需要多长时间或任务已经完成了多长时间。 因此,使用自动的ProgressBar是合适的,它一直运行直到服务器完成处理任务为止。
通常,您会发现自己处在不同的情况下,服务器端代码会精确地监视事情的运行方式,任务进行的距离以及完成任务所需的时间。 例如,您可能正在逐行处理数据库,并且知道有多少行以及已经处理了多少行。 在这种情况下,如果可以根据服务器端的状态而不是盲目地更新浏览器中的进度条,将很有用。 也就是说,如果处理了1000行中的300行,进度条将显示恰好30%的进度。
为此,您需要使用AJAX技术(异步JavaScript和XML,通常称为Ajax)使浏览器与服务器通信。 随附的示例项目中的ajax.jsp页面显示了如何执行此操作。
首先,您需要使用清单13中所示的代码添加一个ProgressBar组件。
清单13。 添加ProgressBar组件以更新服务器活动
<hx:progressBar auto="false" id="bar1"
styleClass="progressBar"
message="Server reports progress..." />
您不希望进度条仅继续独立运行,因此您可以通过将auto
属性设置为false
来使其手动。 乍一看这可能并不明显-毕竟,您实际上并不会每次都手动对其进行更新。 但是,由于将通过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
属性的get方法,并将返回的任何值放入浏览器的隐藏输入字段中。 在示例应用程序中, pbValue
的get方法仅在会话中保留一个计数器,并在每次调用get方法时将其递增。 页面上还有一个“重置”按钮,可将计数器重置为零。
发送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()
函数所做的所有poll()
都是模拟单击按钮。 该单击将Ajax请求发送到服务器,服务器返回当前进度状态,并且隐藏字段已更新。 这一切在没有任何用户交互的情况下发生。
在隐藏的输入字段中更新了当前进度之后,剩下要做的就是相应地更新ProgressBar组件。 如果您注意到了,Ajax标记还具有与之关联JavaScript函数,如清单17所示。
清单17.以最大宽度列出的示例代码
<hx:ajaxRefreshRequest id="ajaxRefreshRequest1"
target="group1"
oncomplete="movePB()" params="text1" />
每当服务器响应Ajax请求时, oncomplete
事件都会运行。 一旦发生这种情况,就可以获取隐藏的输入字段的值并更新进度条(请参见清单18)。 图5显示了对用户界面的影响。
清单18。 使用隐藏字段的值更新进度条
function movePB() {
v=hX.getElementById('form1:hidden1').value;
pb=hX.getComponentById('form1:bar1');
pb.upDatePercentage(v);
pb.redraw();
}
图5. ajax.jsp
如何自定义您的ProgressBar组件
您可以使用表3中列出的属性来自定义ProgressBar组件的行为。
表3.主要的ProgressBar属性
属性 | 行动 |
---|---|
汽车 | 如果为true ,则为自动模式,如果为false ,则为手动模式。 默认值为false 。 |
初始化隐藏 | 如果为true ,则在最初显示页面时隐藏进度条。 默认值为false 。 |
信息 | 显示在条上方的消息。 |
向外 | 如果为true,则进度条从中心向外绘制。 如果为false ,则该条从左到右绘制。 默认值为false 。 |
比例 | 在自动模式下,每次更新时,条显示的完成量(进度条宽度的百分比)会增加。 默认值为5 。 |
初始化值 | 在手动模式下,指示条最初显示的数量(百分比)。 默认值为0 (零)。 |
时间间隔 | 在自动模式下,间隔(多久一次)更新一次。 以毫秒为单位。 默认值为1000。 |
进度条的显示由表4显示CSS类控制。
表4. ProgressBar类
CSS类 | 目的 |
---|---|
<基础> | 可以在ProgressBar组件的styleClass 属性中设置此类的名称。 默认值为progressBar 。 此类为整个进度条控件(包含div )设置样式。 |
<base>-表 | 设置组成进度条的表的样式。 |
<base>-消息 | 设置保存消息文本的区域的样式。 |
<base>-栏 | 设置移动栏的样式。 |
<base> -Bar_container | 设置包含移动条和百分比文本的区域的样式。 |
<base>-Bar_text | 设置百分比文本的样式。 |
有关Rational Application Developer的最新功能(将其与Ajax和Java技术结合使用)的更多信息以及相关信息,请参阅参考资料。
翻译自: https://www.ibm.com/developerworks/rational/library/07/0626_kats/index.html