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

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

fix #11005 - javadoc update (patch by double-m)

  • Property svn:eol-style set to native
File size: 7.4 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 = false;
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 thrown if parent is null
61 */
62 public PleaseWaitRunnable(Component parent, String title, boolean ignoreException) throws IllegalArgumentException{
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 }).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 */
180 protected abstract void realRun() throws SAXException, IOException, OsmTransferException;
181
182 /**
183 * Finish up the data work. Is guaranteed to be called if realRun is called.
184 * Finish is called in the gui thread just after the dialog disappeared.
185 */
186 protected abstract void finish();
187
188 /**
189 * Relies the progress monitor.
190 * @return the progress monitor
191 */
192 public ProgressMonitor getProgressMonitor() {
193 return progressMonitor;
194 }
195
196 /**
197 * Task can run in background if returned value != null. Note that it's tasks responsibility
198 * to ensure proper synchronization, PleaseWaitRunnable doesn't with it.
199 * @return If returned value is != null then task can run in background. TaskId could be used in future for "Always run in background" checkbox
200 */
201 public ProgressTaskId canRunInBackground() {
202 return null;
203 }
204}
Note: See TracBrowser for help on using the repository browser.