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

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

see #11390 - sonar - squid:S1604 - Java 8: Anonymous inner classes containing only one method should become lambdas

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