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 WTKX source for the example is shown below:
<Window title="Meters" maximized="true" xmlns:wtkx="http://pivot.apache.org/wtkx" xmlns="org.apache.pivot.wtk"> <content> <TablePane> <columns> <TablePane.Column width="1*"/> </columns> <rows> <TablePane.Row height="1*"> <Border> <content> <BoxPane styles="{horizontalAlignment:'center', verticalAlignment:'center'}"> <Label text="Progress:"/> <Meter wtkx:id="meter" preferredWidth="200" preferredHeight="16"/> </BoxPane> </content> </Border> </TablePane.Row> <TablePane.Row height="-1"> <BoxPane styles="{horizontalAlignment:'center', padding:6}"> <PushButton wtkx:id="progressButton" styles="{preferredAspectRatio:3}"/> </BoxPane> </TablePane.Row> </rows> </TablePane> </content> </Window>The Java source is as follows. The main application class defines an inner class that extends the 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 pivot.wtk.TaskAdapter is used to process the task notifications for the same reason:
package org.apache.pivot.tutorials.progress; import org.apache.pivot.collections.Map; 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.Application; import org.apache.pivot.wtk.ApplicationContext; import org.apache.pivot.wtk.Button; import org.apache.pivot.wtk.ButtonPressListener; import org.apache.pivot.wtk.DesktopApplicationContext; import org.apache.pivot.wtk.Display; import org.apache.pivot.wtk.Meter; import org.apache.pivot.wtk.PushButton; import org.apache.pivot.wtk.TaskAdapter; import org.apache.pivot.wtk.Window; import org.apache.pivot.wtkx.WTKXSerializer; public class Meters implements Application { 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 { Thread.sleep(100); percentage++; // 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 Window window = null; private Meter meter = null; private PushButton progressButton = null; private SampleTask sampleTask = null; public void startup(Display display, Map<String, String> properties) throws Exception { WTKXSerializer wtkxSerializer = new WTKXSerializer(); window = (Window)wtkxSerializer.readObject(this, "meters.wtkx"); meter = (Meter)wtkxSerializer.get("meter"); progressButton = (PushButton)wtkxSerializer.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) { reset(); } public void executeFailed(Task<Void> task) { reset(); } private void reset() { // Reset the meter and button sampleTask = null; meter.setPercentage(0); updateProgressButton(); } })); } else { // Cancel the task sampleTask.abort(); } updateProgressButton(); } }); updateProgressButton(); window.open(display); } public boolean shutdown(boolean optional) { if (window != null) { window.close(); } return false; } public void suspend() { } public void resume() { } private void updateProgressButton() { if (sampleTask == null) { progressButton.setButtonData("Start"); } else { progressButton.setButtonData("Cancel"); } } public static void main(String[] args) { DesktopApplicationContext.main(Meters.class, args); } }
Next: Activity Indicators