View Javadoc
1   /*
2    * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  package javax.swing;
27  
28  import java.awt.*;
29  import java.awt.image.*;
30  import java.text.AttributedCharacterIterator;
31  
32  /**
33   * Graphics subclass supporting graphics debugging. Overrides most methods
34   * from Graphics.  DebugGraphics objects are rarely created by hand.  They
35   * are most frequently created automatically when a JComponent's
36   * debugGraphicsOptions are changed using the setDebugGraphicsOptions()
37   * method.
38   * <p>
39   * NOTE: You must turn off double buffering to use DebugGraphics:
40   *       RepaintManager repaintManager = RepaintManager.currentManager(component);
41   *       repaintManager.setDoubleBufferingEnabled(false);
42   *
43   * @see JComponent#setDebugGraphicsOptions
44   * @see RepaintManager#currentManager
45   * @see RepaintManager#setDoubleBufferingEnabled
46   *
47   * @author Dave Karlton
48   */
49  public class DebugGraphics extends Graphics {
50      Graphics                    graphics;
51      Image                       buffer;
52      int                         debugOptions;
53      int                         graphicsID = graphicsCount++;
54      int                         xOffset, yOffset;
55      private static int          graphicsCount = 0;
56      private static ImageIcon    imageLoadingIcon = new ImageIcon();
57  
58      /** Log graphics operations. */
59      public static final int     LOG_OPTION   = 1 << 0;
60      /** Flash graphics operations. */
61      public static final int     FLASH_OPTION = 1 << 1;
62      /** Show buffered operations in a separate <code>Frame</code>. */
63      public static final int     BUFFERED_OPTION = 1 << 2;
64      /** Don't debug graphics operations. */
65      public static final int     NONE_OPTION = -1;
66  
67      static {
68          JComponent.DEBUG_GRAPHICS_LOADED = true;
69      }
70  
71      /**
72       * Constructs a new debug graphics context that supports slowed
73       * down drawing.
74       */
75      public DebugGraphics() {
76          super();
77          buffer = null;
78          xOffset = yOffset = 0;
79      }
80  
81      /**
82       * Constructs a debug graphics context from an existing graphics
83       * context that slows down drawing for the specified component.
84       *
85       * @param graphics  the Graphics context to slow down
86       * @param component the JComponent to draw slowly
87       */
88      public DebugGraphics(Graphics graphics, JComponent component) {
89          this(graphics);
90          setDebugOptions(component.shouldDebugGraphics());
91      }
92  
93      /**
94       * Constructs a debug graphics context from an existing graphics
95       * context that supports slowed down drawing.
96       *
97       * @param graphics  the Graphics context to slow down
98       */
99      public DebugGraphics(Graphics graphics) {
100         this();
101         this.graphics = graphics;
102     }
103 
104     /**
105      * Overrides <code>Graphics.create</code> to return a DebugGraphics object.
106      */
107     public Graphics create() {
108         DebugGraphics debugGraphics;
109 
110         debugGraphics = new DebugGraphics();
111         debugGraphics.graphics = graphics.create();
112         debugGraphics.debugOptions = debugOptions;
113         debugGraphics.buffer = buffer;
114 
115         return debugGraphics;
116     }
117 
118     /**
119      * Overrides <code>Graphics.create</code> to return a DebugGraphics object.
120      */
121     public Graphics create(int x, int y, int width, int height) {
122         DebugGraphics debugGraphics;
123 
124         debugGraphics = new DebugGraphics();
125         debugGraphics.graphics = graphics.create(x, y, width, height);
126         debugGraphics.debugOptions = debugOptions;
127         debugGraphics.buffer = buffer;
128         debugGraphics.xOffset = xOffset + x;
129         debugGraphics.yOffset = yOffset + y;
130 
131         return debugGraphics;
132     }
133 
134 
135     //------------------------------------------------
136     //  NEW METHODS
137     //------------------------------------------------
138 
139     /**
140      * Sets the Color used to flash drawing operations.
141      */
142     public static void setFlashColor(Color flashColor) {
143         info().flashColor = flashColor;
144     }
145 
146     /**
147      * Returns the Color used to flash drawing operations.
148      * @see #setFlashColor
149      */
150     public static Color flashColor() {
151         return info().flashColor;
152     }
153 
154     /**
155      * Sets the time delay of drawing operation flashing.
156      */
157     public static void setFlashTime(int flashTime) {
158         info().flashTime = flashTime;
159     }
160 
161     /**
162      * Returns the time delay of drawing operation flashing.
163      * @see #setFlashTime
164      */
165     public static int flashTime() {
166         return info().flashTime;
167     }
168 
169     /**
170      * Sets the number of times that drawing operations will flash.
171      */
172     public static void setFlashCount(int flashCount) {
173         info().flashCount = flashCount;
174     }
175 
176     /** Returns the number of times that drawing operations will flash.
177       * @see #setFlashCount
178       */
179     public static int flashCount() {
180         return info().flashCount;
181     }
182 
183     /** Sets the stream to which the DebugGraphics logs drawing operations.
184       */
185     public static void setLogStream(java.io.PrintStream stream) {
186         info().stream = stream;
187     }
188 
189     /** Returns the stream to which the DebugGraphics logs drawing operations.
190       * @see #setLogStream
191       */
192     public static java.io.PrintStream logStream() {
193         return info().stream;
194     }
195 
196     /** Sets the Font used for text drawing operations.
197       */
198     public void setFont(Font aFont) {
199         if (debugLog()) {
200             info().log(toShortString() + " Setting font: " + aFont);
201         }
202         graphics.setFont(aFont);
203     }
204 
205     /** Returns the Font used for text drawing operations.
206       * @see #setFont
207       */
208     public Font getFont() {
209         return graphics.getFont();
210     }
211 
212     /** Sets the color to be used for drawing and filling lines and shapes.
213       */
214     public void setColor(Color aColor) {
215         if (debugLog()) {
216             info().log(toShortString() + " Setting color: " + aColor);
217         }
218         graphics.setColor(aColor);
219     }
220 
221     /** Returns the Color used for text drawing operations.
222       * @see #setColor
223       */
224     public Color getColor() {
225         return graphics.getColor();
226     }
227 
228 
229     //-----------------------------------------------
230     // OVERRIDDEN METHODS
231     //------------------------------------------------
232 
233     /**
234      * Overrides <code>Graphics.getFontMetrics</code>.
235      */
236     public FontMetrics getFontMetrics() {
237         return graphics.getFontMetrics();
238     }
239 
240     /**
241      * Overrides <code>Graphics.getFontMetrics</code>.
242      */
243     public FontMetrics getFontMetrics(Font f) {
244         return graphics.getFontMetrics(f);
245     }
246 
247     /**
248      * Overrides <code>Graphics.translate</code>.
249      */
250     public void translate(int x, int y) {
251         if (debugLog()) {
252             info().log(toShortString() +
253                 " Translating by: " + new Point(x, y));
254         }
255         xOffset += x;
256         yOffset += y;
257         graphics.translate(x, y);
258     }
259 
260     /**
261      * Overrides <code>Graphics.setPaintMode</code>.
262      */
263     public void setPaintMode() {
264         if (debugLog()) {
265             info().log(toShortString() + " Setting paint mode");
266         }
267         graphics.setPaintMode();
268     }
269 
270     /**
271      * Overrides <code>Graphics.setXORMode</code>.
272      */
273     public void setXORMode(Color aColor) {
274         if (debugLog()) {
275             info().log(toShortString() + " Setting XOR mode: " + aColor);
276         }
277         graphics.setXORMode(aColor);
278     }
279 
280     /**
281      * Overrides <code>Graphics.getClipBounds</code>.
282      */
283     public Rectangle getClipBounds() {
284         return graphics.getClipBounds();
285     }
286 
287     /**
288      * Overrides <code>Graphics.clipRect</code>.
289      */
290     public void clipRect(int x, int y, int width, int height) {
291         graphics.clipRect(x, y, width, height);
292         if (debugLog()) {
293             info().log(toShortString() +
294                 " Setting clipRect: " + (new Rectangle(x, y, width, height)) +
295                 " New clipRect: " + graphics.getClip());
296         }
297     }
298 
299     /**
300      * Overrides <code>Graphics.setClip</code>.
301      */
302     public void setClip(int x, int y, int width, int height) {
303         graphics.setClip(x, y, width, height);
304         if (debugLog()) {
305             info().log(toShortString() +
306                         " Setting new clipRect: " + graphics.getClip());
307         }
308     }
309 
310     /**
311      * Overrides <code>Graphics.getClip</code>.
312      */
313     public Shape getClip() {
314         return graphics.getClip();
315     }
316 
317     /**
318      * Overrides <code>Graphics.setClip</code>.
319      */
320     public void setClip(Shape clip) {
321         graphics.setClip(clip);
322         if (debugLog()) {
323             info().log(toShortString() +
324                        " Setting new clipRect: " +  graphics.getClip());
325         }
326     }
327 
328     /**
329      * Overrides <code>Graphics.drawRect</code>.
330      */
331     public void drawRect(int x, int y, int width, int height) {
332         DebugGraphicsInfo info = info();
333 
334         if (debugLog()) {
335             info().log(toShortString() +
336                       " Drawing rect: " +
337                       new Rectangle(x, y, width, height));
338         }
339 
340         if (isDrawingBuffer()) {
341             if (debugBuffered()) {
342                 Graphics debugGraphics = debugGraphics();
343 
344                 debugGraphics.drawRect(x, y, width, height);
345                 debugGraphics.dispose();
346             }
347         } else if (debugFlash()) {
348             Color oldColor = getColor();
349             int i, count = (info.flashCount * 2) - 1;
350 
351             for (i = 0; i < count; i++) {
352                 graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);
353                 graphics.drawRect(x, y, width, height);
354                 Toolkit.getDefaultToolkit().sync();
355                 sleep(info.flashTime);
356             }
357             graphics.setColor(oldColor);
358         }
359         graphics.drawRect(x, y, width, height);
360     }
361 
362     /**
363      * Overrides <code>Graphics.fillRect</code>.
364      */
365     public void fillRect(int x, int y, int width, int height) {
366         DebugGraphicsInfo info = info();
367 
368         if (debugLog()) {
369             info().log(toShortString() +
370                       " Filling rect: " +
371                       new Rectangle(x, y, width, height));
372         }
373 
374         if (isDrawingBuffer()) {
375             if (debugBuffered()) {
376                 Graphics debugGraphics = debugGraphics();
377 
378                 debugGraphics.fillRect(x, y, width, height);
379                 debugGraphics.dispose();
380             }
381         } else if (debugFlash()) {
382             Color oldColor = getColor();
383             int i, count = (info.flashCount * 2) - 1;
384 
385             for (i = 0; i < count; i++) {
386                 graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);
387                 graphics.fillRect(x, y, width, height);
388                 Toolkit.getDefaultToolkit().sync();
389                 sleep(info.flashTime);
390             }
391             graphics.setColor(oldColor);
392         }
393         graphics.fillRect(x, y, width, height);
394     }
395 
396     /**
397      * Overrides <code>Graphics.clearRect</code>.
398      */
399     public void clearRect(int x, int y, int width, int height) {
400         DebugGraphicsInfo info = info();
401 
402         if (debugLog()) {
403             info().log(toShortString() +
404                       " Clearing rect: " +
405                       new Rectangle(x, y, width, height));
406         }
407 
408         if (isDrawingBuffer()) {
409             if (debugBuffered()) {
410                 Graphics debugGraphics = debugGraphics();
411 
412                 debugGraphics.clearRect(x, y, width, height);
413                 debugGraphics.dispose();
414             }
415         } else if (debugFlash()) {
416             Color oldColor = getColor();
417             int i, count = (info.flashCount * 2) - 1;
418 
419             for (i = 0; i < count; i++) {
420                 graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);
421                 graphics.clearRect(x, y, width, height);
422                 Toolkit.getDefaultToolkit().sync();
423                 sleep(info.flashTime);
424             }
425             graphics.setColor(oldColor);
426         }
427         graphics.clearRect(x, y, width, height);
428     }
429 
430     /**
431      * Overrides <code>Graphics.drawRoundRect</code>.
432      */
433     public void drawRoundRect(int x, int y, int width, int height,
434                               int arcWidth, int arcHeight) {
435         DebugGraphicsInfo info = info();
436 
437         if (debugLog()) {
438             info().log(toShortString() +
439                       " Drawing round rect: " +
440                       new Rectangle(x, y, width, height) +
441                       " arcWidth: " + arcWidth +
442                       " archHeight: " + arcHeight);
443         }
444         if (isDrawingBuffer()) {
445             if (debugBuffered()) {
446                 Graphics debugGraphics = debugGraphics();
447 
448                 debugGraphics.drawRoundRect(x, y, width, height,
449                                             arcWidth, arcHeight);
450                 debugGraphics.dispose();
451             }
452         } else if (debugFlash()) {
453             Color oldColor = getColor();
454             int i, count = (info.flashCount * 2) - 1;
455 
456             for (i = 0; i < count; i++) {
457                 graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);
458                 graphics.drawRoundRect(x, y, width, height,
459                                        arcWidth, arcHeight);
460                 Toolkit.getDefaultToolkit().sync();
461                 sleep(info.flashTime);
462             }
463             graphics.setColor(oldColor);
464         }
465         graphics.drawRoundRect(x, y, width, height, arcWidth, arcHeight);
466     }
467 
468     /**
469      * Overrides <code>Graphics.fillRoundRect</code>.
470      */
471     public void fillRoundRect(int x, int y, int width, int height,
472                               int arcWidth, int arcHeight) {
473         DebugGraphicsInfo info = info();
474 
475         if (debugLog()) {
476             info().log(toShortString() +
477                       " Filling round rect: " +
478                       new Rectangle(x, y, width, height) +
479                       " arcWidth: " + arcWidth +
480                       " archHeight: " + arcHeight);
481         }
482         if (isDrawingBuffer()) {
483             if (debugBuffered()) {
484                 Graphics debugGraphics = debugGraphics();
485 
486                 debugGraphics.fillRoundRect(x, y, width, height,
487                                             arcWidth, arcHeight);
488                 debugGraphics.dispose();
489             }
490         } else if (debugFlash()) {
491             Color oldColor = getColor();
492             int i, count = (info.flashCount * 2) - 1;
493 
494             for (i = 0; i < count; i++) {
495                 graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);
496                 graphics.fillRoundRect(x, y, width, height,
497                                        arcWidth, arcHeight);
498                 Toolkit.getDefaultToolkit().sync();
499                 sleep(info.flashTime);
500             }
501             graphics.setColor(oldColor);
502         }
503         graphics.fillRoundRect(x, y, width, height, arcWidth, arcHeight);
504     }
505 
506     /**
507      * Overrides <code>Graphics.drawLine</code>.
508      */
509     public void drawLine(int x1, int y1, int x2, int y2) {
510         DebugGraphicsInfo info = info();
511 
512         if (debugLog()) {
513             info().log(toShortString() +
514                        " Drawing line: from " + pointToString(x1, y1) +
515                        " to " +  pointToString(x2, y2));
516         }
517 
518         if (isDrawingBuffer()) {
519             if (debugBuffered()) {
520                 Graphics debugGraphics = debugGraphics();
521 
522                 debugGraphics.drawLine(x1, y1, x2, y2);
523                 debugGraphics.dispose();
524             }
525         } else if (debugFlash()) {
526             Color oldColor = getColor();
527             int i, count = (info.flashCount * 2) - 1;
528 
529             for (i = 0; i < count; i++) {
530                 graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);
531                 graphics.drawLine(x1, y1, x2, y2);
532                 Toolkit.getDefaultToolkit().sync();
533                 sleep(info.flashTime);
534             }
535             graphics.setColor(oldColor);
536         }
537         graphics.drawLine(x1, y1, x2, y2);
538     }
539 
540     /**
541      * Overrides <code>Graphics.draw3DRect</code>.
542      */
543     public void draw3DRect(int x, int y, int width, int height,
544                            boolean raised) {
545         DebugGraphicsInfo info = info();
546 
547         if (debugLog()) {
548             info().log(toShortString() +
549                        " Drawing 3D rect: " +
550                        new Rectangle(x, y, width, height) +
551                        " Raised bezel: " + raised);
552         }
553         if (isDrawingBuffer()) {
554             if (debugBuffered()) {
555                 Graphics debugGraphics = debugGraphics();
556 
557                 debugGraphics.draw3DRect(x, y, width, height, raised);
558                 debugGraphics.dispose();
559             }
560         } else if (debugFlash()) {
561             Color oldColor = getColor();
562             int i, count = (info.flashCount * 2) - 1;
563 
564             for (i = 0; i < count; i++) {
565                 graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);
566                 graphics.draw3DRect(x, y, width, height, raised);
567                 Toolkit.getDefaultToolkit().sync();
568                 sleep(info.flashTime);
569             }
570             graphics.setColor(oldColor);
571         }
572         graphics.draw3DRect(x, y, width, height, raised);
573     }
574 
575     /**
576      * Overrides <code>Graphics.fill3DRect</code>.
577      */
578     public void fill3DRect(int x, int y, int width, int height,
579                            boolean raised) {
580         DebugGraphicsInfo info = info();
581 
582         if (debugLog()) {
583             info().log(toShortString() +
584                        " Filling 3D rect: " +
585                        new Rectangle(x, y, width, height) +
586                        " Raised bezel: " + raised);
587         }
588         if (isDrawingBuffer()) {
589             if (debugBuffered()) {
590                 Graphics debugGraphics = debugGraphics();
591 
592                 debugGraphics.fill3DRect(x, y, width, height, raised);
593                 debugGraphics.dispose();
594             }
595         } else if (debugFlash()) {
596             Color oldColor = getColor();
597             int i, count = (info.flashCount * 2) - 1;
598 
599             for (i = 0; i < count; i++) {
600                 graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);
601                 graphics.fill3DRect(x, y, width, height, raised);
602                 Toolkit.getDefaultToolkit().sync();
603                 sleep(info.flashTime);
604             }
605             graphics.setColor(oldColor);
606         }
607         graphics.fill3DRect(x, y, width, height, raised);
608     }
609 
610     /**
611      * Overrides <code>Graphics.drawOval</code>.
612      */
613     public void drawOval(int x, int y, int width, int height) {
614         DebugGraphicsInfo info = info();
615 
616         if (debugLog()) {
617             info().log(toShortString() +
618                       " Drawing oval: " +
619                       new Rectangle(x, y, width, height));
620         }
621         if (isDrawingBuffer()) {
622             if (debugBuffered()) {
623                 Graphics debugGraphics = debugGraphics();
624 
625                 debugGraphics.drawOval(x, y, width, height);
626                 debugGraphics.dispose();
627             }
628         } else if (debugFlash()) {
629             Color oldColor = getColor();
630             int i, count = (info.flashCount * 2) - 1;
631 
632             for (i = 0; i < count; i++) {
633                 graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);
634                 graphics.drawOval(x, y, width, height);
635                 Toolkit.getDefaultToolkit().sync();
636                 sleep(info.flashTime);
637             }
638             graphics.setColor(oldColor);
639         }
640         graphics.drawOval(x, y, width, height);
641     }
642 
643     /**
644      * Overrides <code>Graphics.fillOval</code>.
645      */
646     public void fillOval(int x, int y, int width, int height) {
647         DebugGraphicsInfo info = info();
648 
649         if (debugLog()) {
650             info().log(toShortString() +
651                       " Filling oval: " +
652                       new Rectangle(x, y, width, height));
653         }
654         if (isDrawingBuffer()) {
655             if (debugBuffered()) {
656                 Graphics debugGraphics = debugGraphics();
657 
658                 debugGraphics.fillOval(x, y, width, height);
659                 debugGraphics.dispose();
660             }
661         } else if (debugFlash()) {
662             Color oldColor = getColor();
663             int i, count = (info.flashCount * 2) - 1;
664 
665             for (i = 0; i < count; i++) {
666                 graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);
667                 graphics.fillOval(x, y, width, height);
668                 Toolkit.getDefaultToolkit().sync();
669                 sleep(info.flashTime);
670             }
671             graphics.setColor(oldColor);
672         }
673         graphics.fillOval(x, y, width, height);
674     }
675 
676     /**
677      * Overrides <code>Graphics.drawArc</code>.
678      */
679     public void drawArc(int x, int y, int width, int height,
680                         int startAngle, int arcAngle) {
681         DebugGraphicsInfo info = info();
682 
683         if (debugLog()) {
684             info().log(toShortString() +
685                       " Drawing arc: " +
686                       new Rectangle(x, y, width, height) +
687                       " startAngle: " + startAngle +
688                       " arcAngle: " + arcAngle);
689         }
690         if (isDrawingBuffer()) {
691             if (debugBuffered()) {
692                 Graphics debugGraphics = debugGraphics();
693 
694                 debugGraphics.drawArc(x, y, width, height,
695                                       startAngle, arcAngle);
696                 debugGraphics.dispose();
697             }
698         } else if (debugFlash()) {
699             Color oldColor = getColor();
700             int i, count = (info.flashCount * 2) - 1;
701 
702             for (i = 0; i < count; i++) {
703                 graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);
704                 graphics.drawArc(x, y, width, height, startAngle, arcAngle);
705                 Toolkit.getDefaultToolkit().sync();
706                 sleep(info.flashTime);
707             }
708             graphics.setColor(oldColor);
709         }
710         graphics.drawArc(x, y, width, height, startAngle, arcAngle);
711     }
712 
713     /**
714      * Overrides <code>Graphics.fillArc</code>.
715      */
716     public void fillArc(int x, int y, int width, int height,
717                         int startAngle, int arcAngle) {
718         DebugGraphicsInfo info = info();
719 
720         if (debugLog()) {
721             info().log(toShortString() +
722                       " Filling arc: " +
723                       new Rectangle(x, y, width, height) +
724                       " startAngle: " + startAngle +
725                       " arcAngle: " + arcAngle);
726         }
727         if (isDrawingBuffer()) {
728             if (debugBuffered()) {
729                 Graphics debugGraphics = debugGraphics();
730 
731                 debugGraphics.fillArc(x, y, width, height,
732                                       startAngle, arcAngle);
733                 debugGraphics.dispose();
734             }
735         } else if (debugFlash()) {
736             Color oldColor = getColor();
737             int i, count = (info.flashCount * 2) - 1;
738 
739             for (i = 0; i < count; i++) {
740                 graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);
741                 graphics.fillArc(x, y, width, height, startAngle, arcAngle);
742                 Toolkit.getDefaultToolkit().sync();
743                 sleep(info.flashTime);
744             }
745             graphics.setColor(oldColor);
746         }
747         graphics.fillArc(x, y, width, height, startAngle, arcAngle);
748     }
749 
750     /**
751      * Overrides <code>Graphics.drawPolyline</code>.
752      */
753     public void drawPolyline(int xPoints[], int yPoints[], int nPoints) {
754         DebugGraphicsInfo info = info();
755 
756         if (debugLog()) {
757             info().log(toShortString() +
758                       " Drawing polyline: " +
759                       " nPoints: " + nPoints +
760                       " X's: " + xPoints +
761                       " Y's: " + yPoints);
762         }
763         if (isDrawingBuffer()) {
764             if (debugBuffered()) {
765                 Graphics debugGraphics = debugGraphics();
766 
767                 debugGraphics.drawPolyline(xPoints, yPoints, nPoints);
768                 debugGraphics.dispose();
769             }
770         } else if (debugFlash()) {
771             Color oldColor = getColor();
772             int i, count = (info.flashCount * 2) - 1;
773 
774             for (i = 0; i < count; i++) {
775                 graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);
776                 graphics.drawPolyline(xPoints, yPoints, nPoints);
777                 Toolkit.getDefaultToolkit().sync();
778                 sleep(info.flashTime);
779             }
780             graphics.setColor(oldColor);
781         }
782         graphics.drawPolyline(xPoints, yPoints, nPoints);
783     }
784 
785     /**
786      * Overrides <code>Graphics.drawPolygon</code>.
787      */
788     public void drawPolygon(int xPoints[], int yPoints[], int nPoints) {
789         DebugGraphicsInfo info = info();
790 
791         if (debugLog()) {
792             info().log(toShortString() +
793                       " Drawing polygon: " +
794                       " nPoints: " + nPoints +
795                       " X's: " + xPoints +
796                       " Y's: " + yPoints);
797         }
798         if (isDrawingBuffer()) {
799             if (debugBuffered()) {
800                 Graphics debugGraphics = debugGraphics();
801 
802                 debugGraphics.drawPolygon(xPoints, yPoints, nPoints);
803                 debugGraphics.dispose();
804             }
805         } else if (debugFlash()) {
806             Color oldColor = getColor();
807             int i, count = (info.flashCount * 2) - 1;
808 
809             for (i = 0; i < count; i++) {
810                 graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);
811                 graphics.drawPolygon(xPoints, yPoints, nPoints);
812                 Toolkit.getDefaultToolkit().sync();
813                 sleep(info.flashTime);
814             }
815             graphics.setColor(oldColor);
816         }
817         graphics.drawPolygon(xPoints, yPoints, nPoints);
818     }
819 
820     /**
821      * Overrides <code>Graphics.fillPolygon</code>.
822      */
823     public void fillPolygon(int xPoints[], int yPoints[], int nPoints) {
824         DebugGraphicsInfo info = info();
825 
826         if (debugLog()) {
827             info().log(toShortString() +
828                       " Filling polygon: " +
829                       " nPoints: " + nPoints +
830                       " X's: " + xPoints +
831                       " Y's: " + yPoints);
832         }
833         if (isDrawingBuffer()) {
834             if (debugBuffered()) {
835                 Graphics debugGraphics = debugGraphics();
836 
837                 debugGraphics.fillPolygon(xPoints, yPoints, nPoints);
838                 debugGraphics.dispose();
839             }
840         } else if (debugFlash()) {
841             Color oldColor = getColor();
842             int i, count = (info.flashCount * 2) - 1;
843 
844             for (i = 0; i < count; i++) {
845                 graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);
846                 graphics.fillPolygon(xPoints, yPoints, nPoints);
847                 Toolkit.getDefaultToolkit().sync();
848                 sleep(info.flashTime);
849             }
850             graphics.setColor(oldColor);
851         }
852         graphics.fillPolygon(xPoints, yPoints, nPoints);
853     }
854 
855     /**
856      * Overrides <code>Graphics.drawString</code>.
857      */
858     public void drawString(String aString, int x, int y) {
859         DebugGraphicsInfo info = info();
860 
861         if (debugLog()) {
862             info().log(toShortString() +
863                        " Drawing string: \"" + aString +
864                        "\" at: " + new Point(x, y));
865         }
866 
867         if (isDrawingBuffer()) {
868             if (debugBuffered()) {
869                 Graphics debugGraphics = debugGraphics();
870 
871                 debugGraphics.drawString(aString, x, y);
872                 debugGraphics.dispose();
873             }
874         } else if (debugFlash()) {
875             Color oldColor = getColor();
876             int i, count = (info.flashCount * 2) - 1;
877 
878             for (i = 0; i < count; i++) {
879                 graphics.setColor((i % 2) == 0 ? info.flashColor
880                                   : oldColor);
881                 graphics.drawString(aString, x, y);
882                 Toolkit.getDefaultToolkit().sync();
883                 sleep(info.flashTime);
884             }
885             graphics.setColor(oldColor);
886         }
887         graphics.drawString(aString, x, y);
888     }
889 
890     /**
891      * Overrides <code>Graphics.drawString</code>.
892      */
893     public void drawString(AttributedCharacterIterator iterator, int x, int y) {
894         DebugGraphicsInfo info = info();
895 
896         if (debugLog()) {
897             info().log(toShortString() +
898                        " Drawing text: \"" + iterator +
899                        "\" at: " + new Point(x, y));
900         }
901 
902         if (isDrawingBuffer()) {
903             if (debugBuffered()) {
904                 Graphics debugGraphics = debugGraphics();
905 
906                 debugGraphics.drawString(iterator, x, y);
907                 debugGraphics.dispose();
908             }
909         } else if (debugFlash()) {
910             Color oldColor = getColor();
911             int i, count = (info.flashCount * 2) - 1;
912 
913             for (i = 0; i < count; i++) {
914                 graphics.setColor((i % 2) == 0 ? info.flashColor
915                                   : oldColor);
916                 graphics.drawString(iterator, x, y);
917                 Toolkit.getDefaultToolkit().sync();
918                 sleep(info.flashTime);
919             }
920             graphics.setColor(oldColor);
921         }
922         graphics.drawString(iterator, x, y);
923     }
924 
925     /**
926      * Overrides <code>Graphics.drawBytes</code>.
927      */
928     public void drawBytes(byte data[], int offset, int length, int x, int y) {
929         DebugGraphicsInfo info = info();
930 
931         Font font = graphics.getFont();
932 
933         if (debugLog()) {
934             info().log(toShortString() +
935                        " Drawing bytes at: " + new Point(x, y));
936         }
937 
938         if (isDrawingBuffer()) {
939             if (debugBuffered()) {
940                 Graphics debugGraphics = debugGraphics();
941 
942                 debugGraphics.drawBytes(data, offset, length, x, y);
943                 debugGraphics.dispose();
944             }
945         } else if (debugFlash()) {
946             Color oldColor = getColor();
947             int i, count = (info.flashCount * 2) - 1;
948 
949             for (i = 0; i < count; i++) {
950                 graphics.setColor((i % 2) == 0 ? info.flashColor
951                                   : oldColor);
952                 graphics.drawBytes(data, offset, length, x, y);
953                 Toolkit.getDefaultToolkit().sync();
954                 sleep(info.flashTime);
955             }
956             graphics.setColor(oldColor);
957         }
958         graphics.drawBytes(data, offset, length, x, y);
959     }
960 
961     /**
962      * Overrides <code>Graphics.drawChars</code>.
963      */
964     public void drawChars(char data[], int offset, int length, int x, int y) {
965         DebugGraphicsInfo info = info();
966 
967         Font font = graphics.getFont();
968 
969         if (debugLog()) {
970             info().log(toShortString() +
971                        " Drawing chars at " +  new Point(x, y));
972         }
973 
974         if (isDrawingBuffer()) {
975             if (debugBuffered()) {
976                 Graphics debugGraphics = debugGraphics();
977 
978                 debugGraphics.drawChars(data, offset, length, x, y);
979                 debugGraphics.dispose();
980             }
981         } else if (debugFlash()) {
982             Color oldColor = getColor();
983             int i, count = (info.flashCount * 2) - 1;
984 
985             for (i = 0; i < count; i++) {
986                 graphics.setColor((i % 2) == 0 ? info.flashColor
987                                   : oldColor);
988                 graphics.drawChars(data, offset, length, x, y);
989                 Toolkit.getDefaultToolkit().sync();
990                 sleep(info.flashTime);
991             }
992             graphics.setColor(oldColor);
993         }
994         graphics.drawChars(data, offset, length, x, y);
995     }
996 
997     /**
998      * Overrides <code>Graphics.drawImage</code>.
999      */
1000     public boolean drawImage(Image img, int x, int y,
1001                              ImageObserver observer) {
1002         DebugGraphicsInfo info = info();
1003 
1004         if (debugLog()) {
1005             info.log(toShortString() +
1006                      " Drawing image: " + img +
1007                      " at: " + new Point(x, y));
1008         }
1009 
1010         if (isDrawingBuffer()) {
1011             if (debugBuffered()) {
1012                 Graphics debugGraphics = debugGraphics();
1013 
1014                 debugGraphics.drawImage(img, x, y, observer);
1015                 debugGraphics.dispose();
1016             }
1017         } else if (debugFlash()) {
1018             int i, count = (info.flashCount * 2) - 1;
1019             ImageProducer oldProducer = img.getSource();
1020             ImageProducer newProducer
1021                 = new FilteredImageSource(oldProducer,
1022                                 new DebugGraphicsFilter(info.flashColor));
1023             Image newImage
1024                 = Toolkit.getDefaultToolkit().createImage(newProducer);
1025             DebugGraphicsObserver imageObserver
1026                 = new DebugGraphicsObserver();
1027 
1028             Image imageToDraw;
1029             for (i = 0; i < count; i++) {
1030                 imageToDraw = (i % 2) == 0 ? newImage : img;
1031                 loadImage(imageToDraw);
1032                 graphics.drawImage(imageToDraw, x, y,
1033                                    imageObserver);
1034                 Toolkit.getDefaultToolkit().sync();
1035                 sleep(info.flashTime);
1036             }
1037         }
1038         return graphics.drawImage(img, x, y, observer);
1039     }
1040 
1041     /**
1042      * Overrides <code>Graphics.drawImage</code>.
1043      */
1044     public boolean drawImage(Image img, int x, int y, int width, int height,
1045                              ImageObserver observer) {
1046         DebugGraphicsInfo info = info();
1047 
1048         if (debugLog()) {
1049             info.log(toShortString() +
1050                      " Drawing image: " + img +
1051                      " at: " + new Rectangle(x, y, width, height));
1052         }
1053 
1054         if (isDrawingBuffer()) {
1055             if (debugBuffered()) {
1056                 Graphics debugGraphics = debugGraphics();
1057 
1058                 debugGraphics.drawImage(img, x, y, width, height, observer);
1059                 debugGraphics.dispose();
1060             }
1061         } else if (debugFlash()) {
1062             int i, count = (info.flashCount * 2) - 1;
1063             ImageProducer oldProducer = img.getSource();
1064             ImageProducer newProducer
1065                 = new FilteredImageSource(oldProducer,
1066                                 new DebugGraphicsFilter(info.flashColor));
1067             Image newImage
1068                 = Toolkit.getDefaultToolkit().createImage(newProducer);
1069             DebugGraphicsObserver imageObserver
1070                 = new DebugGraphicsObserver();
1071 
1072             Image imageToDraw;
1073             for (i = 0; i < count; i++) {
1074                 imageToDraw = (i % 2) == 0 ? newImage : img;
1075                 loadImage(imageToDraw);
1076                 graphics.drawImage(imageToDraw, x, y,
1077                                    width, height, imageObserver);
1078                 Toolkit.getDefaultToolkit().sync();
1079                 sleep(info.flashTime);
1080             }
1081         }
1082         return graphics.drawImage(img, x, y, width, height, observer);
1083     }
1084 
1085     /**
1086      * Overrides <code>Graphics.drawImage</code>.
1087      */
1088     public boolean drawImage(Image img, int x, int y,
1089                              Color bgcolor,
1090                              ImageObserver observer) {
1091         DebugGraphicsInfo info = info();
1092 
1093         if (debugLog()) {
1094             info.log(toShortString() +
1095                      " Drawing image: " + img +
1096                      " at: " + new Point(x, y) +
1097                      ", bgcolor: " + bgcolor);
1098         }
1099 
1100         if (isDrawingBuffer()) {
1101             if (debugBuffered()) {
1102                 Graphics debugGraphics = debugGraphics();
1103 
1104                 debugGraphics.drawImage(img, x, y, bgcolor, observer);
1105                 debugGraphics.dispose();
1106             }
1107         } else if (debugFlash()) {
1108             int i, count = (info.flashCount * 2) - 1;
1109             ImageProducer oldProducer = img.getSource();
1110             ImageProducer newProducer
1111                 = new FilteredImageSource(oldProducer,
1112                                 new DebugGraphicsFilter(info.flashColor));
1113             Image newImage
1114                 = Toolkit.getDefaultToolkit().createImage(newProducer);
1115             DebugGraphicsObserver imageObserver
1116                 = new DebugGraphicsObserver();
1117 
1118             Image imageToDraw;
1119             for (i = 0; i < count; i++) {
1120                 imageToDraw = (i % 2) == 0 ? newImage : img;
1121                 loadImage(imageToDraw);
1122                 graphics.drawImage(imageToDraw, x, y,
1123                                    bgcolor, imageObserver);
1124                 Toolkit.getDefaultToolkit().sync();
1125                 sleep(info.flashTime);
1126             }
1127         }
1128         return graphics.drawImage(img, x, y, bgcolor, observer);
1129     }
1130 
1131     /**
1132      * Overrides <code>Graphics.drawImage</code>.
1133      */
1134     public boolean drawImage(Image img, int x, int y,int width, int height,
1135                              Color bgcolor,
1136                              ImageObserver observer) {
1137         DebugGraphicsInfo info = info();
1138 
1139         if (debugLog()) {
1140             info.log(toShortString() +
1141                      " Drawing image: " + img +
1142                      " at: " + new Rectangle(x, y, width, height) +
1143                      ", bgcolor: " + bgcolor);
1144         }
1145 
1146         if (isDrawingBuffer()) {
1147             if (debugBuffered()) {
1148                 Graphics debugGraphics = debugGraphics();
1149 
1150                 debugGraphics.drawImage(img, x, y, width, height,
1151                                         bgcolor, observer);
1152                 debugGraphics.dispose();
1153             }
1154         } else if (debugFlash()) {
1155             int i, count = (info.flashCount * 2) - 1;
1156             ImageProducer oldProducer = img.getSource();
1157             ImageProducer newProducer
1158                 = new FilteredImageSource(oldProducer,
1159                                 new DebugGraphicsFilter(info.flashColor));
1160             Image newImage
1161                 = Toolkit.getDefaultToolkit().createImage(newProducer);
1162             DebugGraphicsObserver imageObserver
1163                 = new DebugGraphicsObserver();
1164 
1165             Image imageToDraw;
1166             for (i = 0; i < count; i++) {
1167                 imageToDraw = (i % 2) == 0 ? newImage : img;
1168                 loadImage(imageToDraw);
1169                 graphics.drawImage(imageToDraw, x, y,
1170                                    width, height, bgcolor, imageObserver);
1171                 Toolkit.getDefaultToolkit().sync();
1172                 sleep(info.flashTime);
1173             }
1174         }
1175         return graphics.drawImage(img, x, y, width, height, bgcolor, observer);
1176     }
1177 
1178     /**
1179      * Overrides <code>Graphics.drawImage</code>.
1180      */
1181     public boolean drawImage(Image img,
1182                              int dx1, int dy1, int dx2, int dy2,
1183                              int sx1, int sy1, int sx2, int sy2,
1184                              ImageObserver observer) {
1185         DebugGraphicsInfo info = info();
1186 
1187         if (debugLog()) {
1188             info.log(toShortString() +
1189                      " Drawing image: " + img +
1190                      " destination: " + new Rectangle(dx1, dy1, dx2, dy2) +
1191                      " source: " + new Rectangle(sx1, sy1, sx2, sy2));
1192         }
1193 
1194         if (isDrawingBuffer()) {
1195             if (debugBuffered()) {
1196                 Graphics debugGraphics = debugGraphics();
1197 
1198                 debugGraphics.drawImage(img, dx1, dy1, dx2, dy2,
1199                                         sx1, sy1, sx2, sy2, observer);
1200                 debugGraphics.dispose();
1201             }
1202         } else if (debugFlash()) {
1203             int i, count = (info.flashCount * 2) - 1;
1204             ImageProducer oldProducer = img.getSource();
1205             ImageProducer newProducer
1206                 = new FilteredImageSource(oldProducer,
1207                                 new DebugGraphicsFilter(info.flashColor));
1208             Image newImage
1209                 = Toolkit.getDefaultToolkit().createImage(newProducer);
1210             DebugGraphicsObserver imageObserver
1211                 = new DebugGraphicsObserver();
1212 
1213             Image imageToDraw;
1214             for (i = 0; i < count; i++) {
1215                 imageToDraw = (i % 2) == 0 ? newImage : img;
1216                 loadImage(imageToDraw);
1217                 graphics.drawImage(imageToDraw,
1218                                    dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2,
1219                                    imageObserver);
1220                 Toolkit.getDefaultToolkit().sync();
1221                 sleep(info.flashTime);
1222             }
1223         }
1224         return graphics.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2,
1225                                   observer);
1226     }
1227 
1228     /**
1229      * Overrides <code>Graphics.drawImage</code>.
1230      */
1231     public boolean drawImage(Image img,
1232                              int dx1, int dy1, int dx2, int dy2,
1233                              int sx1, int sy1, int sx2, int sy2,
1234                              Color bgcolor,
1235                              ImageObserver observer) {
1236         DebugGraphicsInfo info = info();
1237 
1238         if (debugLog()) {
1239             info.log(toShortString() +
1240                      " Drawing image: " + img +
1241                      " destination: " + new Rectangle(dx1, dy1, dx2, dy2) +
1242                      " source: " + new Rectangle(sx1, sy1, sx2, sy2) +
1243                      ", bgcolor: " + bgcolor);
1244         }
1245 
1246         if (isDrawingBuffer()) {
1247             if (debugBuffered()) {
1248                 Graphics debugGraphics = debugGraphics();
1249 
1250                 debugGraphics.drawImage(img, dx1, dy1, dx2, dy2,
1251                                         sx1, sy1, sx2, sy2, bgcolor, observer);
1252                 debugGraphics.dispose();
1253             }
1254         } else if (debugFlash()) {
1255             int i, count = (info.flashCount * 2) - 1;
1256             ImageProducer oldProducer = img.getSource();
1257             ImageProducer newProducer
1258                 = new FilteredImageSource(oldProducer,
1259                                 new DebugGraphicsFilter(info.flashColor));
1260             Image newImage
1261                 = Toolkit.getDefaultToolkit().createImage(newProducer);
1262             DebugGraphicsObserver imageObserver
1263                 = new DebugGraphicsObserver();
1264 
1265             Image imageToDraw;
1266             for (i = 0; i < count; i++) {
1267                 imageToDraw = (i % 2) == 0 ? newImage : img;
1268                 loadImage(imageToDraw);
1269                 graphics.drawImage(imageToDraw,
1270                                    dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2,
1271                                    bgcolor, imageObserver);
1272                 Toolkit.getDefaultToolkit().sync();
1273                 sleep(info.flashTime);
1274             }
1275         }
1276         return graphics.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2,
1277                                   bgcolor, observer);
1278     }
1279 
1280     static void loadImage(Image img) {
1281         imageLoadingIcon.loadImage(img);
1282     }
1283 
1284 
1285     /**
1286      * Overrides <code>Graphics.copyArea</code>.
1287      */
1288     public void copyArea(int x, int y, int width, int height,
1289                          int destX, int destY) {
1290         if (debugLog()) {
1291             info().log(toShortString() +
1292                       " Copying area from: " +
1293                       new Rectangle(x, y, width, height) +
1294                       " to: " + new Point(destX, destY));
1295         }
1296         graphics.copyArea(x, y, width, height, destX, destY);
1297     }
1298 
1299     final void sleep(int mSecs) {
1300         try {
1301             Thread.sleep(mSecs);
1302         } catch (Exception e) {
1303         }
1304     }
1305 
1306     /**
1307      * Overrides <code>Graphics.dispose</code>.
1308      */
1309     public void dispose() {
1310         graphics.dispose();
1311         graphics = null;
1312     }
1313 
1314     // ALERT!
1315     /**
1316      * Returns the drawingBuffer value.
1317      *
1318      * @return true if this object is drawing from a Buffer
1319      */
1320     public boolean isDrawingBuffer() {
1321         return buffer != null;
1322     }
1323 
1324     String toShortString() {
1325         return "Graphics" + (isDrawingBuffer() ? "<B>" : "") + "(" + graphicsID + "-" + debugOptions + ")";
1326     }
1327 
1328     String pointToString(int x, int y) {
1329         return "(" + x + ", " + y + ")";
1330     }
1331 
1332     /** Enables/disables diagnostic information about every graphics
1333       * operation. The value of <b>options</b> indicates how this information
1334       * should be displayed. LOG_OPTION causes a text message to be printed.
1335       * FLASH_OPTION causes the drawing to flash several times. BUFFERED_OPTION
1336       * creates a new Frame that shows each operation on an
1337       * offscreen buffer. The value of <b>options</b> is bitwise OR'd into
1338       * the current value. To disable debugging use NONE_OPTION.
1339       */
1340     public void setDebugOptions(int options) {
1341         if (options != 0) {
1342             if (options == NONE_OPTION) {
1343                 if (debugOptions != 0) {
1344                     System.err.println(toShortString() + " Disabling debug");
1345                     debugOptions = 0;
1346                 }
1347             } else {
1348                 if (debugOptions != options) {
1349                     debugOptions |= options;
1350                     if (debugLog()) {
1351                         System.err.println(toShortString() + " Enabling debug");
1352                     }
1353                 }
1354             }
1355         }
1356     }
1357 
1358     /** Returns the current debugging options for this DebugGraphics.
1359       * @see #setDebugOptions
1360       */
1361     public int getDebugOptions() {
1362         return debugOptions;
1363     }
1364 
1365     /** Static wrapper method for DebugGraphicsInfo.setDebugOptions(). Stores
1366       * options on a per component basis.
1367       */
1368     static void setDebugOptions(JComponent component, int options) {
1369         info().setDebugOptions(component, options);
1370     }
1371 
1372     /** Static wrapper method for DebugGraphicsInfo.getDebugOptions().
1373       */
1374     static int getDebugOptions(JComponent component) {
1375         DebugGraphicsInfo debugGraphicsInfo = info();
1376         if (debugGraphicsInfo == null) {
1377             return 0;
1378         } else {
1379             return debugGraphicsInfo.getDebugOptions(component);
1380         }
1381     }
1382 
1383     /** Returns non-zero if <b>component</b> should display with DebugGraphics,
1384       * zero otherwise. Walks the JComponent's parent tree to determine if
1385       * any debugging options have been set.
1386       */
1387     static int shouldComponentDebug(JComponent component) {
1388         DebugGraphicsInfo info = info();
1389         if (info == null) {
1390             return 0;
1391         } else {
1392             Container container = (Container)component;
1393             int debugOptions = 0;
1394 
1395             while (container != null && (container instanceof JComponent)) {
1396                 debugOptions |= info.getDebugOptions((JComponent)container);
1397                 container = container.getParent();
1398             }
1399 
1400             return debugOptions;
1401         }
1402     }
1403 
1404     /** Returns the number of JComponents that have debugging options turned
1405       * on.
1406       */
1407     static int debugComponentCount() {
1408         DebugGraphicsInfo debugGraphicsInfo = info();
1409         if (debugGraphicsInfo != null &&
1410                     debugGraphicsInfo.componentToDebug != null) {
1411             return debugGraphicsInfo.componentToDebug.size();
1412         } else {
1413             return 0;
1414         }
1415     }
1416 
1417     boolean debugLog() {
1418         return (debugOptions & LOG_OPTION) == LOG_OPTION;
1419     }
1420 
1421     boolean debugFlash() {
1422         return (debugOptions & FLASH_OPTION) == FLASH_OPTION;
1423     }
1424 
1425     boolean debugBuffered() {
1426         return (debugOptions & BUFFERED_OPTION) == BUFFERED_OPTION;
1427     }
1428 
1429     /** Returns a DebugGraphics for use in buffering window.
1430       */
1431     private Graphics debugGraphics() {
1432         DebugGraphics        debugGraphics;
1433         DebugGraphicsInfo    info = info();
1434         JFrame               debugFrame;
1435 
1436         if (info.debugFrame == null) {
1437             info.debugFrame = new JFrame();
1438             info.debugFrame.setSize(500, 500);
1439         }
1440         debugFrame = info.debugFrame;
1441         debugFrame.show();
1442         debugGraphics = new DebugGraphics(debugFrame.getGraphics());
1443         debugGraphics.setFont(getFont());
1444         debugGraphics.setColor(getColor());
1445         debugGraphics.translate(xOffset, yOffset);
1446         debugGraphics.setClip(getClipBounds());
1447         if (debugFlash()) {
1448             debugGraphics.setDebugOptions(FLASH_OPTION);
1449         }
1450         return debugGraphics;
1451     }
1452 
1453     /** Returns DebugGraphicsInfo, or creates one if none exists.
1454       */
1455     static DebugGraphicsInfo info() {
1456         DebugGraphicsInfo debugGraphicsInfo = (DebugGraphicsInfo)
1457             SwingUtilities.appContextGet(debugGraphicsInfoKey);
1458         if (debugGraphicsInfo == null) {
1459             debugGraphicsInfo = new DebugGraphicsInfo();
1460             SwingUtilities.appContextPut(debugGraphicsInfoKey,
1461                                          debugGraphicsInfo);
1462         }
1463         return debugGraphicsInfo;
1464     }
1465     private static final Class debugGraphicsInfoKey = DebugGraphicsInfo.class;
1466 
1467 
1468 }