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; } }