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

Last change on this file since 14206 was 12846, checked in by bastiK, 7 years ago

see #15229 - use Config.getPref() wherever possible

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