source: josm/trunk/src/org/openstreetmap/josm/gui/progress/PleaseWaitProgressMonitor.java@ 9231

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

javadoc update

  • Property svn:eol-style set to native
File size: 11.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.progress;
3
4import java.awt.Component;
5import java.awt.GraphicsEnvironment;
6import java.awt.event.ActionEvent;
7import java.awt.event.ActionListener;
8import java.awt.event.WindowAdapter;
9import java.awt.event.WindowEvent;
10import java.awt.event.WindowListener;
11
12import javax.swing.JOptionPane;
13import javax.swing.SwingUtilities;
14
15import org.openstreetmap.josm.Main;
16import org.openstreetmap.josm.gui.MapFrame;
17import org.openstreetmap.josm.gui.MapStatus.BackgroundProgressMonitor;
18import org.openstreetmap.josm.gui.PleaseWaitDialog;
19
20public class PleaseWaitProgressMonitor extends AbstractProgressMonitor {
21
22 /**
23 * Implemented by both foreground dialog and background progress dialog (in status bar)
24 */
25 public interface ProgressMonitorDialog {
26 void setVisible(boolean visible);
27
28 void updateProgress(int progress);
29
30 void setCustomText(String text);
31
32 void setCurrentAction(String text);
33
34 void setIndeterminate(boolean newValue);
35
36 // TODO Not implemented properly in background monitor, log message will get lost if progress runs in background
37 void appendLogMessage(String message);
38 }
39
40 public static final int PROGRESS_BAR_MAX = 10000;
41 private final Component dialogParent;
42
43 private int currentProgressValue;
44 private String customText;
45 private String title;
46 private boolean indeterminate;
47
48 private boolean isInBackground;
49 private PleaseWaitDialog dialog;
50 private String windowTitle;
51 protected ProgressTaskId taskId;
52
53 private boolean cancelable;
54
55 private static void doInEDT(Runnable runnable) {
56 // This must be invoke later even if current thread is EDT because inside there is dialog.setVisible
57 // which freeze current code flow until modal dialog is closed
58 SwingUtilities.invokeLater(runnable);
59 }
60
61 private void setDialogVisible(boolean visible) {
62 if (dialog.isVisible() != visible) {
63 dialog.setVisible(visible);
64 }
65 }
66
67 private ProgressMonitorDialog getDialog() {
68
69 BackgroundProgressMonitor backgroundMonitor = null;
70 MapFrame map = Main.map;
71 if (map != null) {
72 backgroundMonitor = map.statusLine.progressMonitor;
73 }
74
75 if (backgroundMonitor != null) {
76 backgroundMonitor.setVisible(isInBackground);
77 }
78 if (dialog != null) {
79 setDialogVisible(!isInBackground || backgroundMonitor == null);
80 }
81
82 if (isInBackground && backgroundMonitor != null) {
83 backgroundMonitor.setVisible(true);
84 if (dialog != null) {
85 setDialogVisible(false);
86 }
87 return backgroundMonitor;
88 } else if (backgroundMonitor != null) {
89 backgroundMonitor.setVisible(false);
90 if (dialog != null) {
91 setDialogVisible(true);
92 }
93 return dialog;
94 } else if (dialog != null) {
95 setDialogVisible(true);
96 return dialog;
97 } else
98 return null;
99 }
100
101 /**
102 * Constructs a new {@code PleaseWaitProgressMonitor}.
103 */
104 public PleaseWaitProgressMonitor() {
105 this("");
106 }
107
108 /**
109 * Constructs a new {@code PleaseWaitProgressMonitor}.
110 * @param windowTitle window title
111 */
112 public PleaseWaitProgressMonitor(String windowTitle) {
113 this(Main.parent);
114 this.windowTitle = windowTitle;
115 }
116
117 /**
118 * Constructs a new {@code PleaseWaitProgressMonitor}.
119 * @param dialogParent component to get parent frame from
120 */
121 public PleaseWaitProgressMonitor(Component dialogParent) {
122 super(new CancelHandler());
123 if (GraphicsEnvironment.isHeadless()) {
124 this.dialogParent = dialogParent;
125 } else {
126 this.dialogParent = JOptionPane.getFrameForComponent(dialogParent);
127 }
128 this.cancelable = true;
129 }
130
131 /**
132 * Constructs a new {@code PleaseWaitProgressMonitor}.
133 * @param dialogParent component to get parent frame from
134 * @param windowTitle window title
135 */
136 public PleaseWaitProgressMonitor(Component dialogParent, String windowTitle) {
137 this(JOptionPane.getFrameForComponent(dialogParent));
138 this.windowTitle = windowTitle;
139 }
140
141 private final ActionListener cancelListener = new ActionListener() {
142 @Override
143 public void actionPerformed(ActionEvent e) {
144 cancel();
145 }
146 };
147
148 private final ActionListener inBackgroundListener = new ActionListener() {
149 @Override
150 public void actionPerformed(ActionEvent e) {
151 isInBackground = true;
152 ProgressMonitorDialog dialog = getDialog();
153 if (dialog != null) {
154 reset();
155 dialog.setVisible(true);
156 }
157 }
158 };
159
160 private final WindowListener windowListener = new WindowAdapter() {
161 @Override public void windowClosing(WindowEvent e) {
162 cancel();
163 }
164 };
165
166 public final boolean isCancelable() {
167 return cancelable;
168 }
169
170 public final void setCancelable(boolean cancelable) {
171 this.cancelable = cancelable;
172 }
173
174 @Override
175 public void doBeginTask() {
176 doInEDT(new Runnable() {
177 @Override
178 public void run() {
179 Main.currentProgressMonitor = PleaseWaitProgressMonitor.this;
180 if (GraphicsEnvironment.isHeadless()) {
181 return;
182 }
183 if (dialogParent != null && dialog == null) {
184 dialog = new PleaseWaitDialog(dialogParent);
185 } else
186 throw new ProgressException("PleaseWaitDialog parent must be set");
187
188 if (windowTitle != null) {
189 dialog.setTitle(windowTitle);
190 }
191 dialog.setCancelEnabled(cancelable);
192 dialog.setCancelCallback(cancelListener);
193 dialog.setInBackgroundCallback(inBackgroundListener);
194 dialog.setCustomText("");
195 dialog.addWindowListener(windowListener);
196 dialog.progress.setMaximum(PROGRESS_BAR_MAX);
197 dialog.setVisible(true);
198 }
199 });
200 }
201
202 @Override
203 public void doFinishTask() {
204 // do nothing
205 }
206
207 @Override
208 protected void updateProgress(double progressValue) {
209 final int newValue = (int) (progressValue * PROGRESS_BAR_MAX);
210 if (newValue != currentProgressValue) {
211 currentProgressValue = newValue;
212 doInEDT(new Runnable() {
213 @Override
214 public void run() {
215 ProgressMonitorDialog dialog = getDialog();
216 if (dialog != null) {
217 dialog.updateProgress(currentProgressValue);
218 }
219 }
220 });
221 }
222 }
223
224 @Override
225 protected void doSetCustomText(final String title) {
226 checkState(State.IN_TASK, State.IN_SUBTASK);
227 this.customText = title;
228 doInEDT(new Runnable() {
229 @Override
230 public void run() {
231 ProgressMonitorDialog dialog = getDialog();
232 if (dialog != null) {
233 dialog.setCustomText(title);
234 }
235 }
236 });
237 }
238
239 @Override
240 protected void doSetTitle(final String title) {
241 checkState(State.IN_TASK, State.IN_SUBTASK);
242 this.title = title;
243 doInEDT(new Runnable() {
244 @Override
245 public void run() {
246 ProgressMonitorDialog dialog = getDialog();
247 if (dialog != null) {
248 dialog.setCurrentAction(title);
249 }
250 }
251 });
252 }
253
254 @Override
255 protected void doSetIntermediate(final boolean value) {
256 this.indeterminate = value;
257 doInEDT(new Runnable() {
258 @Override
259 public void run() {
260 // Enable only if progress is at the beginning. Doing intermediate progress in the middle
261 // will hide already reached progress
262 ProgressMonitorDialog dialog = getDialog();
263 if (dialog != null) {
264 dialog.setIndeterminate(value && currentProgressValue == 0);
265 }
266 }
267 });
268 }
269
270 @Override
271 public void appendLogMessage(final String message) {
272 doInEDT(new Runnable() {
273 @Override
274 public void run() {
275 ProgressMonitorDialog dialog = getDialog();
276 if (dialog != null) {
277 dialog.appendLogMessage(message);
278 }
279 }
280 });
281 }
282
283 public void reset() {
284 if (dialog != null) {
285 dialog.setTitle(title);
286 dialog.setCustomText(customText);
287 dialog.updateProgress(currentProgressValue);
288 dialog.setIndeterminate(indeterminate && currentProgressValue == 0);
289 }
290 BackgroundProgressMonitor backgroundMonitor = null;
291 MapFrame map = Main.map;
292 if (map != null) {
293 backgroundMonitor = map.statusLine.progressMonitor;
294 }
295 if (backgroundMonitor != null) {
296 backgroundMonitor.setCurrentAction(title);
297 backgroundMonitor.setCustomText(customText);
298 backgroundMonitor.updateProgress(currentProgressValue);
299 backgroundMonitor.setIndeterminate(indeterminate && currentProgressValue == 0);
300 }
301
302 }
303
304 public void close() {
305 doInEDT(new Runnable() {
306 @Override
307 public void run() {
308 if (dialog != null) {
309 dialog.setVisible(false);
310 dialog.setCancelCallback(null);
311 dialog.setInBackgroundCallback(null);
312 dialog.removeWindowListener(windowListener);
313 dialog.dispose();
314 dialog = null;
315 Main.currentProgressMonitor = null;
316 MapFrame map = Main.map;
317 if (map != null) {
318 map.statusLine.progressMonitor.setVisible(false);
319 }
320 }
321 }
322 });
323 }
324
325 public void showForegroundDialog() {
326 isInBackground = false;
327 doInEDT(new Runnable() {
328 @Override
329 public void run() {
330 if (dialog != null) {
331 dialog.setInBackgroundPossible(PleaseWaitProgressMonitor.this.taskId != null && Main.isDisplayingMapView());
332 reset();
333 getDialog();
334 }
335 }
336 });
337
338 }
339
340 @Override
341 public void setProgressTaskId(ProgressTaskId taskId) {
342 this.taskId = taskId;
343 doInEDT(new Runnable() {
344 @Override
345 public void run() {
346 if (dialog != null) {
347 dialog.setInBackgroundPossible(PleaseWaitProgressMonitor.this.taskId != null && Main.isDisplayingMapView());
348 }
349 }
350 });
351 }
352
353 @Override
354 public ProgressTaskId getProgressTaskId() {
355 return taskId;
356 }
357
358 @Override
359 public Component getWindowParent() {
360 Component parent = dialog;
361 if (isInBackground || parent == null)
362 return Main.parent;
363 else
364 return parent;
365 }
366}
Note: See TracBrowser for help on using the repository browser.