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

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

see #11390 - sonar - squid:S1604 - Java 8: Anonymous inner classes containing only one method should become lambdas

  • Property svn:eol-style set to native
File size: 7.1 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(this::finish);
99 }
100 }
101 } finally {
102 progressMonitor.finishTask();
103 progressMonitor.removeCancelListener(this);
104 progressMonitor.setProgressTaskId(oldTaskId);
105 if (progressMonitor instanceof PleaseWaitProgressMonitor) {
106 ((PleaseWaitProgressMonitor) progressMonitor).close();
107 }
108 if (EventQueue.isDispatchThread()) {
109 afterFinish();
110 } else {
111 EventQueue.invokeAndWait(this::afterFinish);
112 }
113 }
114 } catch (final RuntimeException |
115 OsmTransferException | IOException | SAXException | InvocationTargetException | InterruptedException e) {
116 if (!ignoreException) {
117 // Exception has to thrown in EDT to be shown to user
118 SwingUtilities.invokeLater(() -> {
119 if (e instanceof RuntimeException) {
120 BugReportExceptionHandler.handleException(e);
121 } else {
122 ExceptionDialogUtil.explainException(e);
123 }
124 });
125 }
126 }
127 }
128
129 /**
130 * Can be overriden if something needs to run after progress monitor is closed.
131 */
132 protected void afterFinish() {
133
134 }
135
136 @Override
137 public final void run() {
138 if (EventQueue.isDispatchThread()) {
139 new Thread((Runnable) this::doRealRun, getClass().getName()).start();
140 } else {
141 doRealRun();
142 }
143 }
144
145 @Override
146 public void operationCanceled() {
147 cancel();
148 }
149
150 /**
151 * User pressed cancel button.
152 */
153 protected abstract void cancel();
154
155 /**
156 * Called in the worker thread to do the actual work. When any of the
157 * exception is thrown, a message box will be displayed and closeDialog
158 * is called. finish() is called in any case.
159 * @throws SAXException if a SAX error occurs
160 * @throws IOException if an I/O error occurs
161 * @throws OsmTransferException if a communication error with the OSM server occurs
162 */
163 protected abstract void realRun() throws SAXException, IOException, OsmTransferException;
164
165 /**
166 * Finish up the data work. Is guaranteed to be called if realRun is called.
167 * Finish is called in the gui thread just after the dialog disappeared.
168 */
169 protected abstract void finish();
170
171 /**
172 * Relies the progress monitor.
173 * @return the progress monitor
174 */
175 public ProgressMonitor getProgressMonitor() {
176 return progressMonitor;
177 }
178
179 /**
180 * Task can run in background if returned value != null. Note that it's tasks responsibility
181 * to ensure proper synchronization, PleaseWaitRunnable doesn't with it.
182 * @return If returned value is != null then task can run in background.
183 * TaskId could be used in future for "Always run in background" checkbox
184 */
185 public ProgressTaskId canRunInBackground() {
186 return null;
187 }
188}
Note: See TracBrowser for help on using the repository browser.