ProgressBar
Used in conjunction with ProgressWorker to dynamically render the status and progress of a server invoked thread. This component does not work without javascript. Most of the html for this component is rendered using floating divs and a set of classes. There is a ProgressBar.css file included in the distribution that provides a good set of default values already.
The Prototype javascript library is used by this component to do Periodical refresh requests of the ProgressBar component.
See also: PeriodicalExecutor (prototype) , Live Demo
Parameters
| Name | Type | Direction | Required | Default | Description |
|---|---|---|---|---|---|
| reloadseconds | String | in | no | 3 | The number of seconds the client-side javascript will wait before refreshing the component. |
| truncateLength | String | in | no | 38 | This is the maximum number of characters the managed ProgressWorker's statusString value can contain before the component truncates the value by appending "..." to the end of the string. |
| worker | ProgressWorker | in | yes | The ProgressWorker that this component is displaying the status of. | |
| element | String | in | no | div | The html element to wrap the body with, default is div. |
| onCompleteObject | String | in | no | If provided, the javascript object with the specified name will be invoked with a method name of progressFinished(elementId). Ie progressComplete.progressFinished(elementId) |
Body: rendered
Informal parameters: allowed
Reserved parameters:
Examples
This example increments a simple counter on the server
HTML template
<!-- Task Progress invoker -->
<span jwcid="@Any" id="linkPart" >
<span jwcid="@If" condition="ognl:!importing" >
<div class="progressStart">
<a jwcid="progressLink" >Start</a>
</div>
</span>
<span jwcid="@If" condition="ognl:importing" >
<div class="progressStart">
<a jwcid="progressCancel" >Cancel</a>
</div>
</span>
</span>
<!-- End Task Progress invoker -->
<!-- Task progress -->
<span jwcid="progress" />
<!-- End Task progress -->
<script type="text/javascript">
dojo.require("dojo.event.*");
dojo.require("dojo.animation.*");
dojo.require("dojo.math.*");
var linkString =
"<span jwcid="@Insert" raw="true" value="ognl:components.progress.linkString" />";
var startObject = new Object();
startObject.responseComplete = function(responseElements) {
if (!document.progAnim) {
var progNode = document.getElementById("progress");
dojo.fx.html.fadeShow(progNode, 1000);
document.progAnim = new dojo.animation.Animation(
new dojo.math.curves.Line([1],[20]),
2000, //2 second pauses
0, //no acceleration
-1 //repeat forever
);
dojo.event.connect(document.progAnim, "onAnimate", function(e) {
tacos.defaultLinkAction({url: linkString,
processScripts:true, useSync: true});
});
document.progAnim.play(true);
}
}
var cancelObject = new Object();
cancelObject.ajaxUpdate = function(ajaxElement, responseElement, elementId) {
if (document.progAnim) {
document.progAnim.stop();
document.progAnim = null;
var progNode = document.getElementById("progress");
dojo.fx.html.fadeHide(progNode, 1000);
<span jwcid="@tacos:Refresh" updateComponents="ognl:{'linkPart'}" />
}
}
var progressComplete = new Object();
progressComplete.progressFinished = function(elementId) {
if (document.progAnim) {
document.progAnim.stop();
document.progAnim = null;
var progNode = document.getElementById("progress");
dojo.fx.html.fadeHide(progNode, 1000);
<span jwcid="@tacos:Refresh" updateComponents="ognl:{'linkPart'}" />
}
}
</script>
Page specification
<page-specification class="net.sf.tacos.demo.pages.ajax.ProgressBarExample">
<description>Partial ProgressBar example</description>
<property name="progressWorker" persist="session" />
<property name="startTime" persist="session" />
<component id="progressLink" type="tacos:AjaxDirectLink">
<binding name="listener" value="listener:startTask"/>
<binding name="updateComponents" value="ognl:{'linkPart'}"/>
<binding name="updateObject" value="literal:startObject" />
</component>
<component id="progressCancel" type="tacos:AjaxDirectLink">
<binding name="listener" value="ognl:components.progress.listeners.cancelTask"/>
<binding name="updateComponents" value="ognl:{'linkPart'}"/>
<binding name="updateObject" value="literal:cancelObject" />
</component>
<component id="progress" type="tacos:ProgressBar">
<binding name="reloadseconds" value="1" />
<binding name="worker" value="ognl:progressWorker" />
<binding name="id" value="literal:progress" />
<binding name="onCompleteObject" value="literal:progressComplete" />
</component>
</page-specification>
Java sources
public abstract class ProgressCounter extends BasePage
implements IDirect {
/** Logger */
private static final Log log =
LogFactory.getLog(ProgressCounter.class);
/** Injected ajax engine */
public abstract AjaxDirectService getAjaxEngineService();
/** Worker doing import */
public abstract ProgressWorkThread getProgressWorker();
/** sets worker doing import */
public abstract void setProgressWorker(ProgressWorkThread worker);
/** Set time - in milliseconds - that worker started */
public abstract void setStartTime(long time);
/** Gets start time */
public abstract long getStartTime();
/**
*
* @return True if currently importing a casebase file.
*/
public boolean isImporting()
{
return getProgressWorker() != null && !getProgressWorker().isComplete();
}
/**
* Calculates amount of time left, in minutes, for task.
* @return
*/
public String getEstimatedTimeLeft()
{
if (getProgressWorker() == null)
return "0 min";
//Get values so they don't change on us
double currentProgress = getProgressWorker().getCurrentProgress();
double totalProgress = getProgressWorker().getTotalProgress();
double avgDuration =
(System.currentTimeMillis() - getStartTime()) / currentProgress;
double remainingDuration =
(totalProgress - getProgressWorker()
.getCurrentProgress()) * avgDuration;
return DurationFormatUtils
.formatDurationHMS(Math.round(remainingDuration));
}
/**
* {@inheritDoc}
*/
public void trigger(IRequestCycle cycle)
{
}
/**
* Starts the progress task.
* @param cycle
* @throws Exception
*/
public void startTask(IRequestCycle cycle)
throws Exception
{
if (isImporting())
return;
log.debug("startTask");
setProgressWorker(null);
//Start task
ProgressWorkThread worker = new ProgressWorkThread();
setProgressWorker(worker);
worker.start();
setStartTime(System.currentTimeMillis());
}
}
public class ProgressWorkThread extends Thread
implements ProgressWorker, Serializable {
/** serialuid */
private static final long serialVersionUID = 4915291816082490796L;
/** logger */
private static final Log log = LogFactory.getLog(ProgressWorkThread.class);
/** Total progress we are working on */
private static final double TOTAL = 100;
/** Current progress */
private double progress = 0;
/* Flag for if we are running or not */
private boolean running = true;
/** Default constructor */
public ProgressWorkThread()
{
}
/**
* {@inheritDoc}
*/
public double getTotalProgress() {
return TOTAL;
}
/**
* {@inheritDoc}
*/
public double getCurrentProgress() {
return progress;
}
/**
* {@inheritDoc}
*/
public String getCurrentStatus() {
return "Processing count of " + progress;
}
/**
* {@inheritDoc}
*/
public boolean isComplete() {
return !running;
}
/**
* {@inheritDoc}
*/
public void cancelTask() {
if (!running)
return;
progress = TOTAL;
running = false;
try { this.interrupt(); } catch (Exception et) { }
}
/**
* {@inheritDoc}
*/
public void run() {
while (progress < TOTAL) {
log.debug("progressWorker() " + progress);
progress += 1;
try { sleep(100); } catch (Exception e) { }
}
running = false;
}
}

