1 19 20 package org.netbeans.modules.j2ee.persistence.util; 21 22 import java.awt.event.ActionEvent ; 23 import java.awt.event.ActionListener ; 24 import java.util.ArrayList ; 25 import java.util.Collection ; 26 import java.util.List ; 27 import javax.swing.JComponent ; 28 import javax.swing.SwingUtilities ; 29 import org.netbeans.api.progress.ProgressHandle; 30 import org.netbeans.api.progress.ProgressHandleFactory; 31 import org.openide.ErrorManager; 32 import org.openide.util.Cancellable; 33 import org.openide.util.Mutex; 34 import org.openide.util.RequestProcessor; 35 36 57 public class EventRequestProcessor { 58 59 64 66 private static final ErrorManager LOGGER = ErrorManager.getDefault().getInstance("org.netbeans.modules.j2ee.persistence.util"); private static final boolean LOG = LOGGER.isLoggable(ErrorManager.INFORMATIONAL); 68 69 ActionInvoker actionInvoker; 71 72 public EventRequestProcessor() { 73 } 74 75 public void invoke(Collection <Action> actions) { 76 invoke(actions, false); 77 } 78 79 83 public boolean invoke(Collection <Action> actions, boolean cancellable) { 84 if (!SwingUtilities.isEventDispatchThread()) { 85 throw new IllegalStateException ("This method must be called in the event thread."); } 87 if (this.actionInvoker != null) { 88 throw new IllegalStateException ("The invoke() method is running."); } 90 91 actionInvoker = new ActionInvoker(new ArrayList <Action>(actions), cancellable); 92 boolean success; 93 94 try { 95 success = actionInvoker.invoke(); 96 } finally { 97 actionInvoker = null; 98 } 99 100 return success; 101 } 102 103 private static final class ActionInvoker implements ActionListener { 104 105 private final List <Action> actions; 106 private final boolean cancellable; 107 108 private Context actionContext; 109 private int currentActionIndex; 110 private boolean cancelled; 111 112 public ActionInvoker(List <Action> actions, boolean cancellable) { 113 this.actions = actions; 114 this.cancellable = cancellable; 115 } 116 117 121 public boolean invoke() { 122 assert SwingUtilities.isEventDispatchThread(); 123 124 final ProgressPanel progressPanel = new ProgressPanel(); 125 progressPanel.setCancelVisible(cancellable); 126 progressPanel.addCancelActionListener(this); 127 128 ProgressHandle progressHandle = ProgressHandleFactory.createHandle(null); 129 JComponent progressComponent = ProgressHandleFactory.createProgressComponent(progressHandle); 130 progressHandle.start(); 131 progressHandle.switchToIndeterminate(); 132 133 actionContext = new Context(new Progress(progressPanel, progressHandle)); 134 135 final Throwable [] exceptions = new Throwable [1]; 138 139 try { 140 141 RequestProcessor.Task task = RequestProcessor.getDefault().create(new Runnable () { 142 public void run() { 143 try { 144 invokeActionsUntilThreadSwitch(); 145 } catch (Throwable t) { 146 exceptions[0] = t; 147 } finally { 148 SwingUtilities.invokeLater(new Runnable () { 149 public void run() { 150 progressPanel.close(); 151 } 152 }); 153 } 154 } 155 }); 156 157 boolean runInEDT = true; 158 159 for (;;) { 160 161 if (currentActionIndex >= actions.size() || cancelled) { 162 break; 163 } 164 165 try { 166 if (!runInEDT) { 167 task.schedule(0); 170 progressPanel.open(progressComponent); 171 } 172 173 invokeActionsUntilThreadSwitch(); 174 175 if (!runInEDT) { 176 task.waitFinished(); 181 } 182 } catch (Throwable t) { 183 exceptions[0] = t; 184 } 185 186 if (exceptions[0] != null) { 187 if (exceptions[0] instanceof RuntimeException ) { 188 throw (RuntimeException )exceptions[0]; 189 } else { 190 RuntimeException exception = new RuntimeException (exceptions[0].getMessage()); 191 exception.initCause(exceptions[0]); 192 throw exception; 193 } 194 } 195 196 runInEDT = !runInEDT; 197 } 198 } finally { 199 progressHandle.finish(); 200 } 201 202 return !cancelled; 203 } 204 205 private void invokeActionsUntilThreadSwitch() { 206 boolean isEventThread = SwingUtilities.isEventDispatchThread(); 207 208 for (;;) { 209 210 synchronized (this) { 211 if (cancelled) { 214 break; 215 } 216 } 217 218 if (currentActionIndex >= actions.size()) { 219 break; 220 } 221 222 Action action = actions.get(currentActionIndex); 223 if (!action.isEnabled()) { 224 if (LOG) { 225 LOGGER.log("Skipping " + action); } 227 synchronized (this) { 228 currentActionIndex++; 231 } 232 continue; 233 } 234 235 if (action.getRunInEventThread() != isEventThread) { 236 break; 237 } 238 239 if (LOG) { 240 LOGGER.log("Running " + action); } 242 243 if (!isEventThread) { 245 final boolean cancelEnabled = action instanceof Cancellable; 246 SwingUtilities.invokeLater(new Runnable () { 247 public void run() { 248 actionContext.getProgress().getPanel().setCancelEnabled(cancelEnabled); 249 } 250 }); 251 } 252 253 action.run(actionContext); 254 255 synchronized (this) { 256 currentActionIndex++; 259 } 260 } 261 262 } 263 264 public void actionPerformed(ActionEvent event) { 265 synchronized (this) { 266 267 if (cancelled) { 269 return; 270 } 271 272 if (currentActionIndex >= actions.size()) { 274 return; 275 } 276 277 Action currentAction = actions.get(currentActionIndex); 278 279 if (!currentAction.getRunInEventThread() && currentAction instanceof Cancellable) { 284 cancelled = ((Cancellable)currentAction).cancel(); 286 if (cancelled) { 287 actionContext.getProgress().getPanel().setCancelEnabled(false); 288 } 289 } 290 } 291 } 292 } 293 294 298 public static final class Context { 299 300 private final Progress progress; 301 302 public Context(Progress progress) { 303 this.progress = progress; 304 } 305 306 public Progress getProgress() { 307 return progress; 308 } 309 } 310 311 314 public static final class Progress { 315 316 private final ProgressPanel panel; 317 private final ProgressHandle handle; 318 319 private Progress(ProgressPanel panel, ProgressHandle handle) { 320 this.panel = panel; 321 this.handle = handle; 322 } 323 324 public void switchToDeterminate(int workunits) { 325 handle.switchToDeterminate(workunits); 326 } 327 328 public void progress(final String message) { 329 Mutex.EVENT.readAccess(new Runnable () { 330 public void run() { 331 panel.setText(message); 332 } 333 }); 334 handle.progress(message); 335 } 336 337 public void progress(int workunit) { 338 handle.progress(workunit); 339 } 340 341 344 ProgressPanel getPanel() { 345 return panel; 346 } 347 } 348 349 353 public interface Action { 354 355 359 public boolean getRunInEventThread(); 360 361 369 public boolean isEnabled(); 370 371 374 public void run(Context actionContext); 375 } 376 377 public interface CancellableAction extends Action, Cancellable { 378 379 } 380 381 385 public static abstract class SynchronousAction implements Action { 386 387 public boolean getRunInEventThread() { 388 return true; 389 } 390 391 public boolean isEnabled() { 392 return true; 393 } 394 } 395 396 400 public static abstract class AsynchronousAction implements Action { 401 402 public boolean getRunInEventThread() { 403 return false; 404 } 405 406 public boolean isEnabled() { 407 return true; 408 } 409 } 410 } 411 | Popular Tags |