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

Last change on this file since 5534 was 5534, checked in by bastiK, 12 years ago

increase maximum resolution of progress bar
manual repaint is required, otherwise it will display
at most 100 steps (at least in Metal L&F)

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