Source Code Cross Referenced for CWindow.java in  » 6.0-JDK-Modules » j2me » com » sun » midp » chameleon » 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.midp.chameleon 
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.midp.chameleon;
028:
029:        import com.sun.midp.chameleon.skins.ScreenSkin;
030:        import com.sun.midp.chameleon.layers.BackgroundLayer;
031:        import javax.microedition.lcdui.*;
032:
033:        /**
034:         * This class is a top-level "window" in Chameleon. A window is
035:         * a collection of other layers and serves to maintain a z-ordering
036:         * of those layers. The window also contains the complex repaint logic
037:         * to support semi-transparent windows, their dirty regions, and the
038:         * rectangle logic to repaint other layers of the window when necessary.
039:         */
040:        public abstract class CWindow {
041:
042:            /**
043:             * An array holding the bounds of this window. The indices are
044:             * as follows:
045:             * 0 = window's 'x' coordinate
046:             * 1 = window's 'y' coordinate
047:             * 2 = window's width
048:             * 3 = window's height
049:             * 
050:             * Note: The window's x and y coordinate can only be interpreted
051:             * by some outside entity. For example, if some sort of manager
052:             * was in charge of overseeing the placement of windows on the
053:             * screen, it could do so by using the x and y coordinate values
054:             * of this window's bounds.
055:             */
056:            protected int[] bounds;
057:
058:            /**
059:             * Flag indicating that at least one layer belonging to this
060:             * window is in need of repainting 
061:             */
062:            protected boolean dirty;
063:
064:            /**
065:             * Ordered bi-directional list with all the layers of this window.
066:             */
067:            protected CLayerList layers;
068:
069:            /** The number of dirty layers to repaint */
070:            protected int dirtyCount;
071:
072:            /** Initial maximal number of the dirty layers */
073:            protected int dirtyMaxCount = 10;
074:
075:            /** Layers replication to not keep the lock on painting */
076:            protected CLayer[] dirtyLayers = new CLayer[dirtyMaxCount];
077:
078:            /**
079:             * Background layer of this window, should be the bottom most layer
080:             * of the window, can be invisible for transparent windows. 
081:             */
082:            protected BackgroundLayer bgLayer;
083:
084:            /** Cache values for the clip rectangle */
085:            protected int cX, cY, cW, cH;
086:
087:            /** Cache values for the graphics translation */
088:            protected int tranX, tranY;
089:
090:            /** Cache value for the graphics font */
091:            protected Font font;
092:
093:            /** Cache value for the graphics foreground color */
094:            protected int color;
095:
096:            /**
097:             * Construct a new CWindow given the background image and color.
098:             * If the background image is null, the fill color will be used
099:             * instead. In the case null image and negative color are specified
100:             * the window is considered to be transparent.
101:             *
102:             * @param bgImage the background image to use for the window background
103:             * @param bgColor the background fill color in 0xrrggbbaa format to use
104:             *          for the window background if the background image is null.
105:             */
106:            public CWindow(Image bgImage, int bgColor) {
107:                bounds = new int[4];
108:                bounds[X] = 0;
109:                bounds[Y] = 0;
110:                bounds[W] = ScreenSkin.WIDTH;
111:                bounds[H] = ScreenSkin.HEIGHT;
112:
113:                layers = new CLayerList();
114:
115:                /* Add the most bottom background layer */
116:                bgLayer = new BackgroundLayer(bgImage, bgColor);
117:                bgLayer.setBounds(0, 0, ScreenSkin.WIDTH, ScreenSkin.HEIGHT);
118:                addLayer(bgLayer);
119:            }
120:
121:            /** Resize window and its background according to updated skin values */
122:            public void resize() {
123:                bounds[W] = ScreenSkin.WIDTH;
124:                bounds[H] = ScreenSkin.HEIGHT;
125:                bgLayer.setBounds(0, 0, ScreenSkin.WIDTH, ScreenSkin.HEIGHT);
126:            }
127:
128:            /**
129:             * Add a new CLayer to the "deck" of layers associated
130:             * with this CWindow. This method will sequentially add
131:             * layers to the window, placing subsequently added layers
132:             * on top of previously added layers.
133:             *
134:             * @param layer the new layer to add to this window
135:             * @return true if new layer was added, false otherwise 
136:             */
137:            public boolean addLayer(CLayer layer) {
138:                if (layer != null) {
139:                    if (CGraphicsQ.DEBUG) {
140:                        System.err.println("Add Layer: " + layer);
141:                    }
142:                    synchronized (layers) {
143:                        if (layers.find(layer) == null) {
144:                            layer.owner = this ;
145:                            layers.addLayer(layer);
146:                            layer.addDirtyRegion();
147:                            requestRepaint();
148:                            layer.addNotify();
149:                            return true;
150:                        }
151:                    }
152:                }
153:                return false;
154:            }
155:
156:            /**
157:             * Remove a layer from this CWindow. This method will remove
158:             * the given layer from the "deck" of layers associated with
159:             * this CWindow. If successfull, this method will return true,
160:             * false otherwise (for example, if the layer does not belong
161:             * to this window).
162:             *
163:             * @param layer the layer to remove from this window
164:             * @return true if successful, false otherwise
165:             */
166:            public boolean removeLayer(CLayer layer) {
167:                synchronized (layers) {
168:                    CLayerElement le = sweepLayer(layer);
169:                    if (le != null) {
170:                        if (CGraphicsQ.DEBUG) {
171:                            System.err.println("Remove Layer: " + layer);
172:                        }
173:                        layer.owner = null;
174:                        requestRepaint();
175:                        layers.removeLayerElement(le);
176:                        layer.removeNotify(this );
177:                        return true;
178:                    }
179:                }
180:                return false;
181:            }
182:
183:            /**
184:             * Move layer to anotger location
185:             * @param newBounds new bounds for this layer 
186:             * @param x New 'x' coordinate of the layer's origin
187:             * @param y New 'y' coordinate of the layer's origin
188:             * @param w New width of the layer
189:             * @param h New height of the layer
190:
191:             * @return true if successful, false otherwise
192:             */
193:            public boolean relocateLayer(CLayer layer, int x, int y, int w,
194:                    int h) {
195:                if (layer != null) {
196:                    synchronized (layers) {
197:                        if (sweepLayer(layer) != null) {
198:                            if (CGraphicsQ.DEBUG) {
199:                                System.err.println("Relocate Layer: " + layer);
200:                            }
201:                            int[] oldBounds = { layer.bounds[X],
202:                                    layer.bounds[Y], layer.bounds[W],
203:                                    layer.bounds[H] };
204:
205:                            if (oldBounds[X] != x || oldBounds[Y] != y
206:                                    || oldBounds[W] != w || oldBounds[H] != h) {
207:                                layer.setBounds(x, y, w, h);
208:                                layer.addDirtyRegion();
209:                                requestRepaint();
210:                                layer.relocateNotify(oldBounds);
211:                                return true;
212:                            }
213:                        }
214:                    }
215:                }
216:                return false;
217:            }
218:
219:            /**
220:             * Allow this window to process key input. The type of key input
221:             * will be press, release, repeat, etc. The key code will identify
222:             * which key generated the event. This method will return true if
223:             * the event was processed by this window or one of its layers,
224:             * false otherwise.
225:             *
226:             * @param type the type of key event (press, release, repeat)
227:             * @param keyCode the identifier of the key which generated the event
228:             * @return true if this window or one of its layers processed the event
229:             */
230:            public boolean keyInput(int type, int keyCode) {
231:                CLayer layer;
232:                synchronized (layers) {
233:                    for (CLayerElement le = layers.getTop(); le != null; le = le
234:                            .getLower()) {
235:                        layer = le.getLayer();
236:                        if (layer.supportsInput
237:                                && layer.keyInput(type, keyCode)) {
238:                            return true;
239:                        }
240:                    }
241:                } // sync
242:                return false;
243:            }
244:
245:            /**
246:             * Allow this window to process pointer input. The type of pointer input
247:             * will be press, release, drag, etc. The x and y coordinates will 
248:             * identify the point at which the pointer event occurred in the coordinate
249:             * system of this window. This window will translate the coordinates
250:             * appropriately for each layer contained in this window. This method will
251:             * return true if the event was processed by this window or one of its 
252:             * layers, false otherwise.
253:             *
254:             * @param type the type of pointer event (press, release, drag)
255:             * @param x the x coordinate of the location of the event
256:             * @param y the y coordinate of the location of the event
257:             * @return true if this window or one of its layers processed the event
258:             */
259:            public boolean pointerInput(int type, int x, int y) {
260:                CLayer layer;
261:                synchronized (layers) {
262:                    for (CLayerElement le = layers.getTop(); le != null; le = le
263:                            .getLower()) {
264:                        layer = le.getLayer();
265:                        if (layer.visible && layer.supportsInput
266:                                && layer.handlePoint(x, y)) {
267:                            // If the layer is visible, supports input, and
268:                            // contains the point of the pointer press, we translate
269:                            // the point into the layer's coordinate space and
270:                            // pass on the input
271:                            if (layer.pointerInput(type, x - layer.bounds[X], y
272:                                    - layer.bounds[Y])) {
273:                                return true;
274:                            }
275:                        }
276:                    }
277:                } // sync
278:                return false;
279:            }
280:
281:            /**
282:             * Handle input from some type of device-dependent
283:             * input method. This could be input from something
284:             * such as T9, or a phonebook lookup, etc.
285:             *
286:             * @param str the text to handle as direct input
287:             * @return true if this window or one of its layers processed the event
288:             */
289:            public boolean methodInput(String str) {
290:                CLayer layer;
291:                synchronized (layers) {
292:                    for (CLayerElement le = layers.getTop(); le != null; le = le
293:                            .getLower()) {
294:                        layer = le.getLayer();
295:                        if (layer.visible && layer.supportsInput
296:                                && layer.methodInput(str)) {
297:                            return true;
298:                        }
299:                    }
300:                } // sync
301:                return false;
302:            }
303:
304:            /**
305:             * Request a repaint. This method MUST be overridden
306:             * by subclasses to provide the implementation.
307:             */
308:            public abstract void requestRepaint();
309:
310:            /**
311:             * Subtract this layer area from an underlying dirty regions.
312:             * The method is designed to reduce dirty regions of a layres
313:             * below the opaque visible layer.
314:             *
315:             * @param le layer list element
316:             */
317:            private void cleanLowerDirtyRegions(CLayerElement le) {
318:                if (CGraphicsQ.DEBUG) {
319:                    System.err
320:                            .println("Clean dirty regions under opaque layer: "
321:                                    + le.getLayer());
322:                }
323:
324:                CLayer l = le.getLayer();
325:                for (CLayerElement le2 = le.getLower(); le2 != null; le2 = le2
326:                        .getLower()) {
327:                    CLayer l2 = le2.getLayer();
328:                    if (l2.isDirty()) {
329:                        l2.subDirtyRegion(l.bounds[X] - l2.bounds[X],
330:                                l.bounds[Y] - l2.bounds[Y], l.bounds[W],
331:                                l.bounds[H]);
332:                    }
333:                }
334:            }
335:
336:            /**
337:             * Update dirty regions of all visible layers in the stack regarding
338:             * the entire area of the given layer as being dirty. The method is
339:             * needed to perform layer move/resize/remove opertion, since other
340:             * layers should be informed of changed area.
341:             *
342:             * @param layer the layer whose area should be reported as dirty to
343:             *   other stack layers
344:             */
345:            CLayerElement sweepLayer(CLayer layer) {
346:                if (layer != null) {
347:                    if (CGraphicsQ.DEBUG) {
348:                        System.err.println("Sweep Layer: " + layer);
349:                    }
350:                    synchronized (layers) {
351:                        CLayerElement le = layers.find(layer);
352:                        if (le != null) {
353:                            // IMPL NOTE: when a layer gets removed (or has its setVisible(false))
354:                            // called, the parent window must loop through all the other
355:                            // layers and mark them as dirty if they intersect with the
356:                            // layer being removed (or having its visibility changed).
357:                            layer.addDirtyRegion();
358:                            sweepAndMarkDirtyLayer(le, true);
359:                            return le;
360:                        }
361:                    }
362:                }
363:                return null;
364:            }
365:
366:            /**
367:             * Propagate dirty region of the layer to other layers in the stack.
368:             * The method should be called for dirty layers only.
369:             * The dirty layer can be invisible in the case it has been
370:             * hidden since the previous paint.
371:             *
372:             * IMPL_NOTE: The layer been removed or set to invisible state since
373:             *   the previous paint is considered as "hidden", thus it should be
374:             *   entirely dirty and must affect other visible layers accordingly.   
375:             *
376:             * @param le dirty layer element to be propagated to other layers
377:             * @param hidden indicates whether the dirty layer has been hidden
378:             *   since the previous repaint
379:             * @return the highest layer element above le with modified dirty
380:             *   region, or null if none
381:             */
382:            private CLayerElement sweepAndMarkDirtyLayer(CLayerElement le,
383:                    boolean hidden) {
384:
385:                if (CGraphicsQ.DEBUG) {
386:                    System.err.println("Sweep and mark dirty layer: "
387:                            + le.getLayer());
388:                }
389:
390:                CLayer l2;
391:                CLayerElement res = null;
392:                CLayer l = le.getLayer();
393:
394:                // Prepare absolute dirty region coordinates of layer l
395:                int dx = l.bounds[X];
396:                int dy = l.bounds[Y];
397:                int dh, dw;
398:                if (l.isEmptyDirtyRegions()) {
399:                    dw = l.bounds[W];
400:                    dh = l.bounds[H];
401:                } else {
402:                    dx += l.dirtyBounds[X];
403:                    dy += l.dirtyBounds[Y];
404:                    dw = l.dirtyBounds[W];
405:                    dh = l.dirtyBounds[H];
406:                }
407:
408:                // Sweep dirty region to upper layers
409:                for (CLayerElement le2 = le.getUpper(); le2 != null; le2 = le2
410:                        .getUpper()) {
411:
412:                    l2 = le2.getLayer();
413:                    if (l2.visible) {
414:                        if (l2.addDirtyRegion(dx - l2.bounds[X], dy
415:                                - l2.bounds[Y], dw, dh)) {
416:                            // Remember the highest changed layer
417:                            res = le2;
418:                        }
419:                    }
420:                }
421:
422:                // Sweep non-opaque dirty region to undelying layers
423:                if (!l.opaque || hidden) {
424:                    for (CLayerElement le2 = le.getLower(); le2 != null; le2 = le2
425:                            .getLower()) {
426:
427:                        l2 = le2.getLayer();
428:                        if (l2.visible) {
429:                            l2.addDirtyRegion(dx - l2.bounds[X], dy
430:                                    - l2.bounds[Y], dw, dh);
431:                        }
432:                    }
433:
434:                    // A newly hidden layer should be dirty only for the first
435:                    // succeeded paint, it should be cleaned as soon as underlying
436:                    // layers are properly marked as dirty. 
437:                    if (hidden) {
438:                        l.cleanDirty();
439:                    }
440:                }
441:
442:                return res;
443:            }
444:
445:            // Heuristic Explanation: Any layer that needs painting also
446:            // requires all layers below and above that region to be painted.
447:            // This is required because layers may be transparent or even
448:            // partially translucent - thus they require that all layers beneath
449:            // and above them be repainted as well.
450:
451:            // To accomplish this we loop through the stack of layers from the top
452:            // most to the bottom most. If a layer is "dirty" (has its dirty bit
453:            // set), we find all layers that intersect with the dirty region and
454:            // we mark that layer to be painted as well. If that layer is already
455:            // marked to be painted and has its own dirty region, we union
456:            // the existing region with the new region. If that layer does
457:            // not have a dirty region, we simply set a new one. In the case a
458:            // dirty region is modified for a higher layer been processed already
459:            // we need to restart the loop from the modified layer.
460:
461:            // After doing this initial iteration, all layers will now be
462:            // marked dirty where appropriate and have their individual dirty
463:            // regions set. We then make another iteration from the bottom
464:            // most layer to the top, painting the dirty region of each layer.
465:
466:            /**
467:             * First Pass: We do sweep and mark of all layers requiring a repaint,
468:             * the areas behind a visible opaque layers need no repaint
469:             */
470:            private void sweepAndMarkLayers() {
471:                if (CGraphicsQ.DEBUG) {
472:                    System.err.println("[Sweep and mark layers]");
473:                }
474:
475:                CLayer l;
476:                CLayerElement changed;
477:                CLayerElement le = layers.getTop();
478:
479:                while (le != null) {
480:                    l = le.getLayer();
481:
482:                    if (l.visible && l.opaque) {
483:                        cleanLowerDirtyRegions(le);
484:                    }
485:
486:                    // The dirty layer can be invisible, that means it
487:                    // has been hidden since the previous paint.
488:                    if (l.isDirty()) {
489:                        // In the case higher layer was changed we need to
490:                        // restart all the algorithm from the changed layer
491:                        changed = sweepAndMarkDirtyLayer(le, !l.visible);
492:                        if (changed != null) {
493:                            if (CGraphicsQ.DEBUG) {
494:                                System.err.println("Restart sweep and mark: "
495:                                        + changed.getLayer());
496:                            }
497:                            le = changed;
498:                            changed = null;
499:                            continue;
500:                        }
501:                    }
502:                    // Go to next lower layer
503:                    le = le.getLower();
504:                }
505:            }
506:
507:            /**
508:             * Copy dirty layer references to array for further painting.
509:             * The copying is needed to not keep lock on layers list when
510:             * layers painting will happen.
511:             */
512:            private void copyDirtyLayers() {
513:                if (CGraphicsQ.DEBUG) {
514:                    System.err.println("[Copy dirty layers]");
515:                }
516:                CLayer l;
517:                dirtyCount = 0;
518:                int layersCount = layers.size();
519:                // Heuristics to increase array for copied dirty layers
520:                if (layersCount > dirtyMaxCount) {
521:                    dirtyMaxCount += layersCount;
522:                    dirtyLayers = new CLayer[dirtyMaxCount];
523:                }
524:                // Copy dirty layer references
525:                for (CLayerElement le = layers.getBottom(); le != null; le = le
526:                        .getUpper()) {
527:                    l = le.getLayer();
528:                    if (l.visible && l.isDirty()) {
529:                        l.copyLayerBounds();
530:                        dirtyLayers[dirtyCount++] = l;
531:
532:                    } else { // !(visible && dirty)
533:                        if (CGraphicsQ.DEBUG) {
534:                            System.err.println("Skip Layer: " + l);
535:                        }
536:                    } // if
537:                } // for
538:
539:            }
540:
541:            /**
542:             * Second Pass: We sweep through the layers from the bottom to
543:             * the top and paint each one that is marked as dirty
544:             *
545:             * Note, that the painting for copied layers is done here to
546:             * not hold the layers lock during the painting.
547:             *
548:             * @param g The graphics object to use to paint this window.
549:             * @param refreshQ The custom queue which holds the set of refresh
550:             *        regions needing to be blitted to the screen
551:             */
552:            private void paintLayers(Graphics g, CGraphicsQ refreshQ) {
553:                if (CGraphicsQ.DEBUG) {
554:                    System.err.println("[Paint dirty layers]");
555:                }
556:
557:                for (int i = 0; i < dirtyCount; i++) {
558:                    CLayer l = dirtyLayers[i];
559:
560:                    // Prepare relative dirty region coordinates
561:                    // of the current layer
562:                    int dx = l.dirtyBoundsCopy[X];
563:                    int dy = l.dirtyBoundsCopy[Y];
564:                    int dw = l.dirtyBoundsCopy[W];
565:                    int dh = l.dirtyBoundsCopy[H];
566:
567:                    // Before we call into the layer to paint, we
568:                    // translate the graphics context into the layer's
569:                    // coordinate space
570:                    g.translate(l.boundsCopy[X], l.boundsCopy[Y]);
571:
572:                    if (CGraphicsQ.DEBUG) {
573:                        System.err.println("Painting Layer: " + l);
574:                        System.err.println("\tClip: " + dx + ", " + dy + ", "
575:                                + dw + ", " + dh);
576:                    }
577:
578:                    // Clip the graphics to only contain the dirty region of
579:                    // the layer (if the dirty region isn't set, clip to the
580:                    // whole layer contents).
581:                    g.clipRect(dx, dy, dw, dh);
582:                    refreshQ.queueRefresh(l.boundsCopy[X] + dx, l.boundsCopy[Y]
583:                            + dy, dw, dh);
584:                    l.paint(g);
585:
586:                    // We restore our graphics context to prepare
587:                    // for the next layer
588:                    g.translate(-g.getTranslateX(), -g.getTranslateY());
589:                    g.translate(tranX, tranY);
590:
591:                    // We reset our clip to this window's bounds again.
592:                    g.setClip(bounds[X], bounds[Y], bounds[W], bounds[H]);
593:
594:                    g.setFont(font);
595:                    g.setColor(color);
596:                } // for
597:            }
598:
599:            /**
600:             * Sets all visible layers to dirty state.
601:             * The method is needed on system events like screen rotation,
602:             * when generic layers system is not capabel to properly analyze
603:             * layers changes, e.g. of move/resize kind. It could be fixed in
604:             * the future and this method will be out of use. 
605:             */
606:            public void setAllDirty() {
607:                synchronized (layers) {
608:                    CLayer l;
609:                    for (CLayerElement le = layers.getBottom(); le != null; le = le
610:                            .getUpper()) {
611:                        l = le.getLayer();
612:                        if (l.visible) {
613:                            l.addDirtyRegion();
614:                        } // if
615:                    } // for
616:                } // synchronized
617:            }
618:
619:            /**
620:             * Paint this window. This method should not generally be overridden by
621:             * subclasses. This method carefully stores the clip, translation, and
622:             * color before calling into subclasses. The graphics context should be
623:             * translated such that it is in this window's coordinate space (0,0 is
624:             * the top left corner of this window). 
625:             *
626:             * @param g The graphics object to use to paint this window.
627:             * @param refreshQ The custom queue which holds the set of refresh
628:             *        regions needing to be blitted to the screen
629:             */
630:            public void paint(Graphics g, CGraphicsQ refreshQ) {
631:                // We reset our dirty flag first. Any layers that become
632:                // dirty in the duration of this method will then cause it
633:                // to toggle back to true for the subsequent pass.
634:                // IMPL NOTE: when layers start to do complex animation, there will
635:                // likely need to be better atomic handling of the dirty state,
636:                // and layers becoming dirty and getting painted
637:                this .dirty = false;
638:
639:                // Store the clip, translate, font, color
640:                cX = g.getClipX();
641:                cY = g.getClipY();
642:                cW = g.getClipWidth();
643:                cH = g.getClipHeight();
644:
645:                tranX = g.getTranslateX();
646:                tranY = g.getTranslateY();
647:
648:                font = g.getFont();
649:                color = g.getColor();
650:
651:                // We set the basic clip to the size of this window
652:                g.setClip(bounds[X], bounds[Y], bounds[W], bounds[H]);
653:
654:                synchronized (layers) {
655:                    sweepAndMarkLayers();
656:                    copyDirtyLayers();
657:                }
658:                paintLayers(g, refreshQ);
659:
660:                // We restore the original clip. The original font, color, etc.
661:                // have already been restored
662:                g.setClip(cX, cY, cW, cH);
663:            }
664:
665:            /**
666:             * Establish a background. This method will evaluate the parameters
667:             * and create a background which is appropriate. If the image is non-null,
668:             * the image will be used to create the background. If the image is null,
669:             * the values for the colors will be used and the background will be
670:             * painted in fill color instead. If the image is null, and the background
671:             * color is a negative value, this layer will become transparent and no
672:             * background will be painted.
673:             *
674:             * @param bgImage the image to use for the background tile (or null)
675:             * @param bgColor if the image is null, use this color as a background
676:             *                fill color
677:             */
678:            synchronized void setBackground(Image bgImage, int bgColor) {
679:                bgLayer.setBackground(bgImage, bgColor);
680:            }
681:
682:            /**
683:             * Returns true if any layer of this window is in need of repainting.
684:             *
685:             * @return true if any layer of this window is marked as 'dirty' 
686:             *         and needs repainting.
687:             */
688:            public boolean isDirty() {
689:                return this .dirty;
690:            }
691:
692:            /**
693:             * Mark this window as being dirty and requiring a repaint.
694:             */
695:            public void setDirty() {
696:                this .dirty = true;
697:            }
698:
699:            /** Constant used to reference the '0' index of the bounds array */
700:            public static final int X = 0;
701:
702:            /** Constant used to reference the '1' index of the bounds array */
703:            public static final int Y = 1;
704:
705:            /** Constant used to reference the '2' index of the bounds array */
706:            public static final int W = 2;
707:
708:            /** Constant used to reference the '3' index of the bounds array */
709:            public static final int H = 3;
710:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.