source: josm/trunk/src/org/openstreetmap/josm/gui/progress/AbstractProgressMonitor.java@ 8846

Last change on this file since 8846 was 8846, checked in by Don-vip, 9 years ago

sonar - fb-contrib - minor performance improvements:

  • Method passes constant String of length 1 to character overridden method
  • Method needlessly boxes a boolean constant
  • Method uses iterator().next() on a List to get the first item
  • Method converts String to boxed primitive using excessive boxing
  • Method converts String to primitive using excessive boxing
  • Method creates array using constants
  • Class defines List based fields but uses them like Sets
  • Property svn:eol-style set to native
File size: 10.8 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.progress;
3
4import java.util.Arrays;
5import java.util.Iterator;
6import java.util.LinkedList;
7import java.util.Queue;
8
9public abstract class AbstractProgressMonitor implements ProgressMonitor {
10
11 private static class Request {
12 private AbstractProgressMonitor originator;
13 private int childTicks;
14 private double currentValue;
15
16 private String title;
17 private String customText;
18 private String extraText;
19 private Boolean intermediate;
20
21 private boolean finishRequested;
22 }
23
24 private final CancelHandler cancelHandler;
25
26 protected enum State {INIT, IN_TASK, IN_SUBTASK, FINISHED}
27
28 protected State state = State.INIT;
29
30 private int ticksCount;
31 private int ticks;
32 private int childTicks;
33
34 private String taskTitle;
35 private String customText;
36 private String extraText;
37 private String shownTitle;
38 private String shownCustomText;
39 private boolean intermediateTask;
40
41 private Queue<Request> requests = new LinkedList<>();
42 private AbstractProgressMonitor currentChild;
43 private Request requestedState = new Request();
44
45 protected abstract void doBeginTask();
46
47 protected abstract void doFinishTask();
48
49 protected abstract void doSetIntermediate(boolean value);
50
51 protected abstract void doSetTitle(String title);
52
53 protected abstract void doSetCustomText(String title);
54
55 protected AbstractProgressMonitor(CancelHandler cancelHandler) {
56 this.cancelHandler = cancelHandler;
57 }
58
59 protected void checkState(State... expectedStates) {
60 for (State s:expectedStates) {
61 if (s == state)
62 return;
63 }
64 throw new ProgressException("Expected states are %s but current state is %s", Arrays.asList(expectedStates).toString(), state);
65 }
66
67 /*=======
68 * Tasks
69 =======*/
70
71 @Override
72 public void beginTask(String title) {
73 beginTask(title, DEFAULT_TICKS);
74 }
75
76 @Override
77 public synchronized void beginTask(String title, int ticks) {
78 this.taskTitle = title;
79 checkState(State.INIT);
80 state = State.IN_TASK;
81 doBeginTask();
82 setTicksCount(ticks);
83 resetState();
84 }
85
86 @Override
87 public synchronized void finishTask() {
88 if (state != State.FINISHED) {
89
90 if (state == State.IN_SUBTASK) {
91 requestedState.finishRequested = true;
92 } else {
93 checkState(State.IN_TASK);
94 state = State.FINISHED;
95 doFinishTask();
96 }
97 }
98 }
99
100 @Override
101 public synchronized void invalidate() {
102 if (state == State.INIT) {
103 state = State.FINISHED;
104 doFinishTask();
105 }
106 }
107
108 @Override
109 public synchronized void subTask(final String title) {
110 if (state == State.IN_SUBTASK) {
111 if (title != null) {
112 requestedState.title = title;
113 }
114 requestedState.intermediate = Boolean.FALSE;
115 } else {
116 checkState(State.IN_TASK);
117 if (title != null) {
118 this.taskTitle = title;
119 resetState();
120 }
121 this.intermediateTask = false;
122 doSetIntermediate(false);
123 }
124 }
125
126 @Override
127 public synchronized void indeterminateSubTask(String title) {
128 if (state == State.IN_SUBTASK) {
129 if (title != null) {
130 requestedState.title = title;
131 }
132 requestedState.intermediate = Boolean.TRUE;
133 } else {
134 checkState(State.IN_TASK);
135 if (title != null) {
136 this.taskTitle = title;
137 resetState();
138 }
139 this.intermediateTask = true;
140 doSetIntermediate(true);
141 }
142 }
143
144 @Override
145 public synchronized void setCustomText(String text) {
146 if (state == State.IN_SUBTASK) {
147 requestedState.customText = text;
148 } else {
149 this.customText = text;
150 resetState();
151 }
152 }
153
154 @Override
155 public synchronized void setExtraText(String text) {
156 if (state == State.IN_SUBTASK) {
157 requestedState.extraText = text;
158 } else {
159 this.extraText = text;
160 resetState();
161 }
162 }
163
164 /**
165 * Default implementation is empty. Override in subclasses to display the log messages.
166 */
167 @Override
168 public void appendLogMessage(String message) {
169 // do nothing
170 }
171
172 private void resetState() {
173 String newTitle;
174 if (extraText != null) {
175 newTitle = taskTitle + ' ' + extraText;
176 } else {
177 newTitle = taskTitle;
178 }
179
180 if (newTitle == null ? shownTitle != null : !newTitle.equals(shownTitle)) {
181 shownTitle = newTitle;
182 doSetTitle(shownTitle);
183 }
184
185 if (customText == null ? shownCustomText != null : !customText.equals(shownCustomText)) {
186 shownCustomText = customText;
187 doSetCustomText(shownCustomText);
188 }
189 doSetIntermediate(intermediateTask);
190 }
191
192 @Override
193 public void cancel() {
194 cancelHandler.cancel();
195 }
196
197 @Override
198 public boolean isCanceled() {
199 return cancelHandler.isCanceled();
200 }
201
202 @Override
203 public void addCancelListener(CancelListener listener) {
204 cancelHandler.addCancelListener(listener);
205 }
206
207 @Override
208 public void removeCancelListener(CancelListener listener) {
209 cancelHandler.removeCancelListener(listener);
210 }
211
212 /*=================
213 * Ticks handling
214 ==================*/
215
216 abstract void updateProgress(double value);
217
218 @Override
219 public synchronized void setTicks(int ticks) {
220 if (ticks >= ticksCount) {
221 ticks = ticksCount - 1;
222 }
223 this.ticks = ticks;
224 internalUpdateProgress(0);
225 }
226
227 @Override
228 public synchronized void setTicksCount(int ticks) {
229 this.ticksCount = ticks;
230 internalUpdateProgress(0);
231 }
232
233 @Override
234 public void worked(int ticks) {
235 if (ticks == ALL_TICKS) {
236 setTicks(this.ticksCount - 1);
237 } else {
238 setTicks(this.ticks + ticks);
239 }
240 }
241
242 private void internalUpdateProgress(double childProgress) {
243 if (childProgress > 1) {
244 childProgress = 1;
245 }
246 checkState(State.IN_TASK, State.IN_SUBTASK);
247 updateProgress(ticksCount == 0 ? 0 : (ticks + childProgress * childTicks) / ticksCount);
248 }
249
250 @Override
251 public synchronized int getTicks() {
252 return ticks;
253 }
254
255 @Override
256 public synchronized int getTicksCount() {
257 return ticksCount;
258 }
259
260 /*==========
261 * Subtasks
262 ==========*/
263
264 @Override
265 public synchronized ProgressMonitor createSubTaskMonitor(int ticks, boolean internal) {
266 if (ticks == ALL_TICKS) {
267 ticks = ticksCount - this.ticks;
268 }
269
270 if (state == State.IN_SUBTASK) {
271 Request request = new Request();
272 request.originator = new ChildProgress(this, cancelHandler, internal);
273 request.childTicks = ticks;
274 requests.add(request);
275 return request.originator;
276 } else {
277 checkState(State.IN_TASK);
278 state = State.IN_SUBTASK;
279 this.childTicks = ticks;
280 currentChild = new ChildProgress(this, cancelHandler, internal);
281 return currentChild;
282 }
283 }
284
285 private void applyChildRequest(Request request) {
286 if (request.customText != null) {
287 doSetCustomText(request.customText);
288 }
289
290 if (request.title != null) {
291 doSetTitle(request.title);
292 }
293
294 if (request.intermediate != null) {
295 doSetIntermediate(request.intermediate);
296 }
297
298 internalUpdateProgress(request.currentValue);
299 }
300
301 private void applyThisRequest(Request request) {
302 if (request.finishRequested) {
303 finishTask();
304 } else {
305 if (request.customText != null) {
306 this.customText = request.customText;
307 }
308
309 if (request.title != null) {
310 this.taskTitle = request.title;
311 }
312
313 if (request.intermediate != null) {
314 this.intermediateTask = request.intermediate;
315 }
316
317 if (request.extraText != null) {
318 this.extraText = request.extraText;
319 }
320
321 resetState();
322 }
323 }
324
325 protected synchronized void childFinished(AbstractProgressMonitor child) {
326 checkState(State.IN_SUBTASK);
327 if (currentChild == child) {
328 setTicks(ticks + childTicks);
329 if (requests.isEmpty()) {
330 state = State.IN_TASK;
331 applyThisRequest(requestedState);
332 requestedState = new Request();
333 } else {
334 Request newChild = requests.poll();
335 currentChild = newChild.originator;
336 childTicks = newChild.childTicks;
337 applyChildRequest(newChild);
338 }
339 } else {
340 Iterator<Request> it = requests.iterator();
341 while (it.hasNext()) {
342 if (it.next().originator == child) {
343 it.remove();
344 return;
345 }
346 }
347 throw new ProgressException("Subtask %s not found", child);
348 }
349 }
350
351 private Request getRequest(AbstractProgressMonitor child) {
352 for (Request request:requests) {
353 if (request.originator == child)
354 return request;
355 }
356 throw new ProgressException("Subtask %s not found", child);
357 }
358
359 protected synchronized void childSetProgress(AbstractProgressMonitor child, double value) {
360 checkState(State.IN_SUBTASK);
361 if (currentChild == child) {
362 internalUpdateProgress(value);
363 } else {
364 getRequest(child).currentValue = value;
365 }
366 }
367
368 protected synchronized void childSetTitle(AbstractProgressMonitor child, String title) {
369 checkState(State.IN_SUBTASK);
370 if (currentChild == child) {
371 doSetTitle(title);
372 } else {
373 getRequest(child).title = title;
374 }
375 }
376
377 protected synchronized void childSetCustomText(AbstractProgressMonitor child, String customText) {
378 checkState(State.IN_SUBTASK);
379 if (currentChild == child) {
380 doSetCustomText(customText);
381 } else {
382 getRequest(child).customText = customText;
383 }
384 }
385
386 protected synchronized void childSetIntermediate(AbstractProgressMonitor child, boolean value) {
387 checkState(State.IN_SUBTASK);
388 if (currentChild == child) {
389 doSetIntermediate(value);
390 } else {
391 getRequest(child).intermediate = value;
392 }
393 }
394}
Note: See TracBrowser for help on using the repository browser.