Source Code Cross Referenced for CLayer.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 javax.microedition.lcdui.*;
030:        import com.sun.midp.chameleon.skins.*;
031:
032:        /**
033:         * This class represents a "layer". A layer is an element used to comprise
034:         * a higher-level "window" (see CWindow.java). A layer has several properties
035:         * such as its visibility, whether it accepts input, its size, etc. A layer
036:         * also has content, such as its background and its foreground.
037:         */
038:        public class CLayer {
039:
040:            /** Flag indicating this layer is in need of repainting. */
041:            private boolean dirty;
042:
043:            /** Array holding a bounding rectangle of an area needing repainting. */
044:            protected int[] dirtyBounds;
045:
046:            /** Copy of the layer bounds needed to unlock the layers for painting */
047:            protected int[] boundsCopy;
048:
049:            /** Copy of the dirty bounds needed to unlock the layers for painting */
050:            protected int[] dirtyBoundsCopy;
051:
052:            /** Flag indicating if this layer has a transparent background or not. */
053:            protected boolean transparent;
054:
055:            /** Flag indicating the current visibility state of this layer. */
056:            protected boolean visible;
057:
058:            /** Flag indicating the ability of this layer to support key/pen input. */
059:            protected boolean supportsInput;
060:
061:            /** 
062:             * Flag indicating this layer is either completely opaque, or not.
063:             * By default, a layer is not opaque, and thus requires the background
064:             * and any layers below it to be painted in addition to itself. However,
065:             * if a layer is opaque, it does not require anything it is obscuring to
066:             * be painted, just itself. All layers are opaque by default.
067:             */
068:            protected boolean opaque = true;
069:
070:            /** 
071:             * If this layer has a filled color background, 
072:             * the 0xrrggbbaa value of that color 
073:             */
074:            protected int bgColor;
075:
076:            /**
077:             * The image to use as a background for this layer if this layer
078:             * is not transparent and does not use a fill color.
079:             */
080:            protected Image[] bgImage;
081:
082:            /**
083:             * If this layer is not transparent and uses a background image,
084:             * a flag indicating if that image should be tiled or otherwise centered.
085:             */
086:            protected boolean tileBG;
087:
088:            /**
089:             * The window which owns this layer. If this layer has not been added
090:             * to a window or it has been removed from a window, the owner will be
091:             * null.
092:             */
093:            protected CWindow owner;
094:
095:            /**
096:             * An array holding the bounds of this layer. The indices are
097:             * as follows:
098:             * 0 = layer's 'x' coordinate
099:             * 1 = layer's 'y' coordinate
100:             * 2 = layer's width
101:             * 3 = layer's height
102:             * The 'x' and 'y' coordinates are in the coordinate space of the
103:             * window which contains this layer.
104:             */
105:            public int[] bounds;
106:
107:            /** Constant used to reference the '0' index of the bounds array */
108:            public static final int X = 0;
109:
110:            /** Constant used to reference the '1' index of the bounds array */
111:            public static final int Y = 1;
112:
113:            /** Constant used to reference the '2' index of the bounds array */
114:            public static final int W = 2;
115:
116:            /** Constant used to reference the '3' index of the bounds array */
117:            public static final int H = 3;
118:
119:            /** 
120:             * When in the paint() routine, graphicsColor will be set to the
121:             * default graphics color. This is a convenience variable for
122:             * subclasses to easily modify and then reset the graphics color.
123:             */
124:            int graphicsColor;
125:
126:            /**
127:             * When in the paint() routine, graphicsFont will be set to the
128:             * default graphics Font. This is a convenience variable for
129:             * subclasses to easily modify and then reset the graphics font.
130:             */
131:            Font graphicsFont;
132:
133:            /**
134:             * Construct a default, transparent layer. As a result, the
135:             * 'transparent' value will be set to true.
136:             */
137:            public CLayer() {
138:                this ((Image) null, -1);
139:            }
140:
141:            /**
142:             * Construct a layer with the given background image if it is not null 
143:             * or with a background fill color.
144:             * The color should be in the 0xaarrggbb format. If the bgColor is 
145:             * invalid and bgImage is null, this layer will be transparent and 
146:             * equal to the no-argument constructor.
147:             *
148:             * @param bgImage The background image to use for this layer.
149:             * @param bgColor The color (0xaarrggbb) to use as the background fill
150:             */
151:            public CLayer(Image bgImage, int bgColor) {
152:                if (bgImage != null) {
153:                    this .bgImage = new Image[] { bgImage };
154:                    this .tileBG = true;
155:                    transparent = false;
156:                } else {
157:                    transparent = (bgColor < 0);
158:                }
159:                this .bgColor = bgColor;
160:                initialize();
161:            }
162:
163:            /**
164:             * Construct a layer with the given background images (if not null) 
165:             * or with a background fill color and border. The background images
166:             * should be a 9 element array, creating a 9-piece image background.
167:             * The color should be in the 0xaarrggbb format.  If the bgColor is 
168:             * invalid and bgImages are null, this layer will be transparent and 
169:             * equal to the no-argument constructor.
170:             *
171:             * @param bgImages The background image to use for this layer.
172:             * @param bgColor The color (0xaarrggbb) to use as the background fill
173:             */
174:            public CLayer(Image[] bgImages, int bgColor) {
175:                if (bgImages != null) {
176:                    this .bgImage = new Image[bgImages.length];
177:                    System.arraycopy(bgImages, 0, this .bgImage, 0,
178:                            bgImages.length);
179:                    this .tileBG = false;
180:                    transparent = false;
181:                } else {
182:                    transparent = (bgColor < 0);
183:                }
184:                this .bgColor = bgColor;
185:                initialize();
186:            }
187:
188:            /**
189:             * Finish initialization of this CLayer. This can
190:             * be extended by subclasses. The dimensions of the
191:             * CLayer are stored in its bounds[]. The 'x' and 'y'
192:             * coordinates are in the coordinate space of the
193:             * window which contains this layer. By default, a layer is
194:             * located at the origin and is as large as the screen size.
195:             *
196:             * The X and Y coordinates represent the upper left position
197:             * of this CLayer in the containing CWindow's coordinate space.
198:             *
199:             */
200:            protected void initialize() {
201:                bounds = new int[4];
202:                bounds[X] = 0;
203:                bounds[Y] = 0;
204:                bounds[W] = ScreenSkin.WIDTH;
205:                bounds[H] = ScreenSkin.HEIGHT;
206:
207:                dirtyBounds = new int[4];
208:                dirtyBoundsCopy = new int[4];
209:                boundsCopy = new int[4];
210:                cleanDirtyRegions();
211:
212:                // IMPL_NOTE : center the background image by default
213:            }
214:
215:            /**
216:             * Establish a background. This method will evaluate the parameters
217:             * and create a background which is appropriate. If the image is non-null,
218:             * the image will be used to create the background. If the image is null,
219:             * the values for the colors will be used and the background will be
220:             * painted in fill color instead. If the image is null, and the background
221:             * color is a negative value, this layer will become transparent and no
222:             * background will be painted.
223:             *
224:             * @param bgImage the image to use for the background tile (or null)
225:             * @param tileBG If true, then tile the background image as necessary
226:             *               to fill a larger screen. If false, treat the image
227:             *               as fullsize.
228:             * @param bgColor if the image is null, use this color as a background
229:             *                fill color
230:             */
231:            public void setBackground(Image bgImage, boolean tileBG, int bgColor) {
232:                if (bgImage != null) {
233:                    this .bgImage = new Image[] { bgImage };
234:                    this .tileBG = tileBG;
235:                    transparent = false;
236:                } else {
237:                    this .bgImage = null;
238:                    transparent = (bgColor < 0);
239:                }
240:                this .bgColor = bgColor;
241:                addDirtyRegion();
242:            }
243:
244:            /**
245:             * Establish a background. This method will evaluate the parameters
246:             * and create a background which is appropriate. If the images are 
247:             * non-null, the images will be used to create a 9-piece background.
248:             * If the images are null, the value for the color will be used and
249:             * the background will be painted in fill color instead. If the images
250:             * are null, and the background color is a negative value, this layer
251:             * will become transparent and no background will be painted.
252:             *
253:             * @param bgImages an array containing a 9-piece image set to be used
254:             *                 as the background for this layer
255:             * @param bgColor if the images are null, use this color as a background
256:             *                fill color
257:             */
258:            public void setBackground(Image[] bgImages, int bgColor) {
259:                if (bgImages != null) {
260:                    this .bgImage = new Image[bgImages.length];
261:                    System.arraycopy(bgImages, 0, this .bgImage, 0,
262:                            bgImages.length);
263:                    this .tileBG = false;
264:                    transparent = false;
265:                } else {
266:                    this .bgImage = null;
267:                    transparent = (bgColor < 0);
268:                }
269:                this .bgColor = bgColor;
270:                addDirtyRegion();
271:            }
272:
273:            /**
274:             * Establish the bounds of this layer. The coordinate space for
275:             * the 'x' and 'y' anchor will be interpreted in that of the window
276:             * which contains this layer.
277:             *
278:             * @param x The 'x' coordinate of this layer's origin
279:             * @param y The 'y' coordinate of this layer's origin
280:             * @param w The width of this layer
281:             * @param h The height of this layer
282:             */
283:            public void setBounds(int x, int y, int w, int h) {
284:                if (bounds == null) {
285:                    bounds = new int[4];
286:                }
287:                bounds[X] = x;
288:                bounds[Y] = y;
289:                bounds[W] = w;
290:                bounds[H] = h;
291:            }
292:
293:            /**
294:             * Return the bounds of this layer (in the coordinate space of
295:             * its parent Window). Returns a 4 element array, containing the
296:             * x, y, width, and height representing this layer's bounding
297:             * rectangle
298:             *
299:             * @return this layer's bounding rectangle in the coordinate space
300:             *         of its parent window
301:             */
302:            public int[] getBounds() {
303:                return bounds;
304:            }
305:
306:            /**
307:             * Determine the current visibility of this layer. Note that this
308:             * state only pertains to the layer's visibility status within its
309:             * containing window. The window itself may or may not be actually
310:             * visible on the physical display.
311:             *
312:             * @return true if this layer is currently visible in a window
313:             */
314:            public boolean isVisible() {
315:                return visible;
316:            }
317:
318:            /**
319:             * Toggle the visibility state of this layer within its containing
320:             * window.
321:             *
322:             * @param visible If true, this layer will be painted as part of its
323:             *                containing window, as well as receive events if it
324:             *                supports input.
325:             */
326:            public void setVisible(boolean visible) {
327:                this .visible = visible;
328:                addDirtyRegion();
329:            }
330:
331:            /**
332:             * Determine if this layer is opaque
333:             *
334:             * @return true if this layer does not have any transparent
335:             *         or translucent areas
336:             */
337:            public boolean isOpaque() {
338:                return opaque;
339:            }
340:
341:            /**
342:             * Set the opacity flag for this layer. True means that this
343:             * layer does not have any transparent or translucent areas
344:             *
345:             * @param opaque a flag indicating the layer's opacity
346:             */
347:            public void setOpaque(boolean opaque) {
348:                this .opaque = opaque;
349:            }
350:
351:            /**
352:             * Returns true if this layer is in need of repainting.
353:             *
354:             * @return true if this layer is marked as 'dirty' and needs repainting.
355:             */
356:            public boolean isDirty() {
357:                return this .dirty;
358:            }
359:
360:            /**
361:             * Mark this layer as being dirty.
362:             * By default, this will also mark the containing window (if there is one)
363:             * as being dirty as well.
364:             */
365:            protected void setDirty() {
366:                setDirtyButNotNotifyOwner();
367:                if (owner != null) {
368:                    owner.setDirty();
369:                }
370:            }
371:
372:            /**
373:             * Mark this layer as being dirty
374:             * but don't mark the containing window.
375:             */
376:            protected void setDirtyButNotNotifyOwner() {
377:                this .dirty = true;
378:            }
379:
380:            /** Clean any dirty regions of the layer. */
381:            protected void cleanDirtyRegions() {
382:                dirtyBounds[X] = dirtyBounds[Y] = dirtyBounds[W] = dirtyBounds[H] = -1;
383:            }
384:
385:            /**
386:             * Determines whether dirty regions are empty.
387:             *
388:             * @return true if dirty regions are not set,
389:             *         false otherwise
390:             */
391:            protected boolean isEmptyDirtyRegions() {
392:                return dirtyBounds[X] == -1;
393:            }
394:
395:            /** Clean any dirty regions of the layer and mark layer as not dirty. */
396:            protected void cleanDirty() {
397:                dirty = false;
398:                cleanDirtyRegions();
399:            }
400:
401:            /**
402:             * Determine if this layer supports input, such as key and pen events.
403:             *
404:             * @return true if this layer supports handling input events
405:             */
406:            public boolean supportsInput() {
407:                return supportsInput;
408:            }
409:
410:            /**
411:             * Toggle the ability of this layer to receive input.
412:             *
413:             * @param support If true, this layer will receive user input events
414:             *                (as long as the layer is also visible)
415:             */
416:            public void setSupportsInput(boolean support) {
417:                this .supportsInput = support;
418:            }
419:
420:            /**
421:             * Handle input from a pen tap.
422:             *
423:             * Parameters describe the type of pen event and the x,y location in the
424:             * layer at which the event occurred.
425:             *
426:             * Important: the x,y location of the pen tap will already be translated
427:             * into the coordinate space of the layer.
428:             *
429:             * @param type the type of pen event
430:             * @param x the x coordinate of the event
431:             * @param y the y coordinate of the event
432:             * @return
433:             */
434:            public boolean pointerInput(int type, int x, int y) {
435:                return false;
436:            }
437:
438:            /**
439:             * Handle key input from a keypad. Parameters describe
440:             * the type of key event and the platform-specific
441:             * code for the key. (Codes are translated using the
442:             * lcdui.Canvas)
443:             *
444:             * @param type the type of key event
445:             * @param code the numeric code assigned to the key
446:             * @return
447:             */
448:            public boolean keyInput(int type, int code) {
449:                return false;
450:            }
451:
452:            /**
453:             * Handle input from some type of device-dependent
454:             * input method. This could be input from something
455:             * such as T9, or a phonebook lookup, etc.
456:             *
457:             * @param str the text to handle as direct input
458:             * @return
459:             */
460:            public boolean methodInput(String str) {
461:                return false;
462:            }
463:
464:            /**
465:             * Utility method to determine if the given point lies within
466:             * the bounds of this layer. The point should be in the coordinate
467:             * space of this layer's containing CWindow.
468:             *
469:             * @param x the "x" coordinate of the point
470:             * @param y the "y" coordinate of the point
471:             * @return true if the coordinate lies in the bounds of this layer
472:             */
473:            public boolean containsPoint(int x, int y) {
474:                return (visible && x >= bounds[X]
475:                        && x <= (bounds[X] + bounds[W]) && y >= bounds[Y] && y <= (bounds[Y] + bounds[H]));
476:            }
477:
478:            /**
479:             * Utility method to determine if this layer wanna handle
480:             * the given point. By default the layer handles the point if it
481:             * lies within the bounds of this layer.  The point should be in
482:             * the coordinate space of this layer's containing CWindow.
483:             *
484:             * @param x the "x" coordinate of the point
485:             * @param y the "y" coordinate of the point
486:             * @return true if the coordinate lies in the bounds of this layer
487:             */
488:            public boolean handlePoint(int x, int y) {
489:                return containsPoint(x, y);
490:            }
491:
492:            /**
493:             * Add this layer's entire area to be marked for repaint. Any pending
494:             * dirty regions will be cleared and the entire layer will be painted
495:             * on the next repaint.
496:             */
497:            public void addDirtyRegion() {
498:                if (CGraphicsQ.DEBUG) {
499:                    System.err.println("Layer " + layerID() + ":");
500:                    System.err.println("\tMarking entire layer dirty");
501:                }
502:                cleanDirtyRegions();
503:                setDirty();
504:            }
505:
506:            /**
507:             * Add an area to be marked for repaint to this layer. This could
508:             * be needed for a variety of reasons, such as this layer being
509:             * obscured by another layer or window element. The new region should
510:             * be in the coordinate space of this layer.
511:             *
512:             * @param x the x coordinate of the region
513:             * @param y the y coordinate of the region
514:             * @param w the width of the region
515:             * @param h the height of the region
516:             * @return true if dirty region of the layer was changed,
517:             *         false otherwise
518:             */
519:            public boolean addDirtyRegion(int x, int y, int w, int h) {
520:                if (CGraphicsQ.DEBUG) {
521:                    System.err.println("Layer " + this  + ":");
522:                    System.err.println("\tAdd dirty: " + x + ", " + y + ", "
523:                            + w + ", " + h);
524:                }
525:
526:                // The whole layer is dirty already
527:                if (isDirty() && isEmptyDirtyRegions()) {
528:                    if (CGraphicsQ.DEBUG) {
529:                        System.err.println("\tWhole layer is dirty already");
530:                    }
531:                    return false;
532:                }
533:
534:                // Cache layer bounds
535:                int bw = bounds[W];
536:                int bh = bounds[H];
537:                int x2 = x + w;
538:                int y2 = y + h;
539:
540:                // Dirty region can be outside of the layer
541:                if (x >= bw || y >= bh || x2 <= 0 || y2 <= 0) {
542:                    if (CGraphicsQ.DEBUG) {
543:                        System.err
544:                                .println("\tAdded region is outside of the layer");
545:                    }
546:                    return false;
547:                }
548:
549:                boolean res = false;
550:                int dx, dy, dx2, dy2;
551:                if (isEmptyDirtyRegions()) {
552:                    dx = x;
553:                    dy = y;
554:                    dx2 = x2;
555:                    dy2 = y2;
556:                } else {
557:                    dx = dirtyBounds[X];
558:                    dy = dirtyBounds[Y];
559:                    dx2 = dx + dirtyBounds[W];
560:                    dy2 = dy + dirtyBounds[H];
561:                    if (dx2 < x2)
562:                        dx2 = x2;
563:                    if (dy2 < y2)
564:                        dy2 = y2;
565:                    if (x < dx)
566:                        dx = x;
567:                    if (y < dy)
568:                        dy = y;
569:                }
570:
571:                // Lastly, we carefully restrict the dirty region
572:                // to be within the bounds of this layer
573:                if (dx < 0)
574:                    dx = 0;
575:                if (dy < 0)
576:                    dy = 0;
577:                if (dx2 > bw)
578:                    dx2 = bw;
579:                if (dy2 > bh)
580:                    dy2 = bh;
581:
582:                // Update changed dirty region
583:                int dw = dx2 - dx;
584:                int dh = dy2 - dy;
585:                if (dirtyBounds[W] != dw || dirtyBounds[H] != dh) {
586:                    if (dw == bw && dh == bh) {
587:                        // The entire layer is dirty now
588:                        cleanDirtyRegions();
589:
590:                        if (CGraphicsQ.DEBUG) {
591:                            System.err
592:                                    .println("\tThe entire layer became dirty");
593:                        }
594:                    } else {
595:                        dirtyBounds[X] = dx;
596:                        dirtyBounds[Y] = dy;
597:                        dirtyBounds[W] = dw;
598:                        dirtyBounds[H] = dh;
599:
600:                        if (CGraphicsQ.DEBUG) {
601:                            System.err.println("\tCurrent dirty: "
602:                                    + dirtyBounds[X] + ", " + dirtyBounds[Y]
603:                                    + ", " + dirtyBounds[W] + ", "
604:                                    + dirtyBounds[H]);
605:                        }
606:                    }
607:                    res = true;
608:                    setDirty();
609:                }
610:
611:                return res;
612:            }
613:
614:            /**
615:             * Subtract a layer area not needed for repaint of this layer.
616:             * It could be needed for a variety of reasons, such as layer being
617:             * overlapped with opague higher layer or window element.
618:             * The subtracted region should be in the coordinate space
619:             * of this layer.
620:             *
621:             * @param x the x coordinate of the region
622:             * @param y the y coordinate of the region
623:             * @param w the width of the region
624:             * @param h the height of the region
625:             * @return true if dirty region of the layer was changed,
626:             *         false otherwise
627:             */
628:            boolean subDirtyRegion(int x, int y, int w, int h) {
629:                if (!isDirty()) {
630:                    return false;
631:                }
632:
633:                if (CGraphicsQ.DEBUG) {
634:                    System.err.println("Layer " + this  + ":");
635:                    System.err.println("\tSub dirty: " + x + ", " + y + ", "
636:                            + w + ", " + h);
637:                }
638:
639:                int x2 = x + w;
640:                int y2 = y + h;
641:                boolean res = false;
642:                int dx, dy, dx2, dy2;
643:                if (isEmptyDirtyRegions()) {
644:                    dx = 0;
645:                    dy = 0;
646:                    dx2 = bounds[W];
647:                    dy2 = bounds[H];
648:                } else {
649:                    dx = dirtyBounds[X];
650:                    dy = dirtyBounds[Y];
651:                    dx2 = dx + dirtyBounds[W];
652:                    dy2 = dy + dirtyBounds[H];
653:                }
654:
655:                // Subtracted region can be outside of the dirty area
656:                if (x >= dx2 || y >= dy2 || x2 <= dx || y2 <= dy) {
657:                    if (CGraphicsQ.DEBUG) {
658:                        System.err
659:                                .println("\tSubtracted region is outside of dirty area");
660:                    }
661:                    return false;
662:                }
663:
664:                boolean insideVert = (y <= dy && y2 >= dy2);
665:                boolean insideHorz = (x <= dx && x2 >= dx2);
666:
667:                if (insideVert) {
668:                    if (dx >= x && dx < x2)
669:                        dx = x2;
670:                    else if (dx2 > x && dx2 <= x2)
671:                        dx2 = x;
672:                } else if (insideHorz) {
673:                    if (dy >= y && dy < y2)
674:                        dy = y2;
675:                    else if (dy2 > y && dy2 <= y2)
676:                        dy2 = y;
677:                } else {
678:                    // We can subtract only such a regions that result
679:                    // of subtraction is a rectangular area
680:                    if (CGraphicsQ.DEBUG) {
681:                        System.err.println("\tSubtraction can't be done");
682:                    }
683:                    return false;
684:
685:                }
686:
687:                // Result of subtraction can be an empty dirty region
688:                if (dx >= dx2 || dy >= dy2) {
689:                    cleanDirty();
690:                    res = true;
691:
692:                    if (CGraphicsQ.DEBUG) {
693:                        System.err.println("\tThe layer is no more dirty");
694:                    }
695:
696:                } else if (dirtyBounds[W] != dx2 - dx
697:                        || dirtyBounds[H] != dy2 - dy) {
698:                    // Update changed dirty region
699:                    dirtyBounds[X] = dx;
700:                    dirtyBounds[Y] = dy;
701:                    dirtyBounds[W] = dx2 - dx;
702:                    dirtyBounds[H] = dy2 - dy;
703:                    res = true;
704:
705:                    if (CGraphicsQ.DEBUG) {
706:                        System.err.println("\tCurrent dirty: " + dirtyBounds[X]
707:                                + ", " + dirtyBounds[Y] + ", " + dirtyBounds[W]
708:                                + ", " + dirtyBounds[H]);
709:                    }
710:                } else {
711:                    if (CGraphicsQ.DEBUG) {
712:                        System.err.println("\tDirty area has not been changed");
713:                    }
714:                }
715:
716:                return res;
717:            }
718:
719:            /**
720:             * Copy bounds of the layer to use them on dirty layers painting
721:             * when the layers are not locked for changes from other threads
722:             */
723:            void copyLayerBounds() {
724:                if (dirtyBounds[X] == -1) {
725:                    // Whole layer is dirty
726:                    dirtyBoundsCopy[X] = 0;
727:                    dirtyBoundsCopy[Y] = 0;
728:                    dirtyBoundsCopy[W] = bounds[W];
729:                    dirtyBoundsCopy[H] = bounds[H];
730:                } else {
731:                    System.arraycopy(dirtyBounds, 0, dirtyBoundsCopy, 0, 4);
732:                }
733:                System.arraycopy(bounds, 0, boundsCopy, 0, 4);
734:            }
735:
736:            /**
737:             * Request a repaint for the entire contents of this layer.
738:             */
739:            public void requestRepaint() {
740:                requestRepaint(0, 0, bounds[W], bounds[H]);
741:            }
742:
743:            /**
744:             * Request a repaint for a specific region of this layer.
745:             *
746:             * @param x The 'x' coordinate of the upper left corner of the
747:             *          repaint region
748:             * @param y The 'y' coordinate of the upper right corner of the
749:             *          repaint region
750:             * @param w The width of the repaint region
751:             * @param h The height of the repaint region
752:             */
753:            public void requestRepaint(int x, int y, int w, int h) {
754:                addDirtyRegion(x, y, w, h);
755:                if (owner != null && visible) {
756:                    // We request a repaint of our parent window after translating
757:                    // the origin into the coordinate space of the window.
758:                    owner.requestRepaint();
759:                }
760:            }
761:
762:            /**
763:             * Paint this layer. This method should not generally be overridden by
764:             * subclasses. This method carefully stores the clip, translation, and
765:             * color before calling into subclasses. The graphics region will be
766:             * translated such that it is in this layer's coordinate space (0,0 is
767:             * the top left corner of this layer). The paintBackground() method will
768:             * be called first, then the paintBody() method. The graphics will then
769:             * carefully be put back into its original state before returning.
770:             * Subclasses should override the paintBody() method and do not generally 
771:             * need to do any translates or bother to undo any changes made to
772:             * the Graphics object.
773:             *
774:             * @param g The graphics object to use to paint this layer.
775:             */
776:            public void paint(Graphics g) {
777:                try {
778:                    // We first reset our dirty flag
779:                    this .dirty = false;
780:
781:                    graphicsColor = g.getColor();
782:                    graphicsFont = g.getFont();
783:
784:                    // Paint the background
785:                    if (!transparent) {
786:                        paintBackground(g);
787:                    }
788:
789:                    // Just in case subclasses modified these values,
790:                    // return them to standard
791:                    g.setColor(graphicsColor);
792:                    g.setFont(graphicsFont);
793:
794:                    // Paint the body
795:                    paintBody(g);
796:
797:                    // Just in case subclasses modified these values,
798:                    // return them to standard
799:                    g.setColor(graphicsColor);
800:                    g.setFont(graphicsFont);
801:
802:                    // We reset our dirty bounds region
803:                    cleanDirtyRegions();
804:
805:                } catch (Throwable t) {
806:                    t.printStackTrace();
807:                }
808:            }
809:
810:            /** 
811:             * Paint the background of this layer. This method will automatically
812:             * handle a transparent layer, a layer with a background color (and/or
813:             * border color), and a layer with a background image (either centered
814:             * or tiled). Subclasses may override this method if they require a
815:             * more advanced background (note that the transparent value should be
816:             * set to false in order for the paintBackground() method to be called),
817:             * but subclasses must be careful to reset any modifications made to
818:             * the Graphics object before returning.
819:             *
820:             * @param g The Graphics object to use to paint the background.
821:             */
822:            protected void paintBackground(Graphics g) {
823:                if (bgImage == null) {
824:                    // background is null, just fill using the fill color
825:                    g.setColor(bgColor);
826:                    g.fillRect(g.getClipX(), g.getClipY(), g.getClipWidth(), g
827:                            .getClipHeight());
828:                } else {
829:                    if (bgImage.length == 1) {
830:                        CGraphicsUtil.paintBackground(g, bgImage[0], tileBG,
831:                                bgColor, bounds[W], bounds[H]);
832:                    } else if (bgImage.length == 9) {
833:                        CGraphicsUtil.draw9pcsBackground(g, 0, 0, bounds[W],
834:                                bounds[H], bgImage);
835:
836:                    } else if (bgImage.length == 3) {
837:                        CGraphicsUtil.draw3pcsBackground(g, 0, 0, bounds[W],
838:                                bgImage);
839:                    }
840:                }
841:            }
842:
843:            /**
844:             * Paint the body or content of this layer. This method should be
845:             * overridden by subclasses. Note that the Graphics object will
846:             * already be translated into this layer's coordinate space. Subclasses
847:             * do not need to reset any changes made to the Graphics object as the
848:             * CLayer paint() routine will do that automatically.
849:             *
850:             * @param g The Graphics object to use to paint the content of this layer
851:             */
852:            protected void paintBody(Graphics g) {
853:            }
854:
855:            public void update(CLayer[] mainLayers) {
856:                if (visible) {
857:                    addDirtyRegion();
858:                }
859:            }
860:
861:            /**
862:             * A String identifier used by subclasses (for debug purposes)
863:             * @return abbreviated class name of the layer instance
864:             */
865:            protected String layerID() {
866:                int i;
867:                String res = getClass().getName();
868:                if (res != null && (i = res.lastIndexOf('.')) > -1) {
869:                    res = res.substring(i + 1);
870:                }
871:                return res + "@" + Integer.toHexString(hashCode());
872:            }
873:
874:            /**
875:             * Called by CWindow to notify the layer that is has been  
876:             * added to the active stack. By default this method do nothing.  
877:             * This method could be re-implemented by particular layer  to  
878:             * do some specific action as soon as it's added to the stack  
879:             */
880:            public void addNotify() {
881:            };
882:
883:            /** 
884:             * Called by CWindow to notify the layer that is has been  
885:             * removed from the active stack. By default this method do nothing.  
886:             * This method could be re-implemented by particular layer  to  
887:             * do some specific action as soon as it's removed from the stack  
888:             * @param owner an instance of CWindow this layer has been removed from  
889:             */
890:            public void removeNotify(CWindow owner) {
891:            };
892:
893:            /**
894:             * Called by CWindow to notify the layer that is has been  
895:             * moved to another location. By default this method do nothing.  
896:             * This method could be re-implemented by particular layer  to  
897:             * do some specific action as soon as it's moved
898:             * @param oldBounds original bounds of this layer before it has been moved
899:             */
900:            public void relocateNotify(int[] oldBounds) {
901:            };
902:
903:            /** 
904:             * Get the layer details including
905:             * its bound and dirty region information
906:             *
907:             * @return String with layer details
908:             */
909:            public String toString() {
910:                String res = layerID() + " [" + bounds[X] + ", " + bounds[Y]
911:                        + ", " + bounds[W] + ", " + bounds[H] + "]";
912:
913:                if (isDirty()) {
914:                    res += ", dirty";
915:                    if (!isEmptyDirtyRegions()) {
916:                        res += " (" + dirtyBounds[X] + ", " + dirtyBounds[Y]
917:                                + ", " + dirtyBounds[W] + ", " + dirtyBounds[H]
918:                                + ")";
919:                    }
920:                }
921:                res += ", opaque: " + (opaque ? 1 : 0);
922:                res += ", visible: " + (visible ? 1 : 0);
923:                res += ", transparent: " + (transparent ? 1 : 0);
924:                return res;
925:            }
926:
927:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.