--- title: ProgressBar order: 27 layout: page --- [[components.progressbar]] = [classname]#ProgressBar# ifdef::web[] [.sampler] image:{live-demo-image}[alt="Live Demo", link="http://demo.vaadin.com/sampler/#ui/interaction/progress-bar"] endif::web[] 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 <> 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 <>. [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 <>. 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]] .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.