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

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

sonar - squid:S2221 - "Exception" should not be caught when not required by called methods

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