1 /*
   2  * Copyright (c) 1997, 2004, 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 }