1 18 package org.apache.batik.bridge; 19 20 import java.awt.Shape ; 21 import java.awt.geom.AffineTransform ; 22 import java.util.Collection ; 23 import java.util.ArrayList ; 24 import java.util.Collections ; 25 import java.util.Iterator ; 26 import java.util.LinkedList ; 27 import java.util.List ; 28 29 import org.apache.batik.gvt.GraphicsNode; 30 import org.apache.batik.gvt.RootGraphicsNode; 31 import org.apache.batik.gvt.UpdateTracker; 32 import org.apache.batik.gvt.renderer.ImageRenderer; 33 import org.apache.batik.util.EventDispatcher; 34 import org.apache.batik.util.EventDispatcher.Dispatcher; 35 import org.apache.batik.util.RunnableQueue; 36 import org.w3c.dom.Document ; 37 import org.w3c.dom.events.DocumentEvent ; 38 import org.w3c.dom.events.Event ; 39 import org.w3c.dom.events.EventTarget ; 40 41 47 public class UpdateManager { 48 49 static final long MIN_REPAINT_TIME; 50 static { 51 long value = 20; 52 try { 53 String s = System.getProperty 54 ("org.apache.batik.min_repaint_time", "20"); 55 value = Long.parseLong(s); 56 } catch (SecurityException se) { 57 } catch (NumberFormatException nfe){ 58 } finally { 59 MIN_REPAINT_TIME = value; 60 } 61 } 62 63 66 protected BridgeContext bridgeContext; 67 68 71 protected Document document; 72 73 76 protected RunnableQueue updateRunnableQueue; 77 78 81 protected RunnableQueue.RunHandler runHandler; 82 83 86 protected boolean running; 87 88 91 protected boolean suspendCalled; 92 93 96 protected List listeners = Collections.synchronizedList(new LinkedList ()); 97 98 101 protected ScriptingEnvironment scriptingEnvironment; 102 103 106 protected RepaintManager repaintManager; 107 108 111 protected UpdateTracker updateTracker; 112 113 116 protected GraphicsNode graphicsNode; 117 118 121 protected boolean started; 122 123 129 public UpdateManager(BridgeContext ctx, 130 GraphicsNode gn, 131 Document doc) { 132 bridgeContext = ctx; 133 bridgeContext.setUpdateManager(this); 134 135 document = doc; 136 137 updateRunnableQueue = RunnableQueue.createRunnableQueue(); 138 runHandler = createRunHandler(); 139 updateRunnableQueue.setRunHandler(runHandler); 140 141 graphicsNode = gn; 142 143 scriptingEnvironment = new ScriptingEnvironment(ctx); 144 } 145 146 149 public synchronized void dispatchSVGLoadEvent() 150 throws InterruptedException { 151 scriptingEnvironment.loadScripts(); 152 scriptingEnvironment.dispatchSVGLoadEvent(); 153 } 154 155 158 public void dispatchSVGZoomEvent() 159 throws InterruptedException { 160 scriptingEnvironment.dispatchSVGZoomEvent(); 161 } 162 163 166 public void dispatchSVGScrollEvent() 167 throws InterruptedException { 168 scriptingEnvironment.dispatchSVGScrollEvent(); 169 } 170 171 174 public void dispatchSVGResizeEvent() 175 throws InterruptedException { 176 scriptingEnvironment.dispatchSVGResizeEvent(); 177 } 178 179 182 public void manageUpdates(final ImageRenderer r) { 183 updateRunnableQueue.preemptLater(new Runnable () { 184 public void run() { 185 synchronized (UpdateManager.this) { 186 running = true; 187 188 updateTracker = new UpdateTracker(); 189 RootGraphicsNode root = graphicsNode.getRoot(); 190 if (root != null){ 191 root.addTreeGraphicsNodeChangeListener 192 (updateTracker); 193 } 194 195 repaintManager = new RepaintManager(r); 196 197 UpdateManagerEvent ev = new UpdateManagerEvent 199 (UpdateManager.this, null, null); 200 fireEvent(startedDispatcher, ev); 201 started = true; 202 } 203 } 204 }); 205 resume(); 206 } 207 208 209 212 public BridgeContext getBridgeContext() { 213 return bridgeContext; 214 } 215 216 219 public RunnableQueue getUpdateRunnableQueue() { 220 return updateRunnableQueue; 221 } 222 223 226 public RepaintManager getRepaintManager() { 227 return repaintManager; 228 } 229 230 233 public UpdateTracker getUpdateTracker() { 234 return updateTracker; 235 } 236 237 240 public Document getDocument() { 241 return document; 242 } 243 244 247 public ScriptingEnvironment getScriptingEnvironment() { 248 return scriptingEnvironment; 249 } 250 251 254 public synchronized boolean isRunning() { 255 return running; 256 } 257 258 261 public synchronized void suspend() { 262 if (updateRunnableQueue.getQueueState() == RunnableQueue.RUNNING) { 264 updateRunnableQueue.suspendExecution(false); 265 } 266 suspendCalled = true; 267 } 268 269 272 public synchronized void resume() { 273 275 if (updateRunnableQueue.getQueueState() != RunnableQueue.RUNNING) { 283 updateRunnableQueue.resumeExecution(); 284 } 285 } 286 287 290 public synchronized void interrupt() { 291 if (updateRunnableQueue.getThread() == null) 292 return; 293 294 updateRunnableQueue.preemptLater(new Runnable () { 296 public void run() { 297 synchronized (UpdateManager.this) { 298 if (started) { 299 dispatchSVGUnLoadEvent(); 300 } else { 301 running = false; 302 scriptingEnvironment.interrupt(); 303 updateRunnableQueue.getThread().halt(); 304 } 305 } 306 } 307 }); 308 resume(); 309 } 310 311 316 public void dispatchSVGUnLoadEvent() { 317 if (!started) { 318 throw new IllegalStateException ("UpdateManager not started."); 319 } 320 321 updateRunnableQueue.preemptLater(new Runnable () { 323 public void run() { 324 synchronized (UpdateManager.this) { 325 Event evt = 326 ((DocumentEvent )document).createEvent("SVGEvents"); 327 evt.initEvent("SVGUnload", false, false); 328 ((EventTarget )(document.getDocumentElement())). 329 dispatchEvent(evt); 330 running = false; 331 332 scriptingEnvironment.interrupt(); 336 updateRunnableQueue.getThread().halt(); 337 bridgeContext.dispose(); 338 339 UpdateManagerEvent ev = new UpdateManagerEvent 341 (UpdateManager.this, null, null); 342 fireEvent(stoppedDispatcher, ev); 343 } 344 } 345 }); 346 resume(); 347 } 348 349 358 public void updateRendering(AffineTransform u2d, 359 boolean dbr, 360 Shape aoi, 361 int width, 362 int height) { 363 repaintManager.setupRenderer(u2d,dbr,aoi,width,height); 364 List l = new ArrayList (1); 365 l.add(aoi); 366 updateRendering(l, false); 367 } 368 369 380 public void updateRendering(AffineTransform u2d, 381 boolean dbr, 382 boolean cpt, 383 Shape aoi, 384 int width, 385 int height) { 386 repaintManager.setupRenderer(u2d,dbr,aoi,width,height); 387 List l = new ArrayList (1); 388 l.add(aoi); 389 updateRendering(l, cpt); 390 } 391 392 398 protected void updateRendering(List areas, 399 boolean clearPaintingTransform) { 400 try { 401 UpdateManagerEvent ev = new UpdateManagerEvent 402 (this, repaintManager.getOffScreen(), null); 403 fireEvent(updateStartedDispatcher, ev); 404 405 Collection c = repaintManager.updateRendering(areas); 406 List l = new ArrayList (c); 407 408 ev = new UpdateManagerEvent 409 (this, repaintManager.getOffScreen(), 410 l, clearPaintingTransform); 411 fireEvent(updateCompletedDispatcher, ev); 412 } catch (ThreadDeath td) { 413 UpdateManagerEvent ev = new UpdateManagerEvent 414 (this, null, null); 415 fireEvent(updateFailedDispatcher, ev); 416 throw td; 417 } catch (Throwable t) { 418 UpdateManagerEvent ev = new UpdateManagerEvent 419 (this, null, null); 420 fireEvent(updateFailedDispatcher, ev); 421 } 422 } 423 424 428 long outOfDateTime=0; 429 430 433 protected void repaint() { 434 if (!updateTracker.hasChanged()) 435 return; 436 long ctime = System.currentTimeMillis(); 437 if (ctime-outOfDateTime < MIN_REPAINT_TIME) { 438 synchronized (updateRunnableQueue.getIteratorLock()) { 441 Iterator i = updateRunnableQueue.iterator(); 442 while (i.hasNext()) 443 if (!(i.next() instanceof NoRepaintRunnable)) 444 return; 448 449 } 450 } 451 452 List dirtyAreas = updateTracker.getDirtyAreas(); 453 updateTracker.clear(); 454 if (dirtyAreas != null) { 455 updateRendering(dirtyAreas, false); 456 } 457 outOfDateTime = 0; 458 } 459 460 461 464 public void addUpdateManagerListener(UpdateManagerListener l) { 465 listeners.add(l); 466 } 467 468 471 public void removeUpdateManagerListener(UpdateManagerListener l) { 472 listeners.remove(l); 473 } 474 475 protected void fireEvent(Dispatcher dispatcher, Object event) { 476 EventDispatcher.fireEvent(dispatcher, listeners, event, false); 477 } 478 479 480 484 static Dispatcher startedDispatcher = new Dispatcher() { 485 public void dispatch(Object listener, 486 Object event) { 487 ((UpdateManagerListener)listener).managerStarted 488 ((UpdateManagerEvent)event); 489 } 490 }; 491 492 496 static Dispatcher stoppedDispatcher = new Dispatcher() { 497 public void dispatch(Object listener, 498 Object event) { 499 ((UpdateManagerListener)listener).managerStopped 500 ((UpdateManagerEvent)event); 501 } 502 }; 503 504 508 static Dispatcher suspendedDispatcher = new Dispatcher() { 509 public void dispatch(Object listener, 510 Object event) { 511 ((UpdateManagerListener)listener).managerSuspended 512 ((UpdateManagerEvent)event); 513 } 514 }; 515 516 520 static Dispatcher resumedDispatcher = new Dispatcher() { 521 public void dispatch(Object listener, 522 Object event) { 523 ((UpdateManagerListener)listener).managerResumed 524 ((UpdateManagerEvent)event); 525 } 526 }; 527 528 532 static Dispatcher updateStartedDispatcher = new Dispatcher() { 533 public void dispatch(Object listener, 534 Object event) { 535 ((UpdateManagerListener)listener).updateStarted 536 ((UpdateManagerEvent)event); 537 } 538 }; 539 540 544 static Dispatcher updateCompletedDispatcher = new Dispatcher() { 545 public void dispatch(Object listener, 546 Object event) { 547 ((UpdateManagerListener)listener).updateCompleted 548 ((UpdateManagerEvent)event); 549 } 550 }; 551 552 556 static Dispatcher updateFailedDispatcher = new Dispatcher() { 557 public void dispatch(Object listener, 558 Object event) { 559 ((UpdateManagerListener)listener).updateFailed 560 ((UpdateManagerEvent)event); 561 } 562 }; 563 564 565 566 protected RunnableQueue.RunHandler createRunHandler() { 568 return new UpdateManagerRunHander(); 569 } 570 571 protected class UpdateManagerRunHander 572 extends RunnableQueue.RunHandlerAdapter { 573 574 public void runnableStart(RunnableQueue rq, Runnable r) { 575 if (running && !(r instanceof NoRepaintRunnable)) { 576 if (outOfDateTime == 0) 579 outOfDateTime = System.currentTimeMillis(); 580 } 581 } 582 583 584 588 public void runnableInvoked(RunnableQueue rq, Runnable r) { 589 if (running && !(r instanceof NoRepaintRunnable)) { 590 repaint(); 591 } 592 } 593 594 597 public void executionSuspended(RunnableQueue rq) { 598 synchronized (UpdateManager.this) { 599 if (suspendCalled) { 601 running = false; 602 UpdateManagerEvent ev = new UpdateManagerEvent 603 (this, null, null); 604 fireEvent(suspendedDispatcher, ev); 605 } 606 } 607 } 608 609 612 public void executionResumed(RunnableQueue rq) { 613 synchronized (UpdateManager.this) { 614 if (suspendCalled && !running) { 617 running = true; 618 suspendCalled = false; 619 620 UpdateManagerEvent ev = new UpdateManagerEvent 621 (this, null, null); 622 fireEvent(resumedDispatcher, ev); 623 } 624 } 625 } 626 } 627 } 628 | Popular Tags |