1 19 20 package org.netbeans.modules.j2ee.common; 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 51 public class EventRequestProcessor { 52 53 58 60 private static final ErrorManager LOGGER = ErrorManager.getDefault().getInstance("org.netbeans.modules.j2ee.persistence.util"); private static final boolean LOG = LOGGER.isLoggable(ErrorManager.INFORMATIONAL); 62 63 ActionInvoker actionInvoker; 65 66 public EventRequestProcessor() { 67 } 68 69 public void invoke(Collection <Action> actions) { 70 invoke(actions, false); 71 } 72 73 77 public boolean invoke(Collection <Action> actions, boolean cancellable) { 78 if (!SwingUtilities.isEventDispatchThread()) { 79 throw new IllegalStateException ("This method must be called in the event thread."); } 81 if (this.actionInvoker != null) { 82 throw new IllegalStateException ("The invoke() method is running."); } 84 85 actionInvoker = new ActionInvoker(new ArrayList <Action>(actions), cancellable); 86 boolean success; 87 88 try { 89 success = actionInvoker.invoke(); 90 } finally { 91 actionInvoker = null; 92 } 93 94 return success; 95 } 96 97 private static final class ActionInvoker implements ActionListener { 98 99 private final List <Action> actions; 100 private final boolean cancellable; 101 102 private Context actionContext; 103 private int currentActionIndex; 104 private boolean cancelled; 105 106 public ActionInvoker(List <Action> actions, boolean cancellable) { 107 this.actions = actions; 108 this.cancellable = cancellable; 109 } 110 111 115 public boolean invoke() { 116 assert SwingUtilities.isEventDispatchThread(); 117 118 final ProgressPanel progressPanel = new ProgressPanel(); 119 progressPanel.setCancelVisible(cancellable); 120 progressPanel.addCancelActionListener(this); 121 122 ProgressHandle progressHandle = ProgressHandleFactory.createHandle(null); 123 JComponent progressComponent = ProgressHandleFactory.createProgressComponent(progressHandle); 124 progressHandle.start(); 125 progressHandle.switchToIndeterminate(); 126 127 actionContext = new Context(new Progress(progressPanel, progressHandle)); 128 129 final Throwable [] exceptions = new Throwable [1]; 132 133 try { 134 135 RequestProcessor.Task task = RequestProcessor.getDefault().create(new Runnable () { 136 public void run() { 137 try { 138 invokeActionsUntilThreadSwitch(); 139 } catch (Throwable t) { 140 exceptions[0] = t; 141 } finally { 142 SwingUtilities.invokeLater(new Runnable () { 143 public void run() { 144 progressPanel.close(); 145 } 146 }); 147 } 148 } 149 }); 150 151 boolean runInEDT = true; 152 153 for (;;) { 154 155 if (currentActionIndex >= actions.size() || cancelled) { 156 break; 157 } 158 159 try { 160 if (!runInEDT) { 161 task.schedule(0); 164 progressPanel.open(progressComponent); 165 } 166 167 invokeActionsUntilThreadSwitch(); 168 169 if (!runInEDT) { 170 task.waitFinished(); 175 } 176 } catch (Throwable t) { 177 exceptions[0] = t; 178 } 179 180 if (exceptions[0] != null) { 181 if (exceptions[0] instanceof RuntimeException ) { 182 throw (RuntimeException )exceptions[0]; 183 } else { 184 RuntimeException exception = new RuntimeException (exceptions[0].getMessage()); 185 exception.initCause(exceptions[0]); 186 throw exception; 187 } 188 } 189 190 runInEDT = !runInEDT; 191 } 192 } finally { 193 progressHandle.finish(); 194 } 195 196 return !cancelled; 197 } 198 199 private void invokeActionsUntilThreadSwitch() { 200 boolean isEventThread = SwingUtilities.isEventDispatchThread(); 201 202 for (;;) { 203 204 synchronized (this) { 205 if (cancelled) { 208 break; 209 } 210 } 211 212 if (currentActionIndex >= actions.size()) { 213 break; 214 } 215 216 Action action = actions.get(currentActionIndex); 217 if (!action.isEnabled()) { 218 if (LOG) { 219 LOGGER.log("Skipping " + action); } 221 synchronized (this) { 222 currentActionIndex++; 225 } 226 continue; 227 } 228 229 if (action.getRunInEventThread() != isEventThread) { 230 break; 231 } 232 233 if (LOG) { 234 LOGGER.log("Running " + action); } 236 237 if (!isEventThread) { 239 final boolean cancelEnabled = action instanceof Cancellable; 240 SwingUtilities.invokeLater(new Runnable () { 241 public void run() { 242 actionContext.getProgress().getPanel().setCancelEnabled(cancelEnabled); 243 } 244 }); 245 } 246 247 action.run(actionContext); 248 249 synchronized (this) { 250 currentActionIndex++; 253 } 254 } 255 256 } 257 258 public void actionPerformed(ActionEvent event) { 259 synchronized (this) { 260 261 if (cancelled) { 263 return; 264 } 265 266 if (currentActionIndex >= actions.size()) { 268 return; 269 } 270 271 Action currentAction = actions.get(currentActionIndex); 272 273 if (!currentAction.getRunInEventThread() && currentAction instanceof Cancellable) { 278 cancelled = ((Cancellable)currentAction).cancel(); 280 if (cancelled) { 281 actionContext.getProgress().getPanel().setCancelEnabled(false); 282 } 283 } 284 } 285 } 286 } 287 288 292 public static final class Context { 293 294 private final Progress progress; 295 296 public Context(Progress progress) { 297 this.progress = progress; 298 } 299 300 public Progress getProgress() { 301 return progress; 302 } 303 } 304 305 308 public static final class Progress { 309 310 private final ProgressPanel panel; 311 private final ProgressHandle handle; 312 313 private Progress(ProgressPanel panel, ProgressHandle handle) { 314 this.panel = panel; 315 this.handle = handle; 316 } 317 318 public void switchToDeterminate(int workunits) { 319 handle.switchToDeterminate(workunits); 320 } 321 322 public void progress(final String message) { 323 Mutex.EVENT.readAccess(new Runnable () { 324 public void run() { 325 panel.setText(message); 326 } 327 }); 328 handle.progress(message); 329 } 330 331 public void progress(int workunit) { 332 handle.progress(workunit); 333 } 334 335 338 ProgressPanel getPanel() { 339 return panel; 340 } 341 } 342 343 347 public interface Action { 348 349 353 public boolean getRunInEventThread(); 354 355 363 public boolean isEnabled(); 364 365 368 public void run(Context actionContext); 369 } 370 371 public interface CancellableAction extends Action, Cancellable { 372 373 } 374 375 379 public static abstract class SynchronousAction implements Action { 380 381 public boolean getRunInEventThread() { 382 return true; 383 } 384 385 public boolean isEnabled() { 386 return true; 387 } 388 } 389 390 394 public static abstract class AsynchronousAction implements Action { 395 396 public boolean getRunInEventThread() { 397 return false; 398 } 399 400 public boolean isEnabled() { 401 return true; 402 } 403 } 404 } 405 | Popular Tags |