Meters are used to report progress to the user, generally the completion percentage of a background task such as a file load operation. An example is shown below. Clicking the Start button initiates a background task that simulates a long-running operation. Periodically, the task updates the meter to reflect its progress:

The BXML source for the example is shown below:

            <progress:Meters title="Meters" maximized="true"
                        <TablePane.Column width="1*"/>

                    <TablePane.Row height="1*">
                        <Border styles="{padding:2}">
                            <BoxPane styles="{horizontalAlignment:'center', verticalAlignment:'center'}">
                                <Label text="Progress:"/>
                                <Meter bxml:id="meter" preferredWidth="200" preferredHeight="16"/>

                    <TablePane.Row height="-1">
                        <BoxPane styles="{horizontalAlignment:'center', padding:6}">
                            <PushButton bxml:id="progressButton" styles="{minimumAspectRatio:3}"/>

The Java source is as follows. The main window class defines an inner class that extends the org.apache.pivot.util.concurrent.Task class to simulate a background operation. This task simply sleeps for 100ms at a time and updates the meter when it wakes up to reflect the current count. Since all UI updates must be performed on the UI thread, the task queues a callback to set the meter's percent complete; a org.apache.pivot.wtk.TaskAdapter is used to process the task notifications for the same reason:

            package org.apache.pivot.tutorials.progress;


            import org.apache.pivot.beans.Bindable;
            import org.apache.pivot.collections.Map;
            import org.apache.pivot.util.Resources;
            import org.apache.pivot.util.concurrent.Task;
            import org.apache.pivot.util.concurrent.TaskExecutionException;
            import org.apache.pivot.util.concurrent.TaskListener;
            import org.apache.pivot.wtk.ApplicationContext;
            import org.apache.pivot.wtk.Button;
            import org.apache.pivot.wtk.ButtonPressListener;
            import org.apache.pivot.wtk.Meter;
            import org.apache.pivot.wtk.PushButton;
            import org.apache.pivot.wtk.TaskAdapter;
            import org.apache.pivot.wtk.Window;

            public class Meters extends Window implements Bindable {
                public class SampleTask extends Task<Void> {
                    private int percentage = 0;

                    public Void execute() throws TaskExecutionException {
                        // Simulate a long-running operation
                        percentage = 0;

                        while (percentage < 100
                            && !abort) {
                            try {

                                // Update the meter on the UI thread
                                ApplicationContext.queueCallback(new Runnable() {
                                    public void run() {
                                        meter.setPercentage((double)percentage / 100);
                            } catch(InterruptedException exception) {
                                throw new TaskExecutionException(exception);

                        return null;

                private Meter meter = null;
                private PushButton progressButton = null;

                private SampleTask sampleTask = null;

                public void initialize(Map<String, Object> namespace, URL location, Resources resources) {
                    meter = (Meter)namespace.get("meter");
                    progressButton = (PushButton)namespace.get("progressButton");

                    progressButton.getButtonPressListeners().add(new ButtonPressListener() {
                        public void buttonPressed(Button button) {
                            if (sampleTask == null) {
                                // Create and start the simulated task; wrap it in a
                                // task adapter so the result handlers are called on the
                                // UI thread
                                sampleTask = new SampleTask();
                                sampleTask.execute(new TaskAdapter<Void>(new TaskListener<Void>() {
                                    public void taskExecuted(Task<Void> task) {

                                    public void executeFailed(Task<Void> task) {

                                    private void reset() {
                                        // Reset the meter and button
                                        sampleTask = null;
                            } else {
                                // Cancel the task



                private void updateProgressButton() {
                    if (sampleTask == null) {
                    } else {

Next: Activity Indicators