1 /* DebugGraphics.java --
2    Copyright (C) 2002, 2004, 2005  Free Software Foundation, Inc.
3 
4 This file is part of GNU Classpath.
5 
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20 
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25 
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37 
38 package javax.swing;
39 
40 import java.awt.Color;
41 import java.awt.Font;
42 import java.awt.FontMetrics;
43 import java.awt.Graphics;
44 import java.awt.Image;
45 import java.awt.Point;
46 import java.awt.Rectangle;
47 import java.awt.Shape;
48 import java.awt.image.ImageObserver;
49 import java.io.PrintStream;
50 import java.text.AttributedCharacterIterator;
51 
52 
53 /**
54  * An extension of {@link Graphics} that can be used for debugging
55  * custom Swing widgets. <code>DebugGraphics</code> has the ability to
56  * draw slowly and can log drawing actions.
57  *
58  * @author Andrew Selkirk
59  */
60 public class DebugGraphics extends Graphics
61 {
62   /**
63    * LOG_OPTION
64    */
65   public static final int LOG_OPTION = 1;
66 
67   /**
68    * FLASH_OPTION
69    */
70   public static final int FLASH_OPTION = 2;
71 
72   /**
73    * BUFFERED_OPTION
74    */
75   public static final int BUFFERED_OPTION = 4;
76 
77   /**
78    * NONE_OPTION
79    */
80   public static final int NONE_OPTION = -1;
81 
82   static Color debugFlashColor = Color.RED;
83   static int debugFlashCount = 10;
84   static int debugFlashTime = 1000;
85   static PrintStream debugLogStream = System.out;
86 
87   /**
88    * Counts the created DebugGraphics objects. This is used by the
89    * logging facility.
90    */
91   static int counter = 0;
92 
93   /**
94    * graphics
95    */
96   Graphics graphics;
97 
98   /**
99    * buffer
100    */
101   Image buffer;
102 
103   /**
104    * debugOptions
105    */
106   int debugOptions;
107 
108   /**
109    * graphicsID
110    */
111   int graphicsID;
112 
113   /**
114    * xOffset
115    */
116   int xOffset;
117 
118   /**
119    * yOffset
120    */
121   int yOffset;
122 
123   /**
124    * Creates a <code>DebugGraphics</code> object.
125    */
DebugGraphics()126   public DebugGraphics()
127   {
128     counter++;
129   }
130 
131   /**
132    * Creates a <code>DebugGraphics</code> object.
133    *
134    * @param graphics The <code>Graphics</code> object to wrap
135    * @param component TODO
136    */
DebugGraphics(Graphics graphics, JComponent component)137   public DebugGraphics(Graphics graphics, JComponent component)
138   {
139     this(graphics);
140     // FIXME: What shall we do with component ?
141   }
142 
143   /**
144    * Creates a <code>DebugGraphics</code> object.
145    *
146    * @param graphics The <code>Graphics</code> object to wrap
147    */
DebugGraphics(Graphics graphics)148   public DebugGraphics(Graphics graphics)
149   {
150     this();
151     this.graphics = graphics;
152   }
153 
154   /**
155    * Sets the color to draw stuff with.
156    *
157    * @param color The color
158    */
setColor(Color color)159   public void setColor(Color color)
160   {
161     if ((debugOptions & LOG_OPTION) != 0)
162       logStream().println(prefix() + " Setting color: " + color);
163 
164     graphics.setColor(color);
165   }
166 
167   /**
168    * Creates a overrides <code>Graphics.create</code> to create a
169    * <code>DebugGraphics</code> object.
170    *
171    * @return a new <code>DebugGraphics</code> object.
172    */
create()173   public Graphics create()
174   {
175     DebugGraphics copy = new DebugGraphics(graphics.create());
176     copy.debugOptions = debugOptions;
177     return copy;
178   }
179 
180   /**
181    * Creates a overrides <code>Graphics.create</code> to create a
182    * <code>DebugGraphics</code> object.
183    *
184    * @param x the x coordinate
185    * @param y the y coordinate
186    * @param width the width
187    * @param height the height
188    *
189    * @return a new <code>DebugGraphics</code> object.
190    */
create(int x, int y, int width, int height)191   public Graphics create(int x, int y, int width, int height)
192   {
193     DebugGraphics copy = new DebugGraphics(graphics.create(x, y, width,
194                                                            height));
195     copy.debugOptions = debugOptions;
196     return copy;
197   }
198 
199   /**
200    * flashColor
201    *
202    * @return Color
203    */
flashColor()204   public static Color flashColor()
205   {
206     return debugFlashColor;
207   }
208 
209   /**
210    * setFlashColor
211    *
212    * @param color the color to use for flashing
213    */
setFlashColor(Color color)214   public static void setFlashColor(Color color)
215   {
216     debugFlashColor = color;
217   }
218 
219   /**
220    * flashTime
221    *
222    * @return The time in milliseconds
223    */
flashTime()224   public static int flashTime()
225   {
226     return debugFlashTime;
227   }
228 
229   /**
230    * setFlashTime
231    *
232    * @param time The time in milliseconds
233    */
setFlashTime(int time)234   public static void setFlashTime(int time)
235   {
236     debugFlashTime = time;
237   }
238 
239   /**
240    * flashCount
241    *
242    * @return The number of flashes
243    */
flashCount()244   public static int flashCount()
245   {
246     return debugFlashCount;
247   }
248 
249   /**
250    * setFlashCount
251    *
252    * @param count The number of flashes
253    */
setFlashCount(int count)254   public static void setFlashCount(int count)
255   {
256     debugFlashCount = count;
257   }
258 
259   /**
260    * logStream
261    *
262    * @return The <code>PrintStream</code> to write logging messages to
263    */
logStream()264   public static PrintStream logStream()
265   {
266     return debugLogStream;
267   }
268 
269   /**
270    * setLogStream
271    *
272    * @param stream The currently set <code>PrintStream</code>.
273    */
setLogStream(PrintStream stream)274   public static void setLogStream(PrintStream stream)
275   {
276     debugLogStream = stream;
277   }
278 
279   /**
280    * getFont
281    *
282    * @return The font
283    */
getFont()284   public Font getFont()
285   {
286     return graphics.getFont();
287   }
288 
289   /**
290    * setFont
291    *
292    * @param font The font to use for drawing text
293    */
setFont(Font font)294   public void setFont(Font font)
295   {
296     if ((debugOptions & LOG_OPTION) != 0)
297       logStream().println(prefix() + " Setting font: " + font);
298 
299     graphics.setFont(font);
300   }
301 
302   /**
303    * Returns the color used for drawing.
304    *
305    * @return The color.
306    */
getColor()307   public Color getColor()
308   {
309     return graphics.getColor();
310   }
311 
312   /**
313    * Returns the font metrics of the current font.
314    *
315    * @return a <code>FontMetrics</code> object
316    */
getFontMetrics()317   public FontMetrics getFontMetrics()
318   {
319     return graphics.getFontMetrics();
320   }
321 
322   /**
323    * Returns the font metrics for a given font.
324    *
325    * @param font the font to get the metrics for
326    *
327    * @return a <code>FontMetrics</code> object
328    */
getFontMetrics(Font font)329   public FontMetrics getFontMetrics(Font font)
330   {
331     return graphics.getFontMetrics(font);
332   }
333 
334   /**
335    * translate
336    *
337    * @param x the x coordinate
338    * @param y the y coordinate
339    */
translate(int x, int y)340   public void translate(int x, int y)
341   {
342     if ((debugOptions & LOG_OPTION) != 0)
343       logStream().println(prefix() + " Translating by: " + new Point(x, y));
344 
345     graphics.translate(x, y);
346   }
347 
348   /**
349    * setPaintMode
350    */
setPaintMode()351   public void setPaintMode()
352   {
353     if ((debugOptions & LOG_OPTION) != 0)
354       logStream().println(prefix() + " Setting paint mode");
355 
356     graphics.setPaintMode();
357   }
358 
359   /**
360    * setXORMode
361    *
362    * @param color the color
363    */
setXORMode(Color color)364   public void setXORMode(Color color)
365   {
366     if ((debugOptions & LOG_OPTION) != 0)
367       logStream().println(prefix() + " Setting XOR mode: " + color);
368 
369     graphics.setXORMode(color);
370   }
371 
372   /**
373    * getClipBounds
374    *
375    * @return Rectangle
376    */
getClipBounds()377   public Rectangle getClipBounds()
378   {
379     return graphics.getClipBounds();
380   }
381 
382   /**
383    * Intersects the current clip region with the given region.
384    *
385    * @param x The x-position of the region
386    * @param y The y-position of the region
387    * @param width The width of the region
388    * @param height The height of the region
389    */
clipRect(int x, int y, int width, int height)390   public void clipRect(int x, int y, int width, int height)
391   {
392     if ((debugOptions & LOG_OPTION) != 0)
393       {
394         logStream().print(prefix() + " Setting clipRect: "
395                           + new Rectangle(x, y, width, height));
396       }
397 
398     graphics.clipRect(x, y, width, height);
399 
400     if ((debugOptions & LOG_OPTION) != 0)
401       logStream().println(" Netting clipRect: " + graphics.getClipBounds());
402   }
403 
404   /**
405    * Sets the clipping region.
406    *
407    * @param x The x-position of the region
408    * @param y The y-position of the region
409    * @param width The width of the region
410    * @param height The height of the region
411    */
setClip(int x, int y, int width, int height)412   public void setClip(int x, int y, int width, int height)
413   {
414     if ((debugOptions & LOG_OPTION) != 0)
415       {
416         logStream().println(prefix() + " Setting new clipRect: "
417                             + new Rectangle(x, y, width, height));
418       }
419 
420     graphics.setClip(x, y, width, height);
421   }
422 
423   /**
424    * Returns the current clipping region.
425    *
426    * @return Shape
427    */
getClip()428   public Shape getClip()
429   {
430     return graphics.getClip();
431   }
432 
433   /**
434    * Sets the current clipping region
435    *
436    * @param shape The clippin region
437    */
setClip(Shape shape)438   public void setClip(Shape shape)
439   {
440     if ((debugOptions & LOG_OPTION) != 0)
441       logStream().println(prefix() + " Setting new clipRect: " + shape);
442 
443     graphics.setClip(shape);
444   }
445 
sleep(int milliseconds)446   private void sleep(int milliseconds)
447   {
448     try
449       {
450         Thread.sleep(milliseconds);
451       }
452     catch (InterruptedException e)
453       {
454         // Ignore this.
455       }
456   }
457 
458   /**
459    * Draws a rectangle.
460    *
461    * @param x The x-position of the rectangle
462    * @param y The y-position of the rectangle
463    * @param width The width of the rectangle
464    * @param height The height of the rectangle
465    */
drawRect(int x, int y, int width, int height)466   public void drawRect(int x, int y, int width, int height)
467   {
468     if ((debugOptions & LOG_OPTION) != 0)
469       {
470         logStream().println(prefix() + " Drawing rect: "
471                             + new Rectangle(x, y, width, height));
472       }
473 
474     if ((debugOptions & FLASH_OPTION) != 0)
475       {
476         Color color = graphics.getColor();
477         for (int index = 0; index < (debugFlashCount - 1); ++index)
478           {
479             graphics.setColor(color);
480             graphics.drawRect(x, y, width, height);
481             sleep(debugFlashTime);
482             graphics.setColor(debugFlashColor);
483             graphics.drawRect(x, y, width, height);
484             sleep(debugFlashTime);
485           }
486         graphics.setColor(color);
487       }
488 
489     graphics.drawRect(x, y, width, height);
490   }
491 
492   /**
493    * Draws a filled rectangle.
494    *
495    * @param x The x-position of the rectangle
496    * @param y The y-position of the rectangle
497    * @param width The width of the rectangle
498    * @param height The height of the rectangle
499    */
fillRect(int x, int y, int width, int height)500   public void fillRect(int x, int y, int width, int height)
501   {
502     if ((debugOptions & LOG_OPTION) != 0)
503       {
504         logStream().println(prefix() + " Filling rect: "
505                             + new Rectangle(x, y, width, height));
506       }
507 
508     if ((debugOptions & FLASH_OPTION) != 0)
509       {
510         Color color = graphics.getColor();
511         for (int index = 0; index < (debugFlashCount - 1); ++index)
512           {
513             graphics.setColor(color);
514             graphics.fillRect(x, y, width, height);
515             sleep(debugFlashTime);
516             graphics.setColor(debugFlashColor);
517             graphics.fillRect(x, y, width, height);
518             sleep(debugFlashTime);
519           }
520         graphics.setColor(color);
521       }
522 
523     graphics.fillRect(x, y, width, height);
524   }
525 
526   /**
527    * clearRect
528    *
529    * @param x The x-position of the rectangle
530    * @param y The y-position of the rectangle
531    * @param width The width of the rectangle
532    * @param height The height of the rectangle
533    */
clearRect(int x, int y, int width, int height)534   public void clearRect(int x, int y, int width, int height)
535   {
536     if ((debugOptions & LOG_OPTION) != 0)
537       {
538         logStream().println(prefix() + " Clearing rect: "
539                             + new Rectangle(x, y, width, height));
540       }
541 
542     graphics.clearRect(x, y, width, height);
543   }
544 
545   /**
546    * drawRoundRect
547    *
548    * @param x The x-position of the rectangle
549    * @param y The y-position of the rectangle
550    * @param width The width of the rectangle
551    * @param height The height of the rectangle
552    * @param arcWidth TODO
553    * @param arcHeight TODO
554    */
drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)555   public void drawRoundRect(int x, int y, int width, int height,
556                             int arcWidth, int arcHeight)
557   {
558     if ((debugOptions & LOG_OPTION) != 0)
559       {
560         logStream().println(prefix() + " Drawing round rect: "
561                             + new Rectangle(x, y, width, height)
562                             + " arcWidth: " + arcWidth
563                             + " arcHeight: " + arcHeight);
564       }
565 
566     graphics.drawRoundRect(x, y, width, height, arcWidth, arcHeight);
567   }
568 
569   /**
570    * fillRoundRect
571    *
572    * @param x The x-position of the rectangle
573    * @param y The y-position of the rectangle
574    * @param width The width of the rectangle
575    * @param height The height of the rectangle
576    * @param arcWidth TODO
577    * @param arcHeight TODO
578    */
fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)579   public void fillRoundRect(int x, int y, int width, int height,
580                             int arcWidth, int arcHeight)
581   {
582     if ((debugOptions & LOG_OPTION) != 0)
583       {
584         logStream().println(prefix() + " Filling round rect: "
585                             + new Rectangle(x, y, width, height)
586                             + " arcWidth: " + arcWidth
587                             + " arcHeight: " + arcHeight);
588       }
589 
590     graphics.fillRoundRect(x, y, width, height, arcWidth, arcHeight);
591   }
592 
593   /**
594    * drawLine
595    *
596    * @param x1 The x-position of the start
597    * @param y1 The y-position of the start
598    * @param x2 The x-position of the end
599    * @param y2 The y-position of the end
600    */
drawLine(int x1, int y1, int x2, int y2)601   public void drawLine(int x1, int y1, int x2, int y2)
602   {
603     if ((debugOptions & LOG_OPTION) != 0)
604       {
605         logStream().println(prefix() + " Drawing line: from (" + x1 + ", "
606                             + y1 + ") to (" + x2 + ", " + y2 + ")");
607       }
608 
609     graphics.drawLine(x1, y1, x2, y2);
610   }
611 
612   /**
613    * draw3DRect
614    *
615    * @param x The x-position of the rectangle
616    * @param y The y-position of the rectangle
617    * @param width The width of the rectangle
618    * @param height The height of the rectangle
619    * @param raised TODO
620    */
draw3DRect(int x, int y, int width, int height, boolean raised)621   public void draw3DRect(int x, int y, int width, int height, boolean raised)
622   {
623     if ((debugOptions & LOG_OPTION) != 0)
624       {
625         logStream().println(prefix() + " Drawing 3D rect: "
626                             + new Rectangle(x, y, width, height)
627                             + "Raised bezel: " + raised);
628       }
629 
630     graphics.draw3DRect(x, y, width, height, raised);
631   }
632 
633   /**
634    * fill3DRect
635    *
636    * @param x The x-position of the rectangle
637    * @param y The y-position of the rectangle
638    * @param width The width of the rectangle
639    * @param height The height of the rectangle
640    * @param raised TODO
641    */
fill3DRect(int x, int y, int width, int height, boolean raised)642   public void fill3DRect(int x, int y, int width, int height, boolean raised)
643   {
644     if ((debugOptions & LOG_OPTION) != 0)
645       {
646         logStream().println(prefix() + " Filling 3D rect: "
647                             + new Rectangle(x, y, width, height)
648                             + "Raised bezel: " + raised);
649       }
650 
651     graphics.fill3DRect(x, y, width, height, raised);
652   }
653 
654   /**
655    * drawOval
656    *
657    * @param x the x coordinate
658    * @param y the y coordiante
659    * @param width the width
660    * @param height the height
661    */
drawOval(int x, int y, int width, int height)662   public void drawOval(int x, int y, int width, int height)
663   {
664     if ((debugOptions & LOG_OPTION) != 0)
665       {
666         logStream().println(prefix() + " Drawing oval: "
667                             + new Rectangle(x, y, width, height));
668       }
669 
670     graphics.drawOval(x, y, width, height);
671   }
672 
673   /**
674    * fillOval
675    *
676    * @param x the x coordinate
677    * @param y the y coordinate
678    * @param width the width
679    * @param height the height
680    */
fillOval(int x, int y, int width, int height)681   public void fillOval(int x, int y, int width, int height)
682   {
683     if ((debugOptions & LOG_OPTION) != 0)
684       {
685         logStream().println(prefix() + " Filling oval: "
686                             + new Rectangle(x, y, width, height));
687       }
688 
689     graphics.fillOval(x, y, width, height);
690   }
691 
692   /**
693    * drawArc
694    *
695    * @param x the x coordinate
696    * @param y the y coordinate
697    * @param width the width
698    * @param height the height
699    * @param startAngle TODO
700    * @param arcAngle TODO
701    */
drawArc(int x, int y, int width, int height, int startAngle, int arcAngle)702   public void drawArc(int x, int y, int width, int height,
703                       int startAngle, int arcAngle)
704   {
705     if ((debugOptions & LOG_OPTION) != 0)
706       {
707         logStream().println(prefix() + " Drawing arc: "
708                             + new Rectangle(x, y, width, height)
709                             + " startAngle: " + startAngle
710                             + " arcAngle: " + arcAngle);
711       }
712 
713     graphics.drawArc(x, y, width, height, startAngle, arcAngle);
714   }
715 
716   /**
717    * fillArc
718    *
719    * @param x the coordinate
720    * @param y the y coordinate
721    * @param width the width
722    * @param height the height
723    * @param startAngle TODO
724    * @param arcAngle TODO
725    */
fillArc(int x, int y, int width, int height, int startAngle, int arcAngle)726   public void fillArc(int x, int y, int width, int height,
727                       int startAngle, int arcAngle)
728   {
729     if ((debugOptions & LOG_OPTION) != 0)
730       {
731         logStream().println(prefix() + " Filling arc: "
732                             + new Rectangle(x, y, width, height)
733                             + " startAngle: " + startAngle
734                             + " arcAngle: " + arcAngle);
735       }
736 
737     graphics.fillArc(x, y, width, height, startAngle, arcAngle);
738   }
739 
740   /**
741    * drawPolyline
742    *
743    * @param xpoints TODO
744    * @param ypoints TODO
745    * @param npoints TODO
746    */
drawPolyline(int[] xpoints, int[] ypoints, int npoints)747   public void drawPolyline(int[] xpoints, int[] ypoints, int npoints)
748   {
749     if ((debugOptions & LOG_OPTION) != 0)
750       {
751         logStream().println(prefix() + " Drawing polyline: nPoints: " + npoints
752                             + " X's: " + xpoints + " Y's: " + ypoints);
753       }
754 
755     graphics.drawPolyline(xpoints, ypoints, npoints);
756   }
757 
758   /**
759    * drawPolygon
760    *
761    * @param xpoints TODO
762    * @param ypoints TODO
763    * @param npoints TODO
764    */
drawPolygon(int[] xpoints, int[] ypoints, int npoints)765   public void drawPolygon(int[] xpoints, int[] ypoints, int npoints)
766   {
767     if ((debugOptions & LOG_OPTION) != 0)
768       {
769         logStream().println(prefix() + " Drawing polygon: nPoints: " + npoints
770                             + " X's: " + xpoints + " Y's: " + ypoints);
771       }
772 
773     graphics.drawPolygon(xpoints, ypoints, npoints);
774   }
775 
776   /**
777    * fillPolygon
778    *
779    * @param xpoints TODO
780    * @param ypoints TODO
781    * @param npoints TODO
782    */
fillPolygon(int[] xpoints, int[] ypoints, int npoints)783   public void fillPolygon(int[] xpoints, int[] ypoints, int npoints)
784   {
785     if ((debugOptions & LOG_OPTION) != 0)
786       {
787         logStream().println(prefix() + " Drawing polygon: nPoints: " + npoints
788                             + " X's: " + xpoints + " Y's: " + ypoints);
789       }
790 
791     graphics.fillPolygon(xpoints, ypoints, npoints);
792   }
793 
794   /**
795    * drawString
796    *
797    * @param string the string
798    * @param x the x coordinate
799    * @param y the y coordinate
800    */
drawString(String string, int x, int y)801   public void drawString(String string, int x, int y)
802   {
803     if ((debugOptions & LOG_OPTION) != 0)
804       {
805         logStream().println(prefix() + " Drawing string: \"" + string
806                             + "\" at: " + new Point(x, y));
807       }
808 
809     graphics.drawString(string, x, y);
810   }
811 
812   /**
813    * drawString
814    *
815    * @param iterator TODO
816    * @param x the x coordinate
817    * @param y the y coordinate
818    */
drawString(AttributedCharacterIterator iterator, int x, int y)819   public void drawString(AttributedCharacterIterator iterator,
820                          int x, int y)
821   {
822     if ((debugOptions & LOG_OPTION) != 0)
823       {
824         logStream().println(prefix() + " Drawing string: \"" + iterator
825                             + "\" at: " + new Point(x, y));
826       }
827 
828     graphics.drawString(iterator, x, y);
829   }
830 
831   /**
832    * drawBytes
833    *
834    * @param data TODO
835    * @param offset TODO
836    * @param length TODO
837    * @param x the x coordinate
838    * @param y the y coordinate
839    */
drawBytes(byte[] data, int offset, int length, int x, int y)840   public void drawBytes(byte[] data, int offset, int length,
841                         int x, int y)
842   {
843     if ((debugOptions & LOG_OPTION) != 0)
844       logStream().println(prefix() + " Drawing bytes at: " + new Point(x, y));
845 
846     graphics.drawBytes(data, offset, length, x, y);
847   }
848 
849   /**
850    * drawChars
851    *
852    * @param data array of characters to draw
853    * @param offset offset in array
854    * @param length number of characters in array to draw
855    * @param x x-position
856    * @param y y-position
857    */
drawChars(char[] data, int offset, int length, int x, int y)858   public void drawChars(char[] data, int offset, int length,
859                         int x, int y)
860   {
861     if ((debugOptions & LOG_OPTION) != 0)
862       logStream().println(prefix() + " Drawing chars at: " + new Point(x, y));
863 
864     if ((debugOptions & FLASH_OPTION) != 0)
865       {
866         Color color = graphics.getColor();
867         for (int index = 0; index < (debugFlashCount - 1); ++index)
868           {
869             graphics.setColor(color);
870             graphics.drawChars(data, offset, length, x, y);
871             sleep(debugFlashTime);
872             graphics.setColor(debugFlashColor);
873             graphics.drawChars(data, offset, length, x, y);
874             sleep(debugFlashTime);
875           }
876         graphics.setColor(color);
877       }
878 
879     graphics.drawChars(data, offset, length, x, y);
880   }
881 
882   /**
883    * drawImage
884    *
885    * @param image The image to draw
886    * @param x The x position
887    * @param y The y position
888    * @param observer The image observer
889    * @return boolean
890    */
drawImage(Image image, int x, int y, ImageObserver observer)891   public boolean drawImage(Image image, int x, int y,
892                            ImageObserver observer)
893   {
894     if ((debugOptions & LOG_OPTION) != 0)
895       {
896         logStream().println(prefix() + " Drawing image: " + image + " at: "
897                           + new Point(x, y));
898       }
899 
900     return graphics.drawImage(image, x, y, observer);
901   }
902 
903   /**
904    * drawImage
905    *
906    * @param image The image to draw
907    * @param x The x position
908    * @param y The y position
909    * @param width The width of the area to draw the image
910    * @param height The height of the area to draw the image
911    * @param observer The image observer
912    *
913    * @return boolean
914    */
drawImage(Image image, int x, int y, int width, int height, ImageObserver observer)915   public boolean drawImage(Image image, int x, int y, int width,
916                            int height, ImageObserver observer)
917   {
918     if ((debugOptions & LOG_OPTION) != 0)
919       {
920         logStream().println(prefix() + " Drawing image: " + image
921                             + " at: " + new Rectangle(x, y, width, height));
922       }
923 
924     return graphics.drawImage(image, x, y, width, height, observer);
925   }
926 
927   /**
928    * drawImage
929    *
930    * @param image The image to draw
931    * @param x The x position
932    * @param y The y position
933    * @param background The color for the background in the opaque regions
934    * of the image
935    * @param observer The image observer
936    *
937    * @return boolean
938    */
drawImage(Image image, int x, int y, Color background, ImageObserver observer)939   public boolean drawImage(Image image, int x, int y,
940                            Color background, ImageObserver observer)
941   {
942     if ((debugOptions & LOG_OPTION) != 0)
943       {
944         logStream().println(prefix() + " Drawing image: " + image
945                             + " at: " + new Point(x, y)
946                             + ", bgcolor: " + background);
947       }
948 
949     return graphics.drawImage(image, x, y, background, observer);
950   }
951 
952   /**
953    * drawImage
954    *
955    * @param image The image to draw
956    * @param x The x position
957    * @param y The y position
958    * @param width The width of the area to draw the image
959    * @param height The height of the area to draw the image
960    * @param background The color for the background in the opaque regions
961    * of the image
962    * @param observer The image observer
963    *
964    * @return boolean
965    */
drawImage(Image image, int x, int y, int width, int height, Color background, ImageObserver observer)966   public boolean drawImage(Image image, int x, int y, int width, int height,
967                            Color background, ImageObserver observer)
968   {
969     if ((debugOptions & LOG_OPTION) != 0)
970       {
971         logStream().println(prefix() + " Drawing image: " + image
972                             + " at: " + new Rectangle(x, y, width, height)
973                             + ", bgcolor: " + background);
974       }
975 
976     return graphics.drawImage(image, x, y, width, height, background, observer);
977   }
978 
979   /**
980    * drawImage
981    *
982    * @param image The image to draw
983    * @param dx1 TODO
984    * @param dy1 TODO
985    * @param dx2 TODO
986    * @param dy2 TODO
987    * @param sx1 TODO
988    * @param sy1 TODO
989    * @param sx2 TODO
990    * @param sy2 TODO
991    * @param observer The image observer
992    *
993    * @return boolean
994    */
drawImage(Image image, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer)995   public boolean drawImage(Image image, int dx1, int dy1,
996                            int dx2, int dy2, int sx1, int sy1, int sx2, int sy2,
997                            ImageObserver observer)
998   {
999     if ((debugOptions & LOG_OPTION) != 0)
1000       {
1001         logStream().println(prefix() + " Drawing image: " + image
1002                          + " destination: " + new Rectangle(dx1, dy1, dx2, dy2)
1003                          + " source: " + new Rectangle(sx1, sy1, sx2, sy2));
1004       }
1005 
1006     return graphics.drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, observer);
1007   }
1008 
1009   /**
1010    * drawImage
1011    *
1012    * @param image The image to draw
1013    * @param dx1 TODO
1014    * @param dy1 TODO
1015    * @param dx2 TODO
1016    * @param dy2 TODO
1017    * @param sx1 TODO
1018    * @param sy1 TODO
1019    * @param sx2 TODO
1020    * @param sy2 TODO
1021    * @param background The color for the background in the opaque regions
1022    * of the image
1023    * @param observer The image observer
1024    *
1025    * @return boolean
1026    */
drawImage(Image image, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, Color background, ImageObserver observer)1027   public boolean drawImage(Image image, int dx1, int dy1,
1028                            int dx2, int dy2, int sx1, int sy1, int sx2, int sy2,
1029                            Color background, ImageObserver observer)
1030   {
1031     if ((debugOptions & LOG_OPTION) != 0)
1032       {
1033         logStream().println(prefix() + " Drawing image: " + image
1034                          + " destination: " + new Rectangle(dx1, dy1, dx2, dy2)
1035                          + " source: " + new Rectangle(sx1, sy1, sx2, sy2)
1036                          + ", bgcolor: " + background);
1037       }
1038 
1039     return graphics.drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, background, observer);
1040   }
1041 
1042   /**
1043    * copyArea
1044    *
1045    * @param x The x position of the source area
1046    * @param y The y position of the source area
1047    * @param width The width of the area
1048    * @param height The height of the area
1049    * @param destx The x position of the destination area
1050    * @param desty The y posiiton of the destination area
1051    */
copyArea(int x, int y, int width, int height, int destx, int desty)1052   public void copyArea(int x, int y, int width, int height,
1053                        int destx, int desty)
1054   {
1055     if ((debugOptions & LOG_OPTION) != 0)
1056       {
1057         logStream().println(prefix() + " Copying area from: "
1058                             +  new Rectangle(x, y, width, height)
1059                             + " to: " + new Point(destx, desty));
1060       }
1061 
1062     graphics.copyArea(x, y, width, height, destx, desty);
1063   }
1064 
1065   /**
1066    * Releases all system resources that this <code>Graphics</code> is using.
1067    */
dispose()1068   public void dispose()
1069   {
1070     graphics.dispose();
1071     graphics = null;
1072   }
1073 
1074   /**
1075    * isDrawingBuffer
1076    *
1077    * @return boolean
1078    */
isDrawingBuffer()1079   public boolean isDrawingBuffer()
1080   {
1081     return false; // TODO
1082   }
1083 
1084   /**
1085    * setDebugOptions
1086    *
1087    * @param options the debug options
1088    */
setDebugOptions(int options)1089   public void setDebugOptions(int options)
1090   {
1091     debugOptions = options;
1092     if ((debugOptions & LOG_OPTION) != 0)
1093       if (options == NONE_OPTION)
1094         logStream().println(prefix() + "Disabling debug");
1095       else
1096         logStream().println(prefix() + "Enabling debug");
1097   }
1098 
1099   /**
1100    * getDebugOptions
1101    *
1102    * @return the debug options
1103    */
getDebugOptions()1104   public int getDebugOptions()
1105   {
1106     return debugOptions;
1107   }
1108 
1109   /**
1110    * Creates and returns the prefix that should be prepended to all logging
1111    * messages. The prefix is made up like this:
1112    *
1113    * <code>Graphics(<counter>-1)</code> where counter is an integer number
1114    * saying how many DebugGraphics objects have been created so far. The second
1115    * number always seem to be 1 on Sun's JDK, this has to be investigated a
1116    * little more.
1117    *
1118    * @return the prefix that should be prepended to all logging
1119    *         messages
1120    */
prefix()1121   private String prefix()
1122   {
1123     return "Graphics(" + counter + "-1)";
1124   }
1125 }
1126