public class SubMonitor extends Object implements IProgressMonitorWithBlocking
progress monitor
that uses a given amount of work ticks from a parent monitor.
This is intended as a safer, easier-to-use alternative to SubProgressMonitor
.
Progress monitoring is generally quite invasive to the code that is monitored. At the same time progress monitoring itself is typically very hard to implement correctly. This class aims at reducing the invasiveness as much as possible while offering all the functionality needed to do the job right.
The following aspects of this class help to keep the progress monitoring code short and nice and to avoid common monitoring mistakes:
SubMonitor
, which already makes progress monitoring a lot easier.
Refer to the SubMonitor
documentation or to this article for details and examples.
setWorkRemaining(int)
method it offers a skipped(int)
method, which redistributes the remaining work
according to the last skipped worked(int)
or newChild(int)
call rather than on the sum of all subsequent calls.
work
arguments by using the default value 1
with the overloaded
worked()
, skipped()
and newChild()
calls.
if (monitor.isCanceled()) { throw new OperationCanceledException(); }For details about automatic cancelation detection refer to
detectCancelation()
.
As a solution to this problem this class offers the possibility to transparently instrument SubMonitor
instances such that they automatically
collect and report all kinds of statistics that may help to enhance the user experience. Sometimes it would even indicate to remove some progress monitoring
because it turns out that almost no time is being spent in a particular part of the program. Another typical result from the analysis is the understanding of
one time effects that might need special consideration.
For details about this probing mode refer to ProbingSubMonitor
.
The following example shows how to monitor progress while recursing through a tree of folders:
public void recurse(IContainer container, IProgressMonitor monitor) throws Exception { IResource[] members = container.members(); SubMonitor progress = SubMonitor.convert(monitor, members.length).detectCancelation(); progress.subTask(container.getFullPath().toString()); for (IResource member : members) { if (member instanceof IContainer) { Thread.sleep(5); recurse((IContainer)member, progress.newChild()); } else { progress.skipped(); } } }
Modifier and Type | Class and Description |
---|---|
static class |
SubMonitor.ProbingMode
Enumerates the possible probing mode values
SubMonitor.ProbingMode.OFF , SubMonitor.ProbingMode.STANDARD and SubMonitor.ProbingMode.FULL . |
Modifier and Type | Field and Description |
---|---|
static int |
DEFAULT_WORK |
static int |
SUPPRESS_ALL_LABELS
May be passed as a flag to newChild.
|
static int |
SUPPRESS_BEGINTASK
May be passed as a flag to newChild.
|
static int |
SUPPRESS_NONE
May be passed as a flag to newChild.
|
static int |
SUPPRESS_SETTASKNAME
May be passed as a flag to newChild.
|
static int |
SUPPRESS_SUBTASK
May be passed as a flag to newChild.
|
UNKNOWN
Modifier and Type | Method and Description |
---|---|
void |
beginTask(String name,
int totalWork)
Starts a new main task.
|
void |
childDone() |
void |
clearBlocked() |
static SubMonitor |
convert(IProgressMonitor monitor)
Converts an unknown (possibly null) IProgressMonitor into a SubMonitor.
|
static SubMonitor |
convert(IProgressMonitor monitor,
int work)
Converts an unknown (possibly null) IProgressMonitor into a SubMonitor allocated
with the given number of ticks.
|
static SubMonitor |
convert(IProgressMonitor monitor,
int work,
SubMonitor.ProbingMode probingMode)
Converts an unknown (possibly null) IProgressMonitor into a SubMonitor allocated
with the given number of ticks.
|
static SubMonitor |
convert(IProgressMonitor monitor,
String taskName,
int work)
Converts an unknown (possibly null) IProgressMonitor into a SubMonitor allocated
with the given number of ticks.
|
static SubMonitor |
convert(IProgressMonitor monitor,
String taskName,
int work,
SubMonitor.ProbingMode probingMode)
Converts an unknown (possibly null) IProgressMonitor into a SubMonitor allocated
with the given number of ticks.
|
static SubMonitor |
convert(IProgressMonitor monitor,
SubMonitor.ProbingMode probingMode)
Converts an unknown (possibly null) IProgressMonitor into a SubMonitor.
|
SubMonitor |
detectCancelation() |
SubMonitor |
detectCancelation(boolean on) |
void |
done() |
protected static boolean |
eq(Object o1,
Object o2) |
void |
internalWorked(double work) |
boolean |
isCanceled() |
SubMonitor |
newChild()
Same as
newChild(1) . |
SubMonitor |
newChild(int totalWork)
Creates a sub progress monitor that will consume the given number of ticks from the
receiver.
|
SubMonitor |
newChild(int totalWork,
int suppressFlags)
Creates a sub progress monitor that will consume the given number of ticks from the
receiver.
|
void |
setBlocked(IStatus reason) |
void |
setCanceled(boolean b) |
void |
setTaskName(String name) |
SubMonitor |
setWorkRemaining(int workRemaining)
Sets the work remaining for this SubMonitor instance.
|
void |
skipped()
Same as
skipped(1) . |
void |
skipped(int ticks)
|
void |
subTask(String name) |
void |
worked()
Same as
worked(1) . |
void |
worked(int work) |
public static final int DEFAULT_WORK
public static final int SUPPRESS_SUBTASK
public static final int SUPPRESS_BEGINTASK
public static final int SUPPRESS_SETTASKNAME
public static final int SUPPRESS_ALL_LABELS
public static final int SUPPRESS_NONE
public static SubMonitor convert(IProgressMonitor monitor)
Converts an unknown (possibly null) IProgressMonitor into a SubMonitor. It is not necessary to call done() on the result, but the caller is responsible for calling done() on the argument. Calls beginTask on the argument.
This method should generally be called at the beginning of a method that accepts an IProgressMonitor in order to convert the IProgressMonitor into a SubMonitor.
monitor
- monitor to convert to a SubMonitor instance or null. Treats null
as a new instance of NullProgressMonitor
.public static SubMonitor convert(IProgressMonitor monitor, int work)
Converts an unknown (possibly null) IProgressMonitor into a SubMonitor allocated with the given number of ticks. It is not necessary to call done() on the result, but the caller is responsible for calling done() on the argument. Calls beginTask on the argument.
This method should generally be called at the beginning of a method that accepts an IProgressMonitor in order to convert the IProgressMonitor into a SubMonitor.
monitor
- monitor to convert to a SubMonitor instance or null. Treats null
as a new instance of NullProgressMonitor
.work
- number of ticks that will be available in the resulting monitorpublic static SubMonitor convert(IProgressMonitor monitor, String taskName, int work)
Converts an unknown (possibly null) IProgressMonitor into a SubMonitor allocated with the given number of ticks. It is not necessary to call done() on the result, but the caller is responsible for calling done() on the argument. Calls beginTask on the argument.
This method should generally be called at the beginning of a method that accepts an IProgressMonitor in order to convert the IProgressMonitor into a SubMonitor.
monitor
- to convert into a SubMonitor instance or null. If given a null argument,
the resulting SubMonitor will not report its progress anywhere.taskName
- user readable name to pass to monitor.beginTask. Never null.work
- initial number of ticks to allocate for children of the SubMonitorpublic static SubMonitor convert(IProgressMonitor monitor, SubMonitor.ProbingMode probingMode)
Converts an unknown (possibly null) IProgressMonitor into a SubMonitor. It is not necessary to call done() on the result, but the caller is responsible for calling done() on the argument. Calls beginTask on the argument.
This method should generally be called at the beginning of a method that accepts an IProgressMonitor in order to convert the IProgressMonitor into a SubMonitor.
monitor
- monitor to convert to a SubMonitor instance or null. Treats null
as a new instance of NullProgressMonitor
.public static SubMonitor convert(IProgressMonitor monitor, int work, SubMonitor.ProbingMode probingMode)
Converts an unknown (possibly null) IProgressMonitor into a SubMonitor allocated with the given number of ticks. It is not necessary to call done() on the result, but the caller is responsible for calling done() on the argument. Calls beginTask on the argument.
This method should generally be called at the beginning of a method that accepts an IProgressMonitor in order to convert the IProgressMonitor into a SubMonitor.
monitor
- monitor to convert to a SubMonitor instance or null. Treats null
as a new instance of NullProgressMonitor
.work
- number of ticks that will be available in the resulting monitorpublic static SubMonitor convert(IProgressMonitor monitor, String taskName, int work, SubMonitor.ProbingMode probingMode)
Converts an unknown (possibly null) IProgressMonitor into a SubMonitor allocated with the given number of ticks. It is not necessary to call done() on the result, but the caller is responsible for calling done() on the argument. Calls beginTask on the argument.
This method should generally be called at the beginning of a method that accepts an IProgressMonitor in order to convert the IProgressMonitor into a SubMonitor.
monitor
- to convert into a SubMonitor instance or null. If given a null argument,
the resulting SubMonitor will not report its progress anywhere.taskName
- user readable name to pass to monitor.beginTask. Never null.work
- initial number of ticks to allocate for children of the SubMonitorpublic final SubMonitor detectCancelation()
public final SubMonitor detectCancelation(boolean on)
public final SubMonitor setWorkRemaining(int workRemaining)
Sets the work remaining for this SubMonitor instance. This is the total number of ticks that may be reported by all subsequent calls to worked(int), newChild(int), etc. This may be called many times for the same SubMonitor instance. When this method is called, the remaining space on the progress monitor is redistributed into the given number of ticks.
It doesn't matter how much progress has already been reported with this SubMonitor instance. If you call setWorkRemaining(100), you will be able to report 100 more ticks of work before the progress meter reaches 100%.
workRemaining
- total number of remaining tickspublic final boolean isCanceled()
isCanceled
in interface IProgressMonitor
public final void setTaskName(String name)
setTaskName
in interface IProgressMonitor
public final void beginTask(String name, int totalWork)
This method is equivalent calling setWorkRemaining(...) on the receiver. Unless the SUPPRESS_BEGINTASK flag is set, this will also be equivalent to calling setTaskName(...) on the parent.
beginTask
in interface IProgressMonitor
name
- new main task nametotalWork
- number of ticks to allocateIProgressMonitor.beginTask(java.lang.String, int)
public void done()
done
in interface IProgressMonitor
public final void internalWorked(double work)
internalWorked
in interface IProgressMonitor
public final void subTask(String name)
subTask
in interface IProgressMonitor
public final void worked()
worked(1)
.public void worked(int work)
worked
in interface IProgressMonitor
public final void skipped(int ticks)
public final void skipped()
skipped(1)
.public final void setCanceled(boolean b)
setCanceled
in interface IProgressMonitor
public final SubMonitor newChild()
newChild(1)
.public final SubMonitor newChild(int totalWork)
Creates a sub progress monitor that will consume the given number of ticks from the
receiver. It is not necessary to call beginTask
or done
on the
result. However, the resulting progress monitor will not report any work after the first
call to done() or before ticks are allocated. Ticks may be allocated by calling beginTask
or setWorkRemaining.
Each SubMonitor only has one active child at a time. Each time newChild() is called, the result becomes the new active child and any unused progress from the previously-active child is consumed.
This is property makes it unnecessary to call done() on a SubMonitor instance, since child monitors are automatically cleaned up the next time the parent is touched.
////////////////////////////////////////////////////////////////////////////
// Example 1: Typical usage of newChild
void myMethod(IProgressMonitor parent) {
SubMonitor progress = SubMonitor.convert(parent, 100);
doSomething(progress.newChild(50));
doSomethingElse(progress.newChild(50));
}
////////////////////////////////////////////////////////////////////////////
// Example 2: Demonstrates the function of active children. Creating children
// is sufficient to smoothly report progress, even if worked(...) and done()
// are never called.
void myMethod(IProgressMonitor parent) {
SubMonitor progress = SubMonitor.convert(parent, 100);
for (int i = 0; i < 100; i++) {
// Creating the next child monitor will clean up the previous one,
// causing progress to be reported smoothly even if we don't do anything
// with the monitors we create
progress.newChild(1);
}
}
////////////////////////////////////////////////////////////////////////////
// Example 3: Demonstrates a common anti-pattern
void wrongMethod(IProgressMonitor parent) {
SubMonitor progress = SubMonitor.convert(parent, 100);
// WRONG WAY: Won't have the intended effect, as only one of these progress
// monitors may be active at a time and the other will report no progress.
callMethod(progress.newChild(50), computeValue(progress.newChild(50)));
}
void rightMethod(IProgressMonitor parent) {
SubMonitor progress = SubMonitor.convert(parent, 100);
// RIGHT WAY: Break up method calls so that only one SubMonitor is in use at a time.
Object someValue = computeValue(progress.newChild(50));
callMethod(progress.newChild(50), someValue);
}
totalWork
- number of ticks to consume from the receiverpublic final SubMonitor newChild(int totalWork, int suppressFlags)
Creates a sub progress monitor that will consume the given number of ticks from the
receiver. It is not necessary to call beginTask
or done
on the
result. However, the resulting progress monitor will not report any work after the first
call to done() or before ticks are allocated. Ticks may be allocated by calling beginTask
or setWorkRemaining.
Each SubMonitor only has one active child at a time. Each time newChild() is called, the result becomes the new active child and any unused progress from the previously-active child is consumed.
This is property makes it unnecessary to call done() on a SubMonitor instance, since child monitors are automatically cleaned up the next time the parent is touched.
////////////////////////////////////////////////////////////////////////////
// Example 1: Typical usage of newChild
void myMethod(IProgressMonitor parent) {
SubMonitor progress = SubMonitor.convert(parent, 100);
doSomething(progress.newChild(50));
doSomethingElse(progress.newChild(50));
}
////////////////////////////////////////////////////////////////////////////
// Example 2: Demonstrates the function of active children. Creating children
// is sufficient to smoothly report progress, even if worked(...) and done()
// are never called.
void myMethod(IProgressMonitor parent) {
SubMonitor progress = SubMonitor.convert(parent, 100);
for (int i = 0; i < 100; i++) {
// Creating the next child monitor will clean up the previous one,
// causing progress to be reported smoothly even if we don't do anything
// with the monitors we create
progress.newChild(1);
}
}
////////////////////////////////////////////////////////////////////////////
// Example 3: Demonstrates a common anti-pattern
void wrongMethod(IProgressMonitor parent) {
SubMonitor progress = SubMonitor.convert(parent, 100);
// WRONG WAY: Won't have the intended effect, as only one of these progress
// monitors may be active at a time and the other will report no progress.
callMethod(progress.newChild(50), computeValue(progress.newChild(50)));
}
void rightMethod(IProgressMonitor parent) {
SubMonitor progress = SubMonitor.convert(parent, 100);
// RIGHT WAY: Break up method calls so that only one SubMonitor is in use at a time.
Object someValue = computeValue(progress.newChild(50));
callMethod(progress.newChild(50), someValue);
}
totalWork
- number of ticks to consume from the receiverpublic void childDone()
public final void clearBlocked()
clearBlocked
in interface IProgressMonitorWithBlocking
public final void setBlocked(IStatus reason)
setBlocked
in interface IProgressMonitorWithBlocking
Copyright (c) 2011-2014 Eike Stepper (Berlin, Germany) and others.