source: josm/trunk/src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java@ 8855

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

sonar - squid:S3052 - Fields should not be initialized to default values

  • Property svn:eol-style set to native
File size: 7.6 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui;
3
4import java.awt.Component;
5import java.awt.EventQueue;
6import java.io.IOException;
7
8import javax.swing.SwingUtilities;
9
10import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;
11import org.openstreetmap.josm.gui.progress.ProgressMonitor;
12import org.openstreetmap.josm.gui.progress.ProgressMonitor.CancelListener;
13import org.openstreetmap.josm.gui.progress.ProgressTaskId;
14import org.openstreetmap.josm.io.OsmTransferException;
15import org.openstreetmap.josm.tools.BugReportExceptionHandler;
16import org.openstreetmap.josm.tools.CheckParameterUtil;
17import org.xml.sax.SAXException;
18
19/**
20 * Instanced of this thread will display a "Please Wait" message in middle of JOSM
21 * to indicate a progress being executed.
22 *
23 * @author Imi
24 */
25public abstract class PleaseWaitRunnable implements Runnable, CancelListener {
26 private boolean canceled;
27 private boolean ignoreException;
28 private final String title;
29
30 protected final ProgressMonitor progressMonitor;
31
32 /**
33 * Create the runnable object with a given message for the user.
34 * @param title message for the user
35 */
36 public PleaseWaitRunnable(String title) {
37 this(title, false);
38 }
39
40 /**
41 * Create the runnable object with a given message for the user.
42 *
43 * @param title message for the user
44 * @param ignoreException If true, exception will be silently ignored. If false then
45 * exception will be handled by showing a dialog. When this runnable is executed using executor framework
46 * then use false unless you read result of task (because exception will get lost if you don't)
47 */
48 public PleaseWaitRunnable(String title, boolean ignoreException) {
49 this(title, new PleaseWaitProgressMonitor(title), ignoreException);
50 }
51
52 /**
53 * Create the runnable object with a given message for the user
54 *
55 * @param parent the parent component for the please wait dialog. Must not be null.
56 * @param title message for the user
57 * @param ignoreException If true, exception will be silently ignored. If false then
58 * exception will be handled by showing a dialog. When this runnable is executed using executor framework
59 * then use false unless you read result of task (because exception will get lost if you don't)
60 * @throws IllegalArgumentException if parent is null
61 */
62 public PleaseWaitRunnable(Component parent, String title, boolean ignoreException) {
63 CheckParameterUtil.ensureParameterNotNull(parent, "parent");
64 this.title = title;
65 this.progressMonitor = new PleaseWaitProgressMonitor(parent, title);
66 this.ignoreException = ignoreException;
67 }
68
69 /**
70 * Create the runnable object with a given message for the user
71 *
72 * @param title message for the user
73 * @param progressMonitor progress monitor
74 * @param ignoreException If true, exception will be silently ignored. If false then
75 * exception will be handled by showing a dialog. When this runnable is executed using executor framework
76 * then use false unless you read result of task (because exception will get lost if you don't)
77 */
78 public PleaseWaitRunnable(String title, ProgressMonitor progressMonitor, boolean ignoreException) {
79 this.title = title;
80 this.progressMonitor = progressMonitor == null ? new PleaseWaitProgressMonitor(title) : progressMonitor;
81 this.ignoreException = ignoreException;
82 }
83
84 private void doRealRun() {
85 try {
86 ProgressTaskId oldTaskId = null;
87 try {
88 progressMonitor.addCancelListener(this);
89 progressMonitor.beginTask(title);
90 oldTaskId = progressMonitor.getProgressTaskId();
91 progressMonitor.setProgressTaskId(canRunInBackground());
92 try {
93 realRun();
94 } finally {
95 if (EventQueue.isDispatchThread()) {
96 finish();
97 } else {
98 EventQueue.invokeAndWait(new Runnable() {
99 @Override
100 public void run() {
101 finish();
102 }
103 });
104 }
105 }
106 } finally {
107 progressMonitor.finishTask();
108 progressMonitor.removeCancelListener(this);
109 progressMonitor.setProgressTaskId(oldTaskId);
110 if (progressMonitor instanceof PleaseWaitProgressMonitor) {
111 ((PleaseWaitProgressMonitor) progressMonitor).close();
112 }
113 if (EventQueue.isDispatchThread()) {
114 afterFinish();
115 } else {
116 EventQueue.invokeAndWait(new Runnable() {
117 @Override
118 public void run() {
119 afterFinish();
120 }
121 });
122 }
123 }
124 } catch (final Exception e) {
125 if (!ignoreException) {
126 // Exception has to thrown in EDT to be shown to user
127 SwingUtilities.invokeLater(new Runnable() {
128 @Override
129 public void run() {
130 if (e instanceof RuntimeException) {
131 BugReportExceptionHandler.handleException(e);
132 } else {
133 ExceptionDialogUtil.explainException(e);
134 }
135 }
136 });
137 }
138 }
139 }
140
141 /**
142 * Can be overriden if something needs to run after progress monitor is closed.
143 */
144 protected void afterFinish() {
145
146 }
147
148 @Override
149 public final void run() {
150 if (canceled)
151 return; // since realRun isn't executed, do not call to finish
152
153 if (EventQueue.isDispatchThread()) {
154 new Thread(new Runnable() {
155 @Override
156 public void run() {
157 doRealRun();
158 }
159 }, getClass().getName()).start();
160 } else {
161 doRealRun();
162 }
163 }
164
165 @Override
166 public void operationCanceled() {
167 cancel();
168 }
169
170 /**
171 * User pressed cancel button.
172 */
173 protected abstract void cancel();
174
175 /**
176 * Called in the worker thread to do the actual work. When any of the
177 * exception is thrown, a message box will be displayed and closeDialog
178 * is called. finish() is called in any case.
179 * @throws SAXException if a SAX error occurs
180 * @throws IOException if an I/O error occurs
181 * @throws OsmTransferException if a communication error with the OSM server occurs
182 */
183 protected abstract void realRun() throws SAXException, IOException, OsmTransferException;
184
185 /**
186 * Finish up the data work. Is guaranteed to be called if realRun is called.
187 * Finish is called in the gui thread just after the dialog disappeared.
188 */
189 protected abstract void finish();
190
191 /**
192 * Relies the progress monitor.
193 * @return the progress monitor
194 */
195 public ProgressMonitor getProgressMonitor() {
196 return progressMonitor;
197 }
198
199 /**
200 * Task can run in background if returned value != null. Note that it's tasks responsibility
201 * to ensure proper synchronization, PleaseWaitRunnable doesn't with it.
202 * @return If returned value is != null then task can run in background.
203 * TaskId could be used in future for "Always run in background" checkbox
204 */
205 public ProgressTaskId canRunInBackground() {
206 return null;
207 }
208}
Note: See TracBrowser for help on using the repository browser.