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

Last change on this file since 7135 was 6830, checked in by Don-vip, 10 years ago

javadoc fixes for jdk8 compatibility

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