KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > operation > AccumulatingProgressMonitor


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jface.operation;
12
13 import org.eclipse.core.runtime.IProgressMonitor;
14 import org.eclipse.core.runtime.IProgressMonitorWithBlocking;
15 import org.eclipse.core.runtime.IStatus;
16 import org.eclipse.core.runtime.ProgressMonitorWrapper;
17 import org.eclipse.jface.dialogs.Dialog;
18 import org.eclipse.core.runtime.Assert;
19 import org.eclipse.swt.widgets.Display;
20
21 /**
22  * A progress monitor that accumulates <code>worked</code> and <code>subtask</code>
23  * calls in the following way by wrapping a standard progress monitor:
24  * <ul>
25  * <li> When a <code>worked</code> or <code>subtask</code> call occurs the first time,
26  * the progress monitor posts a runnable into the asynchronous SWT event queue.
27  * </li>
28  * <li> Subsequent calls to <code>worked</code> or <code>subtask</code> do not post
29  * a new runnable as long as a previous runnable still exists in the SWT event
30  * queue. In this case, the progress monitor just updates the internal state of
31  * the runnable that waits in the SWT event queue for its execution. If no runnable
32  * exists, a new one is created and posted into the event queue.
33  * </ul>
34  * <p>
35  * This class is internal to the framework; clients outside JFace should not
36  * use this class.
37  * </p>
38  */

