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

Last change on this file since 4751 was 4718, checked in by jttt, 12 years ago

Add posibility to run please wait runnable tasks in background

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