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

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

findbugs: DP_DO_INSIDE_DO_PRIVILEGED + UWF_UNWRITTEN_FIELD + RC_REF_COMPARISON + OBL_UNSATISFIED_OBLIGATION_EXCEPTION_EDGE

  • Property svn:eol-style set to native
File size: 7.7 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;
7import java.lang.reflect.InvocationTargetException;
8
9import javax.swing.SwingUtilities;
10
11import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;
12import org.openstreetmap.josm.gui.progress.ProgressMonitor;
13import org.openstreetmap.josm.gui.progress.ProgressMonitor.CancelListener;
14import org.openstreetmap.josm.gui.progress.ProgressTaskId;
15import org.openstreetmap.josm.io.OsmTransferException;
16import org.openstreetmap.josm.tools.CheckParameterUtil;
17import org.openstreetmap.josm.tools.bugreport.BugReportExceptionHandler;
18import org.xml.sax.SAXException;
19
20/**
21 * Instanced of this thread will display a "Please Wait" message in middle of JOSM
22 * to indicate a progress being executed.
23 *
24 * @author Imi
25 */
26public abstract class PleaseWaitRunnable implements Runnable, CancelListener {
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 RuntimeException |
125 OsmTransferException | IOException | SAXException | InvocationTargetException | InterruptedException e) {
126 if (!ignoreException) {
127 // Exception has to thrown in EDT to be shown to user
128 SwingUtilities.invokeLater(new Runnable() {
129 @Override
130 public void run() {
131 if (e instanceof RuntimeException) {
132 BugReportExceptionHandler.handleException(e);
133 } else {
134 ExceptionDialogUtil.explainException(e);
135 }
136 }
137 });
138 }
139 }
140 }
141
142 /**
143 * Can be overriden if something needs to run after progress monitor is closed.
144 */
145 protected void afterFinish() {
146
147 }
148
149 @Override
150 public final void run() {
151 if (EventQueue.isDispatchThread()) {
152 new Thread(new Runnable() {
153 @Override
154 public void run() {
155 doRealRun();
156 }
157 }, getClass().getName()).start();
158 } else {
159 doRealRun();
160 }
161 }
162
163 @Override
164 public void operationCanceled() {
165 cancel();
166 }
167
168 /**
169 * User pressed cancel button.
170 */
171 protected abstract void cancel();
172
173 /**
174 * Called in the worker thread to do the actual work. When any of the
175 * exception is thrown, a message box will be displayed and closeDialog
176 * is called. finish() is called in any case.
177 * @throws SAXException if a SAX error occurs
178 * @throws IOException if an I/O error occurs
179 * @throws OsmTransferException if a communication error with the OSM server occurs
180 */
181 protected abstract void realRun() throws SAXException, IOException, OsmTransferException;
182
183 /**
184 * Finish up the data work. Is guaranteed to be called if realRun is called.
185 * Finish is called in the gui thread just after the dialog disappeared.
186 */
187 protected abstract void finish();
188
189 /**
190 * Relies the progress monitor.
191 * @return the progress monitor
192 */
193 public ProgressMonitor getProgressMonitor() {
194 return progressMonitor;
195 }
196
197 /**
198 * Task can run in background if returned value != null. Note that it's tasks responsibility
199 * to ensure proper synchronization, PleaseWaitRunnable doesn't with it.
200 * @return If returned value is != null then task can run in background.
201 * TaskId could be used in future for "Always run in background" checkbox
202 */
203 public ProgressTaskId canRunInBackground() {
204 return null;
205 }
206}
Note: See TracBrowser for help on using the repository browser.