39 /* package */class AccumulatingProgressMonitor extends ProgressMonitorWrapper {
40
41     /**
42      * The display.
43      */

44     private Display display;
45
46     /**
47      * The collector, or <code>null</code> if none.
48      */

49     private Collector collector;
50
51     private String JavaDoc currentTask = ""; //$NON-NLS-1$
52

53     private class Collector implements Runnable JavaDoc {
54         private String JavaDoc subTask;
55
56         private double worked;
57
58         private IProgressMonitor monitor;
59
60         /**
61          * Create a new collector.
62          * @param subTask
63          * @param work
64          * @param monitor
65          */

66         public Collector(String JavaDoc subTask, double work, IProgressMonitor monitor) {
67             this.subTask = subTask;
68             this.worked = work;
69             this.monitor = monitor;
70         }
71
72         /**
73          * Add worked to the work.
74          * @param workedIncrement
75          */

76         public void worked(double workedIncrement) {
77             this.worked = this.worked + workedIncrement;
78         }
79
80         /**
81          * Set the subTask name.
82          * @param subTaskName
83          */

84         public void subTask(String JavaDoc subTaskName) {
85             this.subTask = subTaskName;
86         }
87
88         /**
89          * Run the collector.
90          */

91         public void run() {
92             clearCollector(this);
93             if (subTask != null) {
94                 monitor.subTask(subTask);
95             }
96             if (worked > 0) {
97                 monitor.internalWorked(worked);
98             }
99         }
100     }
101
102     /**
103      * Creates an accumulating progress monitor wrapping the given one
104      * that uses the given display.
105      *
106      * @param monitor the actual progress monitor to be wrapped
107      * @param display the SWT display used to forward the calls
108      * to the wrapped progress monitor
109      */

110     public AccumulatingProgressMonitor(IProgressMonitor monitor, Display display) {
111         super(monitor);
112         Assert.isNotNull(display);
113         this.display = display;
114     }
115
116     /* (non-Javadoc)
117      * Method declared on IProgressMonitor.
118      */

119     public void beginTask(final String JavaDoc name, final int totalWork) {
120         synchronized (this) {
121             collector = null;
122         }
123         display.syncExec(new Runnable JavaDoc() {
124             public void run() {
125                 currentTask = name;
126                 getWrappedProgressMonitor().beginTask(name, totalWork);
127             }
128         });
129     }
130
131     /**
132      * Clears the collector object used to accumulate work and subtask calls
133      * if it matches the given one.
134      * @param collectorToClear
135      */

136     private synchronized void clearCollector(Collector collectorToClear) {
137         // Check if the accumulator is still using the given collector.
138
// If not, don't clear it.
139
if (this.collector == collectorToClear) {
140             this.collector = null;
141         }
142     }
143
144     /**
145      * Creates a collector object to accumulate work and subtask calls.
146      * @param subTask
147      * @param work
148      */

149     private void createCollector(String JavaDoc subTask, double work) {
150         collector = new Collector(subTask, work, getWrappedProgressMonitor());
151         display.asyncExec(collector);
152     }
153
154     /* (non-Javadoc)
155      * Method declared on IProgressMonitor.
156      */

157     public void done() {
158         synchronized (this) {
159             collector = null;
160         }
161         display.syncExec(new Runnable JavaDoc() {
162             public void run() {
163                 getWrappedProgressMonitor().done();
164             }
165         });
166     }
167
168     /* (non-Javadoc)
169      * Method declared on IProgressMonitor.
170      */

171     public synchronized void internalWorked(final double work) {
172         if (collector == null) {
173             createCollector(null, work);
174         } else {
175             collector.worked(work);
176         }
177     }
178
179     /* (non-Javadoc)
180      * Method declared on IProgressMonitor.
181      */

182     public void setTaskName(final String JavaDoc name) {
183         synchronized (this) {
184             collector = null;
185         }
186         display.syncExec(new Runnable JavaDoc() {
187             public void run() {
188                 currentTask = name;
189                 getWrappedProgressMonitor().setTaskName(name);
190             }
191         });
192     }
193
194     /* (non-Javadoc)
195      * Method declared on IProgressMonitor.
196      */

197     public synchronized void subTask(final String JavaDoc name) {
198         if (collector == null) {
199             createCollector(name, 0);
200         } else {
201             collector.subTask(name);
202         }
203     }
204
205     /* (non-Javadoc)
206      * Method declared on IProgressMonitor.
207      */

208     public synchronized void worked(int work) {
209         internalWorked(work);
210     }
211
212     /* (non-Javadoc)
213      * @see org.eclipse.core.runtime.ProgressMonitorWrapper#clearBlocked()
214      */

215     public void clearBlocked() {
216
217         //If this is a monitor that can report blocking do so.
218
//Don't bother with a collector as this should only ever
219
//happen once and prevent any more progress.
220
final IProgressMonitor pm = getWrappedProgressMonitor();
221         if (!(pm instanceof IProgressMonitorWithBlocking)) {
222             return;
223         }
224
225         display.asyncExec(new Runnable JavaDoc() {
226             /* (non-Javadoc)
227              * @see java.lang.Runnable#run()
228              */

229             public void run() {
230                 ((IProgressMonitorWithBlocking) pm).clearBlocked();
231                 Dialog.getBlockedHandler().clearBlocked();
232             }
233         });
234     }
235
236     /* (non-Javadoc)
237      * @see org.eclipse.core.runtime.ProgressMonitorWrapper#setBlocked(org.eclipse.core.runtime.IStatus)
238      */

239     public void setBlocked(final IStatus reason) {
240         //If this is a monitor that can report blocking do so.
241
//Don't bother with a collector as this should only ever
242
//happen once and prevent any more progress.
243
final IProgressMonitor pm = getWrappedProgressMonitor();
244         if (!(pm instanceof IProgressMonitorWithBlocking)) {
245             return;
246         }
247
248         display.asyncExec(new Runnable JavaDoc() {
249             /* (non-Javadoc)
250              * @see java.lang.Runnable#run()
251              */

252             public void run() {
253                 ((IProgressMonitorWithBlocking) pm).setBlocked(reason);
254                 //Do not give a shell as we want it to block until it opens.
255
Dialog.getBlockedHandler().showBlocked(pm, reason, currentTask);
256             }
257         });
258     }
259 }
260
Popular Tags