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

Last change on this file since 4932 was 4907, checked in by jttt, 12 years ago

access gui in edt

  • Property svn:eol-style set to native
File size: 6.7 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 if (EventQueue.isDispatchThread()) {
102 afterFinish();
103 } else {
104 EventQueue.invokeAndWait(new Runnable() {
105 public void run() {
106 afterFinish();
107 }
108 });
109 }
110 }
111 } catch (final Exception e) {
112 if (!ignoreException) {
113 // Exception has to thrown in EDT to be shown to user
114 SwingUtilities.invokeLater(new Runnable() {
115 public void run() {
116 if (e instanceof RuntimeException) {
117 BugReportExceptionHandler.handleException(e);
118 } else {
119 ExceptionDialogUtil.explainException(e);
120 }
121 }
122 });
123 }
124 }
125 }
126
127 /**
128 * Can be overriden if something needs to run after progress monitor is closed.
129 */
130 protected void afterFinish() {
131
132 }
133
134 public final void run() {
135 if (canceled)
136 return; // since realRun isn't executed, do not call to finish
137
138 if (EventQueue.isDispatchThread()) {
139 new Thread(new Runnable() {
140 public void run() {
141 doRealRun();
142 }
143 }).start();
144 } else {
145 doRealRun();
146 }
147 }
148
149 public void operationCanceled() {
150 cancel();
151 }
152
153 /**
154 * User pressed cancel button.
155 */
156 protected abstract void cancel();
157
158 /**
159 * Called in the worker thread to do the actual work. When any of the
160 * exception is thrown, a message box will be displayed and closeDialog
161 * is called. finish() is called in any case.
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 public ProgressMonitor getProgressMonitor() {
172 return progressMonitor;
173 }
174
175 /**
176 * Task can run in background if returned value <> null. Note that it's tasks responsibility
177 * to ensure proper synchronization, PleaseWaitRunnable doesn't with it.
178 * @return If returned value is <> null then task can run in background. TaskId could be used in future for "Always run in background" checkbox
179 */
180 public ProgressTaskId canRunInBackground() {
181 return null;
182 }
183}
Note: See TracBrowser for help on using the repository browser.