diff options
Diffstat (limited to 'documentation/components/components-progressbar.asciidoc')
-rw-r--r-- | documentation/components/components-progressbar.asciidoc | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/documentation/components/components-progressbar.asciidoc b/documentation/components/components-progressbar.asciidoc new file mode 100644 index 0000000000..4e50ae1b43 --- /dev/null +++ b/documentation/components/components-progressbar.asciidoc @@ -0,0 +1,209 @@ +--- +title: ProgressBar +order: 27 +layout: page +--- + +[[components.progressbar]] += [classname]#ProgressBar# + +The [classname]#ProgressBar# component allows displaying the progress of a task +graphically. The progress is specified as a floating-point value between 0.0 and +1.0. + +[[figure.components.progressbar.basic]] +.The Progress Bar Component +image::img/progressbar-basic.png[] + +To display upload progress with the [classname]#Upload# component, you can +update the progress bar in a [interfacename]#ProgressListener#. + +When the position of a progress bar is done in a background thread, the change +is not shown in the browser immediately. You need to use either polling or +server push to update the browser. You can enable polling with +[methodname]#setPollInterval()# in the current UI instance. See +<<dummy/../../../framework/advanced/advanced-push#advanced.push,"Server Push">> +for instructions about using server push. Whichever method you use to update the +UI, it is important to lock the user session by modifying the progress bar value +inside [methodname]#access()# call, as illustrated in the following example and +described in +<<dummy/../../../framework/advanced/advanced-push#advanced.push.running,"Accessing +UI from Another Thread">>. + + +[source, java] +---- +final ProgressBar bar = new ProgressBar(0.0f); +layout.addComponent(bar); + +layout.addComponent(new Button("Increase", + new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + float current = bar.getValue(); + if (current < 1.0f) + bar.setValue(current + 0.10f); + } +})); +---- + +[[components.progressbar.indeterminate]] +== Indeterminate Mode + +In the indeterminate mode, a non-progressive indicator is displayed +continuously. The indeterminate indicator is a circular wheel in the built-in +themes. The progress value has no meaning in the indeterminate mode. + + +[source, java] +---- +ProgressBar bar = new ProgressBar(); +bar.setIndeterminate(true); +---- + +[[figure.components.progressbar.indeterminate]] +.Indeterminate Progress Bar +image::img/progressbar-indeterminate.png[] + + +ifdef::web[] +[[components.progressbar.thread]] +== Doing Heavy Computation + +The progress indicator is often used to display the progress of a heavy +server-side computation task, often running in a background thread. The UI, +including the progress bar, can be updated either with polling or by using +server push. When doing so, you must ensure thread-safety, most easily by +updating the UI inside a [methodname]#UI.access()# call in a +[interfacename]#Runnable#, as described in +<<dummy/../../../framework/advanced/advanced-push#advanced.push.running,"Accessing +UI from Another Thread">>. + +In the following example, we create a thread in the server to do some "heavy +work" and use polling to update the UI. All the thread needs to do is to set the +value of the progress bar with [methodname]#setValue()# and the current progress +is displayed automatically when the browser polls the server. + + +[source, java] +---- +HorizontalLayout barbar = new HorizontalLayout(); +layout.addComponent(barbar); + +// Create the indicator, disabled until progress is started +final ProgressBar progress = new ProgressBar(new Float(0.0)); +progress.setEnabled(false); +barbar.addComponent(progress); + +final Label status = new Label("not running"); +barbar.addComponent(status); + +// A button to start progress +final Button button = new Button("Click to start"); +layout.addComponent(button); + +// A thread to do some work +class WorkThread extends Thread { + // Volatile because read in another thread in access() + volatile double current = 0.0; + + @Override + public void run() { + // Count up until 1.0 is reached + while (current < 1.0) { + current += 0.01; + + // Do some "heavy work" + try { + sleep(50); // Sleep for 50 milliseconds + } catch (InterruptedException e) {} + + // Update the UI thread-safely + UI.getCurrent().access(new Runnable() { + @Override + public void run() { + progress.setValue(new Float(current)); + if (current < 1.0) + status.setValue("" + + ((int)(current*100)) + "% done"); + else + status.setValue("all done"); + } + }); + } + + // Show the "all done" for a while + try { + sleep(2000); // Sleep for 2 seconds + } catch (InterruptedException e) {} + + // Update the UI thread-safely + UI.getCurrent().access(new Runnable() { + @Override + public void run() { + // Restore the state to initial + progress.setValue(new Float(0.0)); + progress.setEnabled(false); + + // Stop polling + UI.getCurrent().setPollInterval(-1); + + button.setEnabled(true); + status.setValue("not running"); + } + }); + } +} + +// Clicking the button creates and runs a work thread +button.addClickListener(new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + final WorkThread thread = new WorkThread(); + thread.start(); + + // Enable polling and set frequency to 0.5 seconds + UI.getCurrent().setPollInterval(500); + + // Disable the button until the work is done + progress.setEnabled(true); + button.setEnabled(false); + + status.setValue("running..."); + } +}); +---- + +The example is illustrated in <<figure.components.progressbar.thread>>. + +[[figure.components.progressbar.thread]] +.Doing Heavy Work +image::img/progressbar-thread.png[] + +endif::web[] + +[[components.progressbar.css]] +== CSS Style Rules + + +[source, css] +---- +.v-progressbar, v-progressbar-indeterminate {} + .v-progressbar-wrapper {} + .v-progressbar-indicator {} +---- + +The progress bar has a [literal]#++v-progressbar++# base style. The animation is +the background of the element with [literal]#++v-progressbar-wrapper++# style, +by default an animated GIF image. The progress is an element with +[literal]#++v-progressbar-indicator++# style inside the wrapper, and therefore +displayed on top of it. When the progress element grows, it covers more and more +of the animated background. + +In the indeterminate mode, the top element also has the +[literal]#++v-progressbar-indeterminate++# style. The built-in themes simply +display the animated GIF in the top element and have the inner elements +disabled. + + + + |