1 56 package org.objectstyle.cayenne.modeler.util; 57 58 import java.awt.event.ActionEvent ; 59 import java.awt.event.ActionListener ; 60 61 import javax.swing.JFrame ; 62 import javax.swing.JProgressBar ; 63 import javax.swing.SwingUtilities ; 64 import javax.swing.Timer ; 65 66 import org.apache.log4j.Logger; 67 import org.objectstyle.cayenne.CayenneRuntimeException; 68 69 81 public abstract class LongRunningTask { 82 83 private static final Logger logObj = Logger.getLogger(LongRunningTask.class); 84 85 protected static final int DEFAULT_MS_TO_DECIDE_TO_POPUP = 500; 86 87 protected ProgressDialog dialog; 88 protected JFrame frame; 89 protected String title; 90 protected Timer taskPollingTimer; 91 protected boolean canceled; 92 protected int minValue; 93 protected int maxValue; 94 protected boolean finished; 95 96 public LongRunningTask(JFrame frame, String title) { 97 this.frame = frame; 98 this.title = title; 99 } 100 101 104 public synchronized void startAndWait() { 105 if (SwingUtilities.isEventDispatchThread()) { 107 throw new CayenneRuntimeException( 108 "Can't block EventDispatchThread. Call 'startAndWait' from another thread."); 109 } 110 111 start(); 112 113 if (finished) { 114 return; 115 } 116 117 try { 118 wait(); 119 } 120 catch (InterruptedException e) { 121 setCanceled(true); 122 } 123 124 notifyAll(); 125 } 126 127 131 public void start() { 132 setCanceled(false); 134 this.finished = false; 135 136 Thread task = new Thread (new Runnable () { 137 138 public void run() { 139 internalExecute(); 140 } 141 }); 142 143 Timer progressDisplayTimer = new Timer ( 144 DEFAULT_MS_TO_DECIDE_TO_POPUP, 145 new ActionListener () { 146 147 public void actionPerformed(ActionEvent e) { 148 showProgress(); 149 } 150 }); 151 152 progressDisplayTimer.setRepeats(false); 153 154 progressDisplayTimer.start(); 156 task.start(); 157 } 158 159 162 protected synchronized void showProgress() { 163 logObj.debug("will show progress..."); 164 165 if (finished) { 166 return; 167 } 168 169 int currentValue = getCurrentValue(); 170 171 if (!isCanceled() && currentValue < getMaxValue()) { 172 173 logObj.debug("task still in progress, will show progress dialog..."); 174 this.dialog = new ProgressDialog(frame, "Progress...", title); 175 this.dialog.getCancelButton().addActionListener(new ActionListener () { 176 177 public void actionPerformed(ActionEvent e) { 178 setCanceled(true); 179 } 180 }); 181 182 dialog.getProgressBar().setMinimum(getMinValue()); 183 dialog.getProgressBar().setMaximum(getMaxValue()); 184 updateProgress(); 185 186 this.taskPollingTimer = new Timer (500, new ActionListener () { 187 188 public void actionPerformed(ActionEvent e) { 189 updateProgress(); 190 } 191 }); 192 193 this.taskPollingTimer.start(); 194 this.dialog.setVisible(true); 195 } 196 } 197 198 201 protected void updateProgress() { 202 if (isCanceled()) { 203 stop(); 204 return; 205 } 206 207 dialog.getStatusLabel().setText(getCurrentNote()); 208 209 JProgressBar progressBar = dialog.getProgressBar(); 210 if (!isIndeterminate()) { 211 progressBar.setValue(getCurrentValue()); 212 progressBar.setIndeterminate(false); 213 } 214 else { 215 progressBar.setIndeterminate(true); 216 } 217 } 218 219 protected synchronized void stop() { 220 if (taskPollingTimer != null) { 221 taskPollingTimer.stop(); 222 } 223 224 if (dialog != null) { 225 dialog.dispose(); 226 } 227 228 finished = true; 230 notifyAll(); 231 } 232 233 public boolean isFinished() { 234 return finished; 235 } 236 237 public boolean isCanceled() { 238 return canceled; 239 } 240 241 public void setCanceled(boolean b) { 242 if (b) { 243 logObj.debug("task canceled"); 244 } 245 246 this.canceled = b; 247 } 248 249 protected void internalExecute() { 250 try { 251 execute(); 252 } 253 catch (Throwable th) { 254 setCanceled(true); 255 logObj.warn("task error", th); 256 } 257 finally { 258 stop(); 259 } 260 } 261 262 266 protected abstract void execute(); 267 268 protected abstract String getCurrentNote(); 269 270 protected abstract int getCurrentValue(); 271 272 protected abstract boolean isIndeterminate(); 273 274 public int getMaxValue() { 275 return maxValue; 276 } 277 278 public void setMaxValue(int maxValue) { 279 this.maxValue = maxValue; 280 } 281 282 public int getMinValue() { 283 return minValue; 284 } 285 286 public void setMinValue(int minValue) { 287 this.minValue = minValue; 288 } 289 } | Popular Tags |