Source Code Cross Referenced for CanvasManager.java in  » 6.0-JDK-Modules » j2me » com » sun » perseus » model » 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 » 6.0 JDK Modules » j2me » com.sun.perseus.model 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *
003:         *
004:         * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006:         * 
007:         * This program is free software; you can redistribute it and/or
008:         * modify it under the terms of the GNU General Public License version
009:         * 2 only, as published by the Free Software Foundation.
010:         * 
011:         * This program is distributed in the hope that it will be useful, but
012:         * WITHOUT ANY WARRANTY; without even the implied warranty of
013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014:         * General Public License version 2 for more details (a copy is
015:         * included at /legal/license.txt).
016:         * 
017:         * You should have received a copy of the GNU General Public License
018:         * version 2 along with this work; if not, write to the Free Software
019:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020:         * 02110-1301 USA
021:         * 
022:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023:         * Clara, CA 95054 or visit www.sun.com if you need additional
024:         * information or have any questions.
025:         */
026:
027:        package com.sun.perseus.model;
028:
029:        import com.sun.perseus.j2d.RenderContext;
030:        import com.sun.perseus.j2d.RenderGraphics;
031:
032:        import java.io.InputStream;
033:
034:        import com.sun.perseus.util.RunnableQueue;
035:        import com.sun.perseus.util.RunnableQueue.RunnableHandler;
036:
037:        import com.sun.perseus.j2d.RGB;
038:        import com.sun.perseus.j2d.Transform;
039:
040:        /**
041:         * <p>The <code>CanvasManager</code> class is responsible for
042:         * keeping the rendering of a <code>ModelNode</code> tree on a 
043:         * <code>RenderGraphics</code> current.</p>
044:         * 
045:         * <p>Specifically, the <code>CanvasManager</code> listens to 
046:         * update events in a <code>ModelNode</code> tree and 
047:         * triggers repaint into the <code>RenderGraphics</code> when
048:         * necessary.</p>
049:         * 
050:         * <p>The <code>CanvasManager</code> optimizes rendering
051:         * of the tree while the document is in loading phase.</p>
052:         *
053:         * @version $Id: CanvasManager.java,v 1.17 2006/07/13 00:55:57 st125089 Exp $
054:         */
055:        public class CanvasManager extends SimpleCanvasManager {
056:            /**
057:             * True while the component is processing a document 
058:             * which is in the loading phase, i.e., between
059:             * the <code>UpdateListener</code>'s <code>loadStarting</code>
060:             * and <code>loadComplete</code> calls.
061:             */
062:            protected boolean loading;
063:
064:            /**
065:             * Progressive painting is needed when a node has
066:             * started loading and has been inserted into the tree.
067:             * This is only used during the loading phase of 
068:             * a document when doing progressive rendering.
069:             * The next node to paint progressively
070:             */
071:            protected ModelNode progressiveNode = null;
072:
073:            /**
074:             * Tracks the highest level node whose load completion
075:             * is needed to proceed with progressive rendering.
076:             * When loading this node completes, then the node
077:             * is painted.
078:             */
079:            protected ModelNode needLoadNode = null;
080:
081:            /**
082:             * The associated SMILSampler, if animations are run.
083:             */
084:            protected SMILSample sampler = null;
085:
086:            /**
087:             * The rate for SMIL animation. The smilRate is the minimum time between
088:             * SMIL samples.
089:             */
090:            protected long smilRate = 40;
091:
092:            /**
093:             * @param rg the <code>RenderGraphics</code> which this 
094:             *        instance will keep up to date with the 
095:             *        model changes.
096:             * @param documentNode the <code>DocumentNode</code>, root of the 
097:             *        tree that this <code>CanvasManager</code> will
098:             *        draw and keep current on the <code>RenderGraphics</code>
099:             * @param canvasUpdateListener the <code>CanvasUpdateListener</code>
100:             *        which listens to completed updates on the associated
101:             *        <code>RenderGraphics</code>
102:             *
103:             * @throws IllegalArgumentException if rg, documentNode or listener is null.
104:             */
105:            public CanvasManager(final RenderGraphics rg,
106:                    final DocumentNode documentNode,
107:                    final CanvasUpdateListener canvasUpdateListener) {
108:                super (rg, documentNode, canvasUpdateListener);
109:            }
110:
111:            /**
112:             * Invoked when a node has been inserted into the tree
113:             *
114:             * @param node the newly inserted node
115:             */
116:            public void nodeInserted(final ModelNode node) {
117:                if (loading) {
118:                    if (needLoadNode == null) {
119:                        // Progressive rendering is _not_ suspended
120:
121:                        // If this node's parent is already loaded,
122:                        // it means we are dealing with a node insertion
123:                        // resulting from reference resolution. We need
124:                        // to repaint the document in its current state.
125:                        if (node.parent.loaded) {
126:                            fullPaint();
127:                        } else {
128:                            // Check if this node suspends progressive
129:                            // rendering.
130:                            if (!node.getPaintNeedsLoad()) {
131:                                if (progressiveNode != null) {
132:                                    needRepaint = true;
133:                                } else {
134:                                    progressiveNode = node;
135:                                }
136:                            } else {
137:                                needLoadNode = node;
138:                            }
139:                        }
140:                    } else {
141:                        // Progressive rendering _is_ suspended
142:
143:                        // We are loading a document and progressive 
144:                        // repaint is disabled. However, the newly 
145:                        // inserted node might be a ElementNodeProxy
146:                        // child of a Use element which is referencing
147:                        // content under the current needLoadNode. 
148:                        // In that situation, we need to do a repaint
149:                        // of the document up to, but not including
150:                        // the needLoadNode.
151:                        ModelNode parent = node;
152:                        while (parent != null) {
153:                            if (parent == needLoadNode) {
154:                                // We are under the disabled node, no
155:                                // problem
156:                                break;
157:                            }
158:                            parent = parent.parent;
159:                        }
160:                        if (parent == null) {
161:                            // Re-render the document up to the current
162:                            // needLoadNode
163:                            needRepaint = true;
164:                        }
165:                    }
166:                } else {
167:                    needRepaint = true;
168:                }
169:            }
170:
171:            /**
172:             * @param node the node to test.
173:             * @return true if <code>node</code> is
174:             * a chid of the node currently holding up progressive
175:             * rendering. The caller must make sure <code>needNodeLoad</code>
176:             * is not null before calling this utility method. If called
177:             * when <code>needLoadNode</code> is null, the method returns 
178:             * true.
179:             */
180:            boolean isNeedLoadNodeOrChild(final ModelNode node) {
181:                ModelNode parent = node;
182:
183:                while (parent != null) {
184:                    if (parent == needLoadNode) {
185:                        break;
186:                    }
187:                    parent = parent.parent;
188:                }
189:
190:                if (parent == null) {
191:                    return false;
192:                }
193:
194:                return true;
195:            }
196:
197:            /**
198:             * Invoked when a node is about to be modified. 
199:             *
200:             * @param node the node which is about to be modified
201:             */
202:            public void modifyingNode(final ModelNode node) {
203:                if (!isNeedLoadNodeOrChild(node)
204:                        && ((node.hasNodeRendering() || node.hasDescendants()) && (node.canRenderState == 0))) {
205:                    needRepaint = true;
206:                }
207:            }
208:
209:            /**
210:             * Invoked when a node modification completed.
211:             *
212:             * @param node the node which was just modified.
213:             */
214:            public void modifiedNode(final ModelNode node) {
215:                if (!loading) {
216:                    if (!needRepaint
217:                            && (node.hasNodeRendering() || node
218:                                    .hasDescendants())) {
219:                        needRepaint = true;
220:                    }
221:                } else {
222:                    // Ignore modifications on nodes which have no 
223:                    // rendering and no descendants
224:                    if (!node.hasNodeRendering() && !node.hasDescendants()) {
225:                        return;
226:                    }
227:
228:                    // We are doing progressive rendering. Check if
229:                    // the modified node is the one currently suspended
230:                    // or one of its children.
231:                    // Modifications will be picked up when we 
232:                    // paint the node after it has finished 
233:                    // loading.
234:                    if (needLoadNode != null) {
235:                        if (node == needLoadNode) {
236:                            return;
237:                        } else {
238:                            ModelNode parent = node.parent;
239:                            while (parent != null) {
240:                                if (parent == needLoadNode) {
241:                                    return;
242:                                }
243:                                parent = parent.parent;
244:                            }
245:                            needRepaint = true;
246:                        }
247:                    } else {
248:                        if (!needRepaint) {
249:                            // We modified a node which did not have node 
250:                            // rendering. 
251:                            if (progressiveNode != null
252:                                    && progressiveNode != node) {
253:                                needRepaint = true;
254:                            }
255:                            progressiveNode = node;
256:                        }
257:                    }
258:                }
259:            }
260:
261:            /**
262:             * Invoked when the input node has finished loading. 
263:             *
264:             * @param node the <code>node</code> for which loading
265:             *        is complete.
266:             */
267:            public void loadComplete(final ModelNode node) {
268:                // System.err.println(">>>>>>>>>>>>>> loadComplete : " + node);
269:                if (node instanceof  DocumentNode) {
270:                    // We are finished with the loading phase.
271:                    // Progressive rendering can stop
272:                    loading = false;
273:                    canvasUpdateListener.initialLoadComplete(null);
274:
275:                    // At this point, we are ready to start the animation loop.
276:                    // We set the document's scheduled Runnable.
277:
278:                    // IMPL NOTE : We disable animations if there are no initial animations.
279:                    // We should really only sample when there are 
280:                    // active animations, but animations can be added by scripts, so
281:                    // we will need a more sophisticated mechanism.
282:                    if (documentNode.updateQueue != null
283:                            && documentNode.timeContainerRootSupport.timedElementChildren
284:                                    .size() > 0) {
285:                        SMILSample.DocumentWallClock clock = new SMILSample.DocumentWallClock(
286:                                documentNode);
287:                        sampler = new SMILSample(documentNode, clock);
288:                        documentNode.updateQueue.scheduleAtFixedRate(sampler,
289:                                this , smilRate);
290:                        documentNode.timeContainerRootSupport.initialize();
291:                        clock.start();
292:                    }
293:                } else if (node == needLoadNode) {
294:                    // We loaded a node fully. We can now display that
295:                    // node and its children and proceed with progressive
296:                    // rendering
297:                    if (progressiveNode != null) {
298:                        throw new Error();
299:                    }
300:                    progressiveNode = node;
301:                    needLoadNode = null;
302:                }
303:                updateCanvas();
304:            }
305:
306:            /**
307:             * Invoked when a document error happened before finishing loading.
308:             *
309:             * @param documentNode the <code>DocumentNode</code> for which loading
310:             *        has failed.
311:             * @param error the exception which describes the reason why loading
312:             *        failed.
313:             */
314:            public void loadingFailed(final DocumentNode documentNode,
315:                    final Exception error) {
316:                loading = false;
317:                canvasUpdateListener.initialLoadComplete(error);
318:            }
319:
320:            /**
321:             * Invoked when the document starts loading
322:             *
323:             * @param documentNode the <code>DocumentNode</code> for which loading
324:             *        is starting
325:             * @param is the <code>InputStream</code> from which SVG content
326:             *        is loaded.
327:             */
328:            public void loadStarting(final DocumentNode documentNode,
329:                    final InputStream is) {
330:                loading = true;
331:            }
332:
333:            /**
334:             * Invoked when the input node has started loading
335:             *
336:             * @param node the <code>ModelNode</code> for which loading
337:             *        has started.
338:             */
339:            public void loadBegun(final ModelNode node) {
340:                updateCanvas();
341:            }
342:
343:            /**
344:             * Invoked when a string has been appended, during a load
345:             * phase. This is only used when parsing a document and is
346:             * used in support of progressive download, like the other
347:             * loadXXX methods.
348:             *
349:             * @param node the <code>ModelNode</code> on which text has been
350:             *        inserted.
351:             */
352:            public void textInserted(final ModelNode node) {
353:            }
354:
355:            /**
356:             * @return the associated SMILSampler, if animations are run.
357:             */
358:            public SMILSample getSampler() {
359:                return sampler;
360:            }
361:
362:            /**
363:             * Utility method used to update the canvas appropriately
364:             * depending on what is needed.
365:             * 
366:             * During the loading phase, while we do progressive
367:             * rendering, the canvas will only redraw nodes in the
368:             * progressiveNodes list, unless a repaint has been 
369:             * requested.
370:             *
371:             * Important Note: this method should only be called from
372:             * the update thread, i.e., the thread that also manages
373:             * the model node tree.
374:             */
375:            public void updateCanvas() {
376:                if (!loading) {
377:                    if (needRepaint) {
378:                        if (canvasConsumed) {
379:                            fullPaint();
380:                            needRepaint = false;
381:                        } else {
382:                            // There is a request to update the canvas
383:                            // (likely after a Runnable was invoked),
384:                            // but the last update was not consumed.
385:                            // If there is a Runnable in the RunnableQueue,
386:                            // we just skip this rendering update. Otherwise,
387:                            // schedule a fake Runnable to force a later repaint.
388:                            if (documentNode.getUpdateQueue().getSize() == 0) {
389:                                documentNode.getUpdateQueue().preemptLater(
390:                                        new Runnable() {
391:                                            public void run() {
392:                                            }
393:                                        }, this );
394:                            }
395:                        }
396:                    }
397:                } else {
398:                    if (needRepaint) {
399:                        // A full repaint was requested. If there is no
400:                        // suspended node, just do a full repaint.
401:                        // Otherwise, do a partial paint
402:                        if (needLoadNode == null) {
403:                            fullPaint();
404:                        } else {
405:                            partialPaint(documentNode);
406:                            canvasUpdateListener.updateComplete(this );
407:                        }
408:                    } else if (progressiveNode != null) {
409:                        progressivePaint(progressiveNode);
410:                    }
411:                    needRepaint = false;
412:                    progressiveNode = null;
413:                }
414:            }
415:
416:            /**
417:             * Utility method invoked when an incremental painting is needed
418:             * on a node. This may be invoked when a node was just inserted
419:             * into the tree or when a node which required full loading of
420:             * its children has been completely loaded.
421:             *
422:             * @param node the node to paint incrementally on the canvas
423:             */
424:            protected void progressivePaint(final ModelNode node) {
425:                // If this node already has children, we need to do a fullNodePaint.
426:                // This happens for the <use> element when the <use> references
427:                // an element which appeared before in the document.
428:                if (node.hasDescendants()) {
429:                    fullNodePaint(node);
430:                } else if (node.hasNodeRendering()
431:                        && (node.canRenderState == 0)) {
432:                    synchronized (lock) {
433:                        if (!canvasConsumed) {
434:                            try {
435:                                lock.wait();
436:                            } catch (InterruptedException ie) {
437:                            }
438:                        }
439:                        node.paint(rg);
440:                        canvasConsumed = false;
441:                        canvasUpdateListener.updateComplete(this );
442:                    }
443:                }
444:            }
445:
446:            /**
447:             * Utility method invoked when a node and its children need
448:             * to be painted. This is used, for example, when a node
449:             * which requires full loading before rendering is finally
450:             * fully loaded.
451:             * 
452:             * @param node the node to paint fully, i.e, including its 
453:             *        children.
454:             */
455:            protected void fullNodePaint(final ModelNode node) {
456:                if (node.canRenderState == 0) {
457:                    synchronized (lock) {
458:                        if (!canvasConsumed) {
459:                            try {
460:                                lock.wait();
461:                            } catch (InterruptedException ie) {
462:                            }
463:                        }
464:                        node.paint(rg);
465:                        canvasConsumed = false;
466:                        canvasUpdateListener.updateComplete(this );
467:                    }
468:                }
469:            }
470:
471:            /**
472:             * Utility method to paint the input tree up to, but not
473:             * including the needLoadNode. This is a recursive method
474:             * which should be called with the root of the tree to 
475:             * be painted.
476:             *
477:             * @param node the node to paint next.
478:             */
479:            protected void partialPaint(final ModelNode node) {
480:                if (node == needLoadNode || (node.canRenderState != 0)) {
481:                    return;
482:                }
483:
484:                if (node.hasNodeRendering()) {
485:                    synchronized (lock) {
486:                        node.paint(rg);
487:                    }
488:                } else {
489:                    ModelNode child = node.getFirstExpandedChild();
490:                    while (child != null) {
491:                        partialPaint(child);
492:                        child = child.nextSibling;
493:                    }
494:
495:                    child = node.getFirstChildNode();
496:                    while (child != null) {
497:                        partialPaint(child);
498:                        child = child.nextSibling;
499:                    }
500:                }
501:            }
502:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.