Source Code Cross Referenced for UpdateManager.java in  » Graphic-Library » batik » org » apache » batik » bridge » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Graphic Library » batik » org.apache.batik.bridge 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:
003:           Licensed to the Apache Software Foundation (ASF) under one or more
004:           contributor license agreements.  See the NOTICE file distributed with
005:           this work for additional information regarding copyright ownership.
006:           The ASF licenses this file to You under the Apache License, Version 2.0
007:           (the "License"); you may not use this file except in compliance with
008:           the License.  You may obtain a copy of the License at
009:
010:               http://www.apache.org/licenses/LICENSE-2.0
011:
012:           Unless required by applicable law or agreed to in writing, software
013:           distributed under the License is distributed on an "AS IS" BASIS,
014:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015:           See the License for the specific language governing permissions and
016:           limitations under the License.
017:
018:         */
019:        package org.apache.batik.bridge;
020:
021:        import java.awt.Shape;
022:        import java.awt.geom.AffineTransform;
023:        import java.util.Collection;
024:        import java.util.ArrayList;
025:        import java.util.Collections;
026:        import java.util.Iterator;
027:        import java.util.LinkedList;
028:        import java.util.List;
029:        import java.util.Timer;
030:        import java.util.TimerTask;
031:
032:        import org.apache.batik.bridge.svg12.DefaultXBLManager;
033:        import org.apache.batik.bridge.svg12.SVG12BridgeContext;
034:        import org.apache.batik.bridge.svg12.SVG12ScriptingEnvironment;
035:        import org.apache.batik.dom.events.AbstractEvent;
036:        import org.apache.batik.dom.svg.SVGOMDocument;
037:        import org.apache.batik.gvt.GraphicsNode;
038:        import org.apache.batik.gvt.RootGraphicsNode;
039:        import org.apache.batik.gvt.UpdateTracker;
040:        import org.apache.batik.gvt.renderer.ImageRenderer;
041:        import org.apache.batik.util.EventDispatcher;
042:        import org.apache.batik.util.XMLConstants;
043:        import org.apache.batik.util.EventDispatcher.Dispatcher;
044:        import org.apache.batik.util.RunnableQueue;
045:        import org.w3c.dom.Document;
046:        import org.w3c.dom.events.DocumentEvent;
047:        import org.w3c.dom.events.EventTarget;
048:
049:        /**
050:         * This class provides features to manage the update of an SVG document.
051:         *
052:         * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
053:         * @version $Id: UpdateManager.java 501843 2007-01-31 13:52:12Z deweese $
054:         */
055:        public class UpdateManager {
056:
057:            static final int MIN_REPAINT_TIME;
058:            static {
059:                int value = 20;
060:                try {
061:                    String s = System.getProperty(
062:                            "org.apache.batik.min_repaint_time", "20");
063:                    value = Integer.parseInt(s);
064:                } catch (SecurityException se) {
065:                } catch (NumberFormatException nfe) {
066:                } finally {
067:                    MIN_REPAINT_TIME = value;
068:                }
069:            }
070:
071:            /**
072:             * The bridge context.
073:             */
074:            protected BridgeContext bridgeContext;
075:
076:            /**
077:             * The document to manage.
078:             */
079:            protected Document document;
080:
081:            /**
082:             * The update RunnableQueue.
083:             */
084:            protected RunnableQueue updateRunnableQueue;
085:
086:            /**
087:             * The RunHandler for the RunnableQueue.
088:             */
089:            protected RunnableQueue.RunHandler runHandler;
090:
091:            /**
092:             * Whether the update manager is running.
093:             */
094:            protected volatile boolean running;
095:
096:            /**
097:             * Whether the suspend() method was called.
098:             */
099:            protected volatile boolean suspendCalled;
100:
101:            /**
102:             * The listeners.
103:             */
104:            protected List listeners = Collections
105:                    .synchronizedList(new LinkedList());
106:
107:            /**
108:             * The scripting environment.
109:             */
110:            protected ScriptingEnvironment scriptingEnvironment;
111:
112:            /**
113:             * The repaint manager.
114:             */
115:            protected RepaintManager repaintManager;
116:
117:            /**
118:             * The update tracker.
119:             */
120:            protected UpdateTracker updateTracker;
121:
122:            /**
123:             * The GraphicsNode whose updates are to be tracked.
124:             */
125:            protected GraphicsNode graphicsNode;
126:
127:            /**
128:             * Whether the manager was started.
129:             */
130:            protected boolean started;
131:
132:            /**
133:             * Array of resource documents' BridgeContexts.
134:             */
135:            protected BridgeContext[] secondaryBridgeContexts;
136:
137:            /**
138:             * Array of resource documents' ScriptingEnvironments that should
139:             * have their SVGLoad event dispatched.
140:             */
141:            protected ScriptingEnvironment[] secondaryScriptingEnvironments;
142:
143:            /**
144:             * The current minRepaintTime
145:             */
146:            protected int minRepaintTime;
147:
148:            /**
149:             * Creates a new update manager.
150:             * @param ctx The bridge context.
151:             * @param gn GraphicsNode whose updates are to be tracked.
152:             * @param doc The document to manage.
153:             */
154:            public UpdateManager(BridgeContext ctx, GraphicsNode gn,
155:                    Document doc) {
156:                bridgeContext = ctx;
157:                bridgeContext.setUpdateManager(this );
158:
159:                document = doc;
160:
161:                updateRunnableQueue = RunnableQueue.createRunnableQueue();
162:                runHandler = createRunHandler();
163:                updateRunnableQueue.setRunHandler(runHandler);
164:
165:                graphicsNode = gn;
166:
167:                scriptingEnvironment = initializeScriptingEnvironment(bridgeContext);
168:
169:                // Any BridgeContexts for resource documents that exist
170:                // when initializing the scripting environment for the
171:                // primary document also need to have their scripting
172:                // environments initialized.
173:                secondaryBridgeContexts = (BridgeContext[]) ctx
174:                        .getChildContexts().clone();
175:                secondaryScriptingEnvironments = new ScriptingEnvironment[secondaryBridgeContexts.length];
176:                for (int i = 0; i < secondaryBridgeContexts.length; i++) {
177:                    BridgeContext resCtx = secondaryBridgeContexts[i];
178:                    if (!((SVGOMDocument) resCtx.getDocument()).isSVG12()) {
179:                        continue;
180:                    }
181:                    resCtx.setUpdateManager(this );
182:                    ScriptingEnvironment se = initializeScriptingEnvironment(resCtx);
183:                    secondaryScriptingEnvironments[i] = se;
184:                }
185:                minRepaintTime = MIN_REPAINT_TIME;
186:            }
187:
188:            public int getMinRepaintTime() {
189:                return minRepaintTime;
190:            }
191:
192:            public void setMinRepaintTime(int minRepaintTime) {
193:                this .minRepaintTime = minRepaintTime;
194:            }
195:
196:            /**
197:             * Creates an appropriate ScriptingEnvironment and XBL manager for
198:             * the given document.
199:             */
200:            protected ScriptingEnvironment initializeScriptingEnvironment(
201:                    BridgeContext ctx) {
202:                SVGOMDocument d = (SVGOMDocument) ctx.getDocument();
203:                ScriptingEnvironment se;
204:                if (d.isSVG12()) {
205:                    se = new SVG12ScriptingEnvironment(ctx);
206:                    ctx.xblManager = new DefaultXBLManager(d, ctx);
207:                    d.setXBLManager(ctx.xblManager);
208:                } else {
209:                    se = new ScriptingEnvironment(ctx);
210:                }
211:                return se;
212:            }
213:
214:            /**
215:             * Dispatches an 'SVGLoad' event to the document.
216:             */
217:            public synchronized void dispatchSVGLoadEvent()
218:                    throws InterruptedException {
219:                dispatchSVGLoadEvent(bridgeContext, scriptingEnvironment);
220:                for (int i = 0; i < secondaryScriptingEnvironments.length; i++) {
221:                    BridgeContext ctx = secondaryBridgeContexts[i];
222:                    if (!((SVGOMDocument) ctx.getDocument()).isSVG12()) {
223:                        continue;
224:                    }
225:                    ScriptingEnvironment se = secondaryScriptingEnvironments[i];
226:                    dispatchSVGLoadEvent(ctx, se);
227:                }
228:                secondaryBridgeContexts = null;
229:                secondaryScriptingEnvironments = null;
230:            }
231:
232:            /**
233:             * Dispatches an 'SVGLoad' event to the document.
234:             */
235:            protected void dispatchSVGLoadEvent(BridgeContext ctx,
236:                    ScriptingEnvironment se) {
237:                se.loadScripts();
238:                se.dispatchSVGLoadEvent();
239:                if (ctx.isSVG12() && ctx.xblManager != null) {
240:                    SVG12BridgeContext ctx12 = (SVG12BridgeContext) ctx;
241:                    ctx12.addBindingListener();
242:                    ctx12.xblManager.startProcessing();
243:                }
244:            }
245:
246:            /**
247:             * Dispatches an "SVGZoom" event to the document.
248:             */
249:            public void dispatchSVGZoomEvent() throws InterruptedException {
250:                scriptingEnvironment.dispatchSVGZoomEvent();
251:            }
252:
253:            /**
254:             * Dispatches an "SVGZoom" event to the document.
255:             */
256:            public void dispatchSVGScrollEvent() throws InterruptedException {
257:                scriptingEnvironment.dispatchSVGScrollEvent();
258:            }
259:
260:            /**
261:             * Dispatches an "SVGZoom" event to the document.
262:             */
263:            public void dispatchSVGResizeEvent() throws InterruptedException {
264:                scriptingEnvironment.dispatchSVGResizeEvent();
265:            }
266:
267:            /**
268:             * Finishes the UpdateManager initialization.
269:             */
270:            public void manageUpdates(final ImageRenderer r) {
271:                updateRunnableQueue.preemptLater(new Runnable() {
272:                    public void run() {
273:                        synchronized (UpdateManager.this ) {
274:                            running = true;
275:
276:                            updateTracker = new UpdateTracker();
277:                            RootGraphicsNode root = graphicsNode.getRoot();
278:                            if (root != null) {
279:                                root
280:                                        .addTreeGraphicsNodeChangeListener(updateTracker);
281:                            }
282:
283:                            repaintManager = new RepaintManager(r);
284:
285:                            // Send the UpdateManagerStarted event.
286:                            UpdateManagerEvent ev = new UpdateManagerEvent(
287:                                    UpdateManager.this , null, null);
288:                            fireEvent(startedDispatcher, ev);
289:                            started = true;
290:                        }
291:                    }
292:                });
293:                resume();
294:            }
295:
296:            /**
297:             * Returns the bridge context.
298:             */
299:            public BridgeContext getBridgeContext() {
300:                return bridgeContext;
301:            }
302:
303:            /**
304:             * Returns the update RunnableQueue.
305:             */
306:            public RunnableQueue getUpdateRunnableQueue() {
307:                return updateRunnableQueue;
308:            }
309:
310:            /**
311:             * Returns the repaint manager.
312:             */
313:            public RepaintManager getRepaintManager() {
314:                return repaintManager;
315:            }
316:
317:            /**
318:             * Returns the GVT update tracker.
319:             */
320:            public UpdateTracker getUpdateTracker() {
321:                return updateTracker;
322:            }
323:
324:            /**
325:             * Returns the current Document.
326:             */
327:            public Document getDocument() {
328:                return document;
329:            }
330:
331:            /**
332:             * Returns the scripting environment.
333:             */
334:            public ScriptingEnvironment getScriptingEnvironment() {
335:                return scriptingEnvironment;
336:            }
337:
338:            /**
339:             * Tells whether the update manager is currently running.
340:             */
341:            public synchronized boolean isRunning() {
342:                return running;
343:            }
344:
345:            /**
346:             * Suspends the update manager.
347:             */
348:            public synchronized void suspend() {
349:                // System.err.println("Suspend: " + suspendCalled + " : " + running);
350:                if (updateRunnableQueue.getQueueState() == RunnableQueue.RUNNING) {
351:                    updateRunnableQueue.suspendExecution(false);
352:                }
353:                suspendCalled = true;
354:            }
355:
356:            /**
357:             * Resumes the update manager.
358:             */
359:            public synchronized void resume() {
360:                // System.err.println("Resume: " + suspendCalled + " : " + running);
361:
362:                // if (suspendCalled) {
363:                //     UpdateManagerEvent ev = new UpdateManagerEvent
364:                //         (this, null, null);
365:                //     // FIXX: Must happen in a different thread!
366:                //     fireEvent(suspendedDispatcher, ev);
367:                //     fireEvent(resumedDispatcher, ev);
368:                // }
369:                if (updateRunnableQueue.getQueueState() != RunnableQueue.RUNNING) {
370:                    updateRunnableQueue.resumeExecution();
371:                }
372:            }
373:
374:            /**
375:             * Interrupts the manager tasks.
376:             */
377:            public void interrupt() {
378:                Runnable r = new Runnable() {
379:                    public void run() {
380:                        synchronized (UpdateManager.this ) {
381:                            if (started) {
382:                                dispatchSVGUnLoadEvent();
383:                            } else {
384:                                running = false;
385:                                scriptingEnvironment.interrupt();
386:                                updateRunnableQueue.getThread().halt();
387:                            }
388:                        }
389:                    }
390:                };
391:                try {
392:                    // Preempt to cancel the pending tasks
393:                    updateRunnableQueue.preemptLater(r);
394:                    updateRunnableQueue.resumeExecution(); // ensure runnable runs...
395:                } catch (IllegalStateException ise) {
396:                    // Not running, which is probably ok since that's what we
397:                    // wanted.  Might be an issue if SVGUnload wasn't issued...
398:                }
399:            }
400:
401:            /**
402:             * Dispatches an 'SVGUnLoad' event to the document.
403:             * This method interrupts the update manager threads.
404:             * NOTE: this method must be called outside the update thread.
405:             */
406:            public void dispatchSVGUnLoadEvent() {
407:                if (!started) {
408:                    throw new IllegalStateException(
409:                            "UpdateManager not started.");
410:                }
411:
412:                // Invoke first to cancel the pending tasks
413:                updateRunnableQueue.preemptLater(new Runnable() {
414:                    public void run() {
415:                        synchronized (UpdateManager.this ) {
416:                            AbstractEvent evt = (AbstractEvent) ((DocumentEvent) document)
417:                                    .createEvent("SVGEvents");
418:                            String type;
419:                            if (bridgeContext.isSVG12()) {
420:                                type = "unload";
421:                            } else {
422:                                type = "SVGUnload";
423:                            }
424:                            evt.initEventNS(
425:                                    XMLConstants.XML_EVENTS_NAMESPACE_URI,
426:                                    type, false, // canBubbleArg
427:                                    false); // cancelableArg
428:                            ((EventTarget) (document.getDocumentElement()))
429:                                    .dispatchEvent(evt);
430:                            running = false;
431:
432:                            // Now shut everything down and disconnect
433:                            // everything before we send the
434:                            // UpdateMangerStopped event.
435:                            scriptingEnvironment.interrupt();
436:                            updateRunnableQueue.getThread().halt();
437:                            bridgeContext.dispose();
438:
439:                            // Send the UpdateManagerStopped event.
440:                            UpdateManagerEvent ev = new UpdateManagerEvent(
441:                                    UpdateManager.this , null, null);
442:                            fireEvent(stoppedDispatcher, ev);
443:                        }
444:                    }
445:                });
446:                resume();
447:            }
448:
449:            /**
450:             * Updates the rendering buffer.  Only to be called from the
451:             * update thread.
452:             * @param u2d The user to device transform.
453:             * @param dbr Whether the double buffering should be used.
454:             * @param aoi The area of interest in the renderer space units.
455:             * @param width The offscreen buffer width.
456:             * @param height The offscreen buffer height.
457:             */
458:            public void updateRendering(AffineTransform u2d, boolean dbr,
459:                    Shape aoi, int width, int height) {
460:                repaintManager.setupRenderer(u2d, dbr, aoi, width, height);
461:                List l = new ArrayList(1);
462:                l.add(aoi);
463:                updateRendering(l, false);
464:            }
465:
466:            /**
467:             * Updates the rendering buffer.  Only to be called from the
468:             * update thread.
469:             * @param u2d The user to device transform.
470:             * @param dbr Whether the double buffering should be used.
471:             * @param cpt If the canvas painting transform should be cleared
472:             *            when the update complets
473:             * @param aoi The area of interest in the renderer space units.
474:             * @param width The offscreen buffer width.
475:             * @param height The offscreen buffer height.
476:             */
477:            public void updateRendering(AffineTransform u2d, boolean dbr,
478:                    boolean cpt, Shape aoi, int width, int height) {
479:                repaintManager.setupRenderer(u2d, dbr, aoi, width, height);
480:                List l = new ArrayList(1);
481:                l.add(aoi);
482:                updateRendering(l, cpt);
483:            }
484:
485:            /**
486:             * Updates the rendering buffer.
487:             * @param areas List of areas of interest in rederer space units.
488:             * @param clearPaintingTransform Indicates if the painting transform
489:             *        should be cleared as a result of this update.
490:             */
491:            protected void updateRendering(List areas,
492:                    boolean clearPaintingTransform) {
493:                try {
494:                    UpdateManagerEvent ev = new UpdateManagerEvent(this ,
495:                            repaintManager.getOffScreen(), null);
496:                    fireEvent(updateStartedDispatcher, ev);
497:
498:                    Collection c = repaintManager.updateRendering(areas);
499:                    List l = new ArrayList(c);
500:
501:                    ev = new UpdateManagerEvent(this , repaintManager
502:                            .getOffScreen(), l, clearPaintingTransform);
503:                    fireEvent(updateCompletedDispatcher, ev);
504:                } catch (ThreadDeath td) {
505:                    UpdateManagerEvent ev = new UpdateManagerEvent(this , null,
506:                            null);
507:                    fireEvent(updateFailedDispatcher, ev);
508:                    throw td;
509:                } catch (Throwable t) {
510:                    UpdateManagerEvent ev = new UpdateManagerEvent(this , null,
511:                            null);
512:                    fireEvent(updateFailedDispatcher, ev);
513:                }
514:            }
515:
516:            /**
517:             * This tracks when the rendering first got 'out of date'
518:             * with respect to the document.
519:             */
520:            long outOfDateTime = 0;
521:
522:            /**
523:             * Repaints the dirty areas, if needed.
524:             */
525:            protected void repaint() {
526:                if (!updateTracker.hasChanged()) {
527:                    // No changes, nothing to repaint.
528:                    outOfDateTime = 0;
529:                    return;
530:                }
531:
532:                long ctime = System.currentTimeMillis();
533:                if (ctime < allResumeTime) {
534:                    createRepaintTimer();
535:                    return;
536:                }
537:                if (allResumeTime > 0) {
538:                    // All suspendRedraw requests have expired.
539:                    releaseAllRedrawSuspension();
540:                }
541:
542:                if (ctime - outOfDateTime < minRepaintTime) {
543:                    // We very recently did a repaint check if other
544:                    // repaint runnables are pending.
545:                    synchronized (updateRunnableQueue.getIteratorLock()) {
546:                        Iterator i = updateRunnableQueue.iterator();
547:                        while (i.hasNext())
548:                            if (!(i.next() instanceof  NoRepaintRunnable))
549:                                // have a pending repaint runnable so we
550:                                // will skip this repaint and we will let
551:                                // the next one pick it up.
552:                                return;
553:
554:                    }
555:                }
556:
557:                List dirtyAreas = updateTracker.getDirtyAreas();
558:                updateTracker.clear();
559:                if (dirtyAreas != null) {
560:                    updateRendering(dirtyAreas, false);
561:                }
562:                outOfDateTime = 0;
563:            }
564:
565:            /**
566:             * Users of Batik should essentially never call
567:             * this directly from Java.  If the Canvas is not
568:             * updating when you change the SVG Document it is almost
569:             * certainly because you are not making your changes
570:             * in the RunnableQueue (getUpdateRunnableQueue()).
571:             * You will have problems if you are not making all
572:             * changes to the document in the UpdateManager's
573:             * RunnableQueue.
574:             *
575:             * This method exists to implement the
576:             * 'SVGSVGElement.forceRedraw()' method.
577:             */
578:            public void forceRepaint() {
579:                if (!updateTracker.hasChanged()) {
580:                    // No changes, nothing to repaint.
581:                    outOfDateTime = 0;
582:                    return;
583:                }
584:
585:                List dirtyAreas = updateTracker.getDirtyAreas();
586:                updateTracker.clear();
587:                if (dirtyAreas != null) {
588:                    updateRendering(dirtyAreas, false);
589:                }
590:                outOfDateTime = 0;
591:            }
592:
593:            protected class SuspensionInfo {
594:                /**
595:                 * The index of this redraw suspension
596:                 */
597:                int index;
598:                /**
599:                 * The system time in millisec that this suspension
600:                 * will expire and redraws can resume (at least for
601:                 * this suspension.
602:                 */
603:                long resumeMilli;
604:
605:                public SuspensionInfo(int index, long resumeMilli) {
606:                    this .index = index;
607:                    this .resumeMilli = resumeMilli;
608:                }
609:
610:                public int getIndex() {
611:                    return index;
612:                }
613:
614:                public long getResumeMilli() {
615:                    return resumeMilli;
616:                }
617:            }
618:
619:            protected class RepaintTimerTask extends TimerTask {
620:                UpdateManager um;
621:
622:                RepaintTimerTask(UpdateManager um) {
623:                    this .um = um;
624:                }
625:
626:                public void run() {
627:                    RunnableQueue rq = um.getUpdateRunnableQueue();
628:                    if (rq == null)
629:                        return;
630:                    rq.invokeLater(new Runnable() {
631:                        public void run() {
632:                        }
633:                    });
634:                }
635:            }
636:
637:            List suspensionList = new ArrayList();
638:            int nextSuspensionIndex = 1;
639:            long allResumeTime = -1;
640:            Timer repaintTriggerTimer = null;
641:            TimerTask repaintTimerTask = null;
642:
643:            void createRepaintTimer() {
644:                if (repaintTimerTask != null)
645:                    return;
646:                if (allResumeTime < 0)
647:                    return;
648:                if (repaintTriggerTimer == null)
649:                    repaintTriggerTimer = new Timer(true);
650:
651:                long delay = allResumeTime - System.currentTimeMillis();
652:                if (delay < 0)
653:                    delay = 0;
654:                repaintTimerTask = new RepaintTimerTask(this );
655:                repaintTriggerTimer.schedule(repaintTimerTask, delay);
656:                // System.err.println("CTimer delay: " + delay);
657:            }
658:
659:            /**
660:             * Sets up a timer that will trigger a repaint
661:             * when it fires.
662:             * If create is true it will construct a timer even
663:             * if one
664:             */
665:            void resetRepaintTimer() {
666:                if (repaintTimerTask == null)
667:                    return;
668:                if (allResumeTime < 0)
669:                    return;
670:                if (repaintTriggerTimer == null)
671:                    repaintTriggerTimer = new Timer(true);
672:
673:                long delay = allResumeTime - System.currentTimeMillis();
674:                if (delay < 0)
675:                    delay = 0;
676:                repaintTimerTask = new RepaintTimerTask(this );
677:                repaintTriggerTimer.schedule(repaintTimerTask, delay);
678:                // System.err.println("Timer delay: " + delay);
679:            }
680:
681:            int addRedrawSuspension(int max_wait_milliseconds) {
682:                long resumeTime = System.currentTimeMillis()
683:                        + max_wait_milliseconds;
684:                SuspensionInfo si = new SuspensionInfo(nextSuspensionIndex++,
685:                        resumeTime);
686:                if (resumeTime > allResumeTime) {
687:                    allResumeTime = resumeTime;
688:                    // System.err.println("Added AllRes Time: " + allResumeTime);
689:                    resetRepaintTimer();
690:                }
691:                suspensionList.add(si);
692:                return si.getIndex();
693:            }
694:
695:            void releaseAllRedrawSuspension() {
696:                suspensionList.clear();
697:                allResumeTime = -1;
698:                resetRepaintTimer();
699:            }
700:
701:            boolean releaseRedrawSuspension(int index) {
702:                if (index > nextSuspensionIndex)
703:                    return false;
704:                if (suspensionList.size() == 0)
705:                    return true;
706:
707:                int lo = 0, hi = suspensionList.size() - 1;
708:                while (lo < hi) {
709:                    int mid = (lo + hi) >> 1;
710:                    SuspensionInfo si = (SuspensionInfo) suspensionList
711:                            .get(mid);
712:                    int idx = si.getIndex();
713:                    if (idx == index) {
714:                        lo = hi = mid;
715:                    } else if (idx < index) {
716:                        lo = mid + 1;
717:                    } else {
718:                        hi = mid - 1;
719:                    }
720:                }
721:
722:                SuspensionInfo si = (SuspensionInfo) suspensionList.get(lo);
723:                int idx = si.getIndex();
724:                if (idx != index)
725:                    return true; // currently not in list but was at some point...
726:
727:                suspensionList.remove(lo);
728:                if (suspensionList.size() == 0) {
729:                    // No more active suspensions
730:                    allResumeTime = -1;
731:                    resetRepaintTimer();
732:                } else {
733:                    // Check if we need to find a new 'bounding' suspension.
734:                    long resumeTime = si.getResumeMilli();
735:                    if (resumeTime == allResumeTime) {
736:                        allResumeTime = findNewAllResumeTime();
737:                        // System.err.println("New AllRes Time: " + allResumeTime);
738:                        resetRepaintTimer();
739:                    }
740:                }
741:                return true;
742:            }
743:
744:            long findNewAllResumeTime() {
745:                long ret = -1;
746:                Iterator i = suspensionList.iterator();
747:                while (i.hasNext()) {
748:                    SuspensionInfo si = (SuspensionInfo) i.next();
749:                    long t = si.getResumeMilli();
750:                    if (t > ret)
751:                        ret = t;
752:                }
753:                return ret;
754:            }
755:
756:            /**
757:             * Adds a UpdateManagerListener to this UpdateManager.
758:             */
759:            public void addUpdateManagerListener(UpdateManagerListener l) {
760:                listeners.add(l);
761:            }
762:
763:            /**
764:             * Removes a UpdateManagerListener from this UpdateManager.
765:             */
766:            public void removeUpdateManagerListener(UpdateManagerListener l) {
767:                listeners.remove(l);
768:            }
769:
770:            protected void fireEvent(Dispatcher dispatcher, Object event) {
771:                EventDispatcher.fireEvent(dispatcher, listeners, event, false);
772:            }
773:
774:            /**
775:             * Dispatches a UpdateManagerEvent to notify that the manager was
776:             * started
777:             */
778:            static Dispatcher startedDispatcher = new Dispatcher() {
779:                public void dispatch(Object listener, Object event) {
780:                    ((UpdateManagerListener) listener)
781:                            .managerStarted((UpdateManagerEvent) event);
782:                }
783:            };
784:
785:            /**
786:             * Dispatches a UpdateManagerEvent to notify that the manager was
787:             * stopped.
788:             */
789:            static Dispatcher stoppedDispatcher = new Dispatcher() {
790:                public void dispatch(Object listener, Object event) {
791:                    ((UpdateManagerListener) listener)
792:                            .managerStopped((UpdateManagerEvent) event);
793:                }
794:            };
795:
796:            /**
797:             * Dispatches a UpdateManagerEvent to notify that the manager was
798:             * suspended.
799:             */
800:            static Dispatcher suspendedDispatcher = new Dispatcher() {
801:                public void dispatch(Object listener, Object event) {
802:                    ((UpdateManagerListener) listener)
803:                            .managerSuspended((UpdateManagerEvent) event);
804:                }
805:            };
806:
807:            /**
808:             * Dispatches a UpdateManagerEvent to notify that the manager was
809:             * resumed.
810:             */
811:            static Dispatcher resumedDispatcher = new Dispatcher() {
812:                public void dispatch(Object listener, Object event) {
813:                    ((UpdateManagerListener) listener)
814:                            .managerResumed((UpdateManagerEvent) event);
815:                }
816:            };
817:
818:            /**
819:             * Dispatches a UpdateManagerEvent to notify that an update
820:             * started
821:             */
822:            static Dispatcher updateStartedDispatcher = new Dispatcher() {
823:                public void dispatch(Object listener, Object event) {
824:                    ((UpdateManagerListener) listener)
825:                            .updateStarted((UpdateManagerEvent) event);
826:                }
827:            };
828:
829:            /**
830:             * Dispatches a UpdateManagerEvent to notify that an update
831:             * completed
832:             */
833:            static Dispatcher updateCompletedDispatcher = new Dispatcher() {
834:                public void dispatch(Object listener, Object event) {
835:                    ((UpdateManagerListener) listener)
836:                            .updateCompleted((UpdateManagerEvent) event);
837:                }
838:            };
839:
840:            /**
841:             * Dispatches a UpdateManagerEvent to notify that an update
842:             * failed
843:             */
844:            static Dispatcher updateFailedDispatcher = new Dispatcher() {
845:                public void dispatch(Object listener, Object event) {
846:                    ((UpdateManagerListener) listener)
847:                            .updateFailed((UpdateManagerEvent) event);
848:                }
849:            };
850:
851:            // RunnableQueue.RunHandler /////////////////////////////////////////
852:            protected RunnableQueue.RunHandler createRunHandler() {
853:                return new UpdateManagerRunHander();
854:            }
855:
856:            protected class UpdateManagerRunHander extends
857:                    RunnableQueue.RunHandlerAdapter {
858:
859:                public void runnableStart(RunnableQueue rq, Runnable r) {
860:                    if (running && !(r instanceof  NoRepaintRunnable)) {
861:                        // Mark the document as updated when the
862:                        // runnable starts.
863:                        if (outOfDateTime == 0)
864:                            outOfDateTime = System.currentTimeMillis();
865:                    }
866:                }
867:
868:                /**
869:                 * Called when the given Runnable has just been invoked and
870:                 * has returned.
871:                 */
872:                public void runnableInvoked(RunnableQueue rq, Runnable r) {
873:                    if (running && !(r instanceof  NoRepaintRunnable)) {
874:                        repaint();
875:                    }
876:                }
877:
878:                /**
879:                 * Called when the execution of the queue has been suspended.
880:                 */
881:                public void executionSuspended(RunnableQueue rq) {
882:                    synchronized (UpdateManager.this ) {
883:                        // System.err.println("Suspended: " + suspendCalled);
884:                        if (suspendCalled) {
885:                            running = false;
886:                            UpdateManagerEvent ev = new UpdateManagerEvent(
887:                                    this , null, null);
888:                            fireEvent(suspendedDispatcher, ev);
889:                        }
890:                    }
891:                }
892:
893:                /**
894:                 * Called when the execution of the queue has been resumed.
895:                 */
896:                public void executionResumed(RunnableQueue rq) {
897:                    synchronized (UpdateManager.this ) {
898:                        // System.err.println("Resumed: " + suspendCalled +
899:                        //                    " : " + running);
900:                        if (suspendCalled && !running) {
901:                            running = true;
902:                            suspendCalled = false;
903:
904:                            UpdateManagerEvent ev = new UpdateManagerEvent(
905:                                    this, null, null);
906:                            fireEvent(resumedDispatcher, ev);
907:                        }
908:                    }
909:                }
910:            }
911:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.