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