Path: blob/master/src/java.desktop/share/classes/javax/swing/DebugGraphics.java
41153 views
/*1* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.swing;2627import java.awt.*;28import java.awt.image.*;29import java.text.AttributedCharacterIterator;3031/**32* Graphics subclass supporting graphics debugging. Overrides most methods33* from Graphics. DebugGraphics objects are rarely created by hand. They34* are most frequently created automatically when a JComponent's35* debugGraphicsOptions are changed using the setDebugGraphicsOptions()36* method.37* <p>38* NOTE: You must turn off double buffering to use DebugGraphics:39* RepaintManager repaintManager = RepaintManager.currentManager(component);40* repaintManager.setDoubleBufferingEnabled(false);41*42* @see JComponent#setDebugGraphicsOptions43* @see RepaintManager#currentManager44* @see RepaintManager#setDoubleBufferingEnabled45*46* @author Dave Karlton47* @since 1.248*/49public class DebugGraphics extends Graphics {50Graphics graphics;51Image buffer;52int debugOptions;53int graphicsID = graphicsCount++;54int xOffset, yOffset;55private static int graphicsCount = 0;56private static ImageIcon imageLoadingIcon = new ImageIcon();5758/** Log graphics operations. */59public static final int LOG_OPTION = 1 << 0;60/** Flash graphics operations. */61public static final int FLASH_OPTION = 1 << 1;62/** Show buffered operations in a separate <code>Frame</code>. */63public static final int BUFFERED_OPTION = 1 << 2;64/** Don't debug graphics operations. */65public static final int NONE_OPTION = -1;6667static {68JComponent.DEBUG_GRAPHICS_LOADED = true;69}7071/**72* Constructs a new debug graphics context that supports slowed73* down drawing.74*/75public DebugGraphics() {76super();77buffer = null;78xOffset = yOffset = 0;79}8081/**82* Constructs a debug graphics context from an existing graphics83* context that slows down drawing for the specified component.84*85* @param graphics the Graphics context to slow down86* @param component the JComponent to draw slowly87*/88public DebugGraphics(Graphics graphics, JComponent component) {89this(graphics);90setDebugOptions(component.shouldDebugGraphics());91}9293/**94* Constructs a debug graphics context from an existing graphics95* context that supports slowed down drawing.96*97* @param graphics the Graphics context to slow down98*/99public DebugGraphics(Graphics graphics) {100this();101this.graphics = graphics;102}103104/**105* Overrides <code>Graphics.create</code> to return a DebugGraphics object.106*/107public Graphics create() {108DebugGraphics debugGraphics;109110debugGraphics = new DebugGraphics();111debugGraphics.graphics = graphics.create();112debugGraphics.debugOptions = debugOptions;113debugGraphics.buffer = buffer;114115return debugGraphics;116}117118/**119* Overrides <code>Graphics.create</code> to return a DebugGraphics object.120*/121public Graphics create(int x, int y, int width, int height) {122DebugGraphics debugGraphics;123124debugGraphics = new DebugGraphics();125debugGraphics.graphics = graphics.create(x, y, width, height);126debugGraphics.debugOptions = debugOptions;127debugGraphics.buffer = buffer;128debugGraphics.xOffset = xOffset + x;129debugGraphics.yOffset = yOffset + y;130131return debugGraphics;132}133134135//------------------------------------------------136// NEW METHODS137//------------------------------------------------138139/**140* Sets the Color used to flash drawing operations.141*142* @param flashColor the Color used to flash drawing operations143*/144public static void setFlashColor(Color flashColor) {145info().flashColor = flashColor;146}147148/**149* Returns the Color used to flash drawing operations.150*151* @return the Color used to flash drawing operations152* @see #setFlashColor153*/154public static Color flashColor() {155return info().flashColor;156}157158/**159* Sets the time delay of drawing operation flashing.160*161* @param flashTime the time delay of drawing operation flashing162*/163public static void setFlashTime(int flashTime) {164info().flashTime = flashTime;165}166167/**168* Returns the time delay of drawing operation flashing.169*170* @return the time delay of drawing operation flashing171* @see #setFlashTime172*/173public static int flashTime() {174return info().flashTime;175}176177/**178* Sets the number of times that drawing operations will flash.179*180* @param flashCount number of times that drawing operations will flash181*/182public static void setFlashCount(int flashCount) {183info().flashCount = flashCount;184}185186/**187* Returns the number of times that drawing operations will flash.188*189* @return the number of times that drawing operations will flash190* @see #setFlashCount191*/192public static int flashCount() {193return info().flashCount;194}195196/**197* Sets the stream to which the DebugGraphics logs drawing operations.198*199* @param stream the stream to which the DebugGraphics logs drawing operations200*/201public static void setLogStream(java.io.PrintStream stream) {202info().stream = stream;203}204205/**206* Returns the stream to which the DebugGraphics logs drawing operations.207*208* @return the stream to which the DebugGraphics logs drawing operations209* @see #setLogStream210*/211public static java.io.PrintStream logStream() {212return info().stream;213}214215/** Sets the Font used for text drawing operations.216*/217public void setFont(Font aFont) {218if (debugLog()) {219info().log(toShortString() + " Setting font: " + aFont);220}221graphics.setFont(aFont);222}223224/** Returns the Font used for text drawing operations.225* @see #setFont226*/227public Font getFont() {228return graphics.getFont();229}230231/** Sets the color to be used for drawing and filling lines and shapes.232*/233public void setColor(Color aColor) {234if (debugLog()) {235info().log(toShortString() + " Setting color: " + aColor);236}237graphics.setColor(aColor);238}239240/** Returns the Color used for text drawing operations.241* @see #setColor242*/243public Color getColor() {244return graphics.getColor();245}246247248//-----------------------------------------------249// OVERRIDDEN METHODS250//------------------------------------------------251252/**253* Overrides <code>Graphics.getFontMetrics</code>.254*/255public FontMetrics getFontMetrics() {256return graphics.getFontMetrics();257}258259/**260* Overrides <code>Graphics.getFontMetrics</code>.261*/262public FontMetrics getFontMetrics(Font f) {263return graphics.getFontMetrics(f);264}265266/**267* Overrides <code>Graphics.translate</code>.268*/269public void translate(int x, int y) {270if (debugLog()) {271info().log(toShortString() +272" Translating by: " + new Point(x, y));273}274xOffset += x;275yOffset += y;276graphics.translate(x, y);277}278279/**280* Overrides <code>Graphics.setPaintMode</code>.281*/282public void setPaintMode() {283if (debugLog()) {284info().log(toShortString() + " Setting paint mode");285}286graphics.setPaintMode();287}288289/**290* Overrides <code>Graphics.setXORMode</code>.291*/292public void setXORMode(Color aColor) {293if (debugLog()) {294info().log(toShortString() + " Setting XOR mode: " + aColor);295}296graphics.setXORMode(aColor);297}298299/**300* Overrides <code>Graphics.getClipBounds</code>.301*/302public Rectangle getClipBounds() {303return graphics.getClipBounds();304}305306/**307* Overrides <code>Graphics.clipRect</code>.308*/309public void clipRect(int x, int y, int width, int height) {310graphics.clipRect(x, y, width, height);311if (debugLog()) {312info().log(toShortString() +313" Setting clipRect: " + (new Rectangle(x, y, width, height)) +314" New clipRect: " + graphics.getClip());315}316}317318/**319* Overrides <code>Graphics.setClip</code>.320*/321public void setClip(int x, int y, int width, int height) {322graphics.setClip(x, y, width, height);323if (debugLog()) {324info().log(toShortString() +325" Setting new clipRect: " + graphics.getClip());326}327}328329/**330* Overrides <code>Graphics.getClip</code>.331*/332public Shape getClip() {333return graphics.getClip();334}335336/**337* Overrides <code>Graphics.setClip</code>.338*/339public void setClip(Shape clip) {340graphics.setClip(clip);341if (debugLog()) {342info().log(toShortString() +343" Setting new clipRect: " + graphics.getClip());344}345}346347/**348* Overrides <code>Graphics.drawRect</code>.349*/350public void drawRect(int x, int y, int width, int height) {351DebugGraphicsInfo info = info();352353if (debugLog()) {354info().log(toShortString() +355" Drawing rect: " +356new Rectangle(x, y, width, height));357}358359if (isDrawingBuffer()) {360if (debugBuffered()) {361Graphics debugGraphics = debugGraphics();362363debugGraphics.drawRect(x, y, width, height);364debugGraphics.dispose();365}366} else if (debugFlash()) {367Color oldColor = getColor();368int i, count = (info.flashCount * 2) - 1;369370for (i = 0; i < count; i++) {371graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);372graphics.drawRect(x, y, width, height);373Toolkit.getDefaultToolkit().sync();374sleep(info.flashTime);375}376graphics.setColor(oldColor);377}378graphics.drawRect(x, y, width, height);379}380381/**382* Overrides <code>Graphics.fillRect</code>.383*/384public void fillRect(int x, int y, int width, int height) {385DebugGraphicsInfo info = info();386387if (debugLog()) {388info().log(toShortString() +389" Filling rect: " +390new Rectangle(x, y, width, height));391}392393if (isDrawingBuffer()) {394if (debugBuffered()) {395Graphics debugGraphics = debugGraphics();396397debugGraphics.fillRect(x, y, width, height);398debugGraphics.dispose();399}400} else if (debugFlash()) {401Color oldColor = getColor();402int i, count = (info.flashCount * 2) - 1;403404for (i = 0; i < count; i++) {405graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);406graphics.fillRect(x, y, width, height);407Toolkit.getDefaultToolkit().sync();408sleep(info.flashTime);409}410graphics.setColor(oldColor);411}412graphics.fillRect(x, y, width, height);413}414415/**416* Overrides <code>Graphics.clearRect</code>.417*/418public void clearRect(int x, int y, int width, int height) {419DebugGraphicsInfo info = info();420421if (debugLog()) {422info().log(toShortString() +423" Clearing rect: " +424new Rectangle(x, y, width, height));425}426427if (isDrawingBuffer()) {428if (debugBuffered()) {429Graphics debugGraphics = debugGraphics();430431debugGraphics.clearRect(x, y, width, height);432debugGraphics.dispose();433}434} else if (debugFlash()) {435Color oldColor = getColor();436int i, count = (info.flashCount * 2) - 1;437438for (i = 0; i < count; i++) {439graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);440graphics.clearRect(x, y, width, height);441Toolkit.getDefaultToolkit().sync();442sleep(info.flashTime);443}444graphics.setColor(oldColor);445}446graphics.clearRect(x, y, width, height);447}448449/**450* Overrides <code>Graphics.drawRoundRect</code>.451*/452public void drawRoundRect(int x, int y, int width, int height,453int arcWidth, int arcHeight) {454DebugGraphicsInfo info = info();455456if (debugLog()) {457info().log(toShortString() +458" Drawing round rect: " +459new Rectangle(x, y, width, height) +460" arcWidth: " + arcWidth +461" archHeight: " + arcHeight);462}463if (isDrawingBuffer()) {464if (debugBuffered()) {465Graphics debugGraphics = debugGraphics();466467debugGraphics.drawRoundRect(x, y, width, height,468arcWidth, arcHeight);469debugGraphics.dispose();470}471} else if (debugFlash()) {472Color oldColor = getColor();473int i, count = (info.flashCount * 2) - 1;474475for (i = 0; i < count; i++) {476graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);477graphics.drawRoundRect(x, y, width, height,478arcWidth, arcHeight);479Toolkit.getDefaultToolkit().sync();480sleep(info.flashTime);481}482graphics.setColor(oldColor);483}484graphics.drawRoundRect(x, y, width, height, arcWidth, arcHeight);485}486487/**488* Overrides <code>Graphics.fillRoundRect</code>.489*/490public void fillRoundRect(int x, int y, int width, int height,491int arcWidth, int arcHeight) {492DebugGraphicsInfo info = info();493494if (debugLog()) {495info().log(toShortString() +496" Filling round rect: " +497new Rectangle(x, y, width, height) +498" arcWidth: " + arcWidth +499" archHeight: " + arcHeight);500}501if (isDrawingBuffer()) {502if (debugBuffered()) {503Graphics debugGraphics = debugGraphics();504505debugGraphics.fillRoundRect(x, y, width, height,506arcWidth, arcHeight);507debugGraphics.dispose();508}509} else if (debugFlash()) {510Color oldColor = getColor();511int i, count = (info.flashCount * 2) - 1;512513for (i = 0; i < count; i++) {514graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);515graphics.fillRoundRect(x, y, width, height,516arcWidth, arcHeight);517Toolkit.getDefaultToolkit().sync();518sleep(info.flashTime);519}520graphics.setColor(oldColor);521}522graphics.fillRoundRect(x, y, width, height, arcWidth, arcHeight);523}524525/**526* Overrides <code>Graphics.drawLine</code>.527*/528public void drawLine(int x1, int y1, int x2, int y2) {529DebugGraphicsInfo info = info();530531if (debugLog()) {532info().log(toShortString() +533" Drawing line: from " + pointToString(x1, y1) +534" to " + pointToString(x2, y2));535}536537if (isDrawingBuffer()) {538if (debugBuffered()) {539Graphics debugGraphics = debugGraphics();540541debugGraphics.drawLine(x1, y1, x2, y2);542debugGraphics.dispose();543}544} else if (debugFlash()) {545Color oldColor = getColor();546int i, count = (info.flashCount * 2) - 1;547548for (i = 0; i < count; i++) {549graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);550graphics.drawLine(x1, y1, x2, y2);551Toolkit.getDefaultToolkit().sync();552sleep(info.flashTime);553}554graphics.setColor(oldColor);555}556graphics.drawLine(x1, y1, x2, y2);557}558559/**560* Overrides <code>Graphics.draw3DRect</code>.561*/562public void draw3DRect(int x, int y, int width, int height,563boolean raised) {564DebugGraphicsInfo info = info();565566if (debugLog()) {567info().log(toShortString() +568" Drawing 3D rect: " +569new Rectangle(x, y, width, height) +570" Raised bezel: " + raised);571}572if (isDrawingBuffer()) {573if (debugBuffered()) {574Graphics debugGraphics = debugGraphics();575576debugGraphics.draw3DRect(x, y, width, height, raised);577debugGraphics.dispose();578}579} else if (debugFlash()) {580Color oldColor = getColor();581int i, count = (info.flashCount * 2) - 1;582583for (i = 0; i < count; i++) {584graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);585graphics.draw3DRect(x, y, width, height, raised);586Toolkit.getDefaultToolkit().sync();587sleep(info.flashTime);588}589graphics.setColor(oldColor);590}591graphics.draw3DRect(x, y, width, height, raised);592}593594/**595* Overrides <code>Graphics.fill3DRect</code>.596*/597public void fill3DRect(int x, int y, int width, int height,598boolean raised) {599DebugGraphicsInfo info = info();600601if (debugLog()) {602info().log(toShortString() +603" Filling 3D rect: " +604new Rectangle(x, y, width, height) +605" Raised bezel: " + raised);606}607if (isDrawingBuffer()) {608if (debugBuffered()) {609Graphics debugGraphics = debugGraphics();610611debugGraphics.fill3DRect(x, y, width, height, raised);612debugGraphics.dispose();613}614} else if (debugFlash()) {615Color oldColor = getColor();616int i, count = (info.flashCount * 2) - 1;617618for (i = 0; i < count; i++) {619graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);620graphics.fill3DRect(x, y, width, height, raised);621Toolkit.getDefaultToolkit().sync();622sleep(info.flashTime);623}624graphics.setColor(oldColor);625}626graphics.fill3DRect(x, y, width, height, raised);627}628629/**630* Overrides <code>Graphics.drawOval</code>.631*/632public void drawOval(int x, int y, int width, int height) {633DebugGraphicsInfo info = info();634635if (debugLog()) {636info().log(toShortString() +637" Drawing oval: " +638new Rectangle(x, y, width, height));639}640if (isDrawingBuffer()) {641if (debugBuffered()) {642Graphics debugGraphics = debugGraphics();643644debugGraphics.drawOval(x, y, width, height);645debugGraphics.dispose();646}647} else if (debugFlash()) {648Color oldColor = getColor();649int i, count = (info.flashCount * 2) - 1;650651for (i = 0; i < count; i++) {652graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);653graphics.drawOval(x, y, width, height);654Toolkit.getDefaultToolkit().sync();655sleep(info.flashTime);656}657graphics.setColor(oldColor);658}659graphics.drawOval(x, y, width, height);660}661662/**663* Overrides <code>Graphics.fillOval</code>.664*/665public void fillOval(int x, int y, int width, int height) {666DebugGraphicsInfo info = info();667668if (debugLog()) {669info().log(toShortString() +670" Filling oval: " +671new Rectangle(x, y, width, height));672}673if (isDrawingBuffer()) {674if (debugBuffered()) {675Graphics debugGraphics = debugGraphics();676677debugGraphics.fillOval(x, y, width, height);678debugGraphics.dispose();679}680} else if (debugFlash()) {681Color oldColor = getColor();682int i, count = (info.flashCount * 2) - 1;683684for (i = 0; i < count; i++) {685graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);686graphics.fillOval(x, y, width, height);687Toolkit.getDefaultToolkit().sync();688sleep(info.flashTime);689}690graphics.setColor(oldColor);691}692graphics.fillOval(x, y, width, height);693}694695/**696* Overrides <code>Graphics.drawArc</code>.697*/698public void drawArc(int x, int y, int width, int height,699int startAngle, int arcAngle) {700DebugGraphicsInfo info = info();701702if (debugLog()) {703info().log(toShortString() +704" Drawing arc: " +705new Rectangle(x, y, width, height) +706" startAngle: " + startAngle +707" arcAngle: " + arcAngle);708}709if (isDrawingBuffer()) {710if (debugBuffered()) {711Graphics debugGraphics = debugGraphics();712713debugGraphics.drawArc(x, y, width, height,714startAngle, arcAngle);715debugGraphics.dispose();716}717} else if (debugFlash()) {718Color oldColor = getColor();719int i, count = (info.flashCount * 2) - 1;720721for (i = 0; i < count; i++) {722graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);723graphics.drawArc(x, y, width, height, startAngle, arcAngle);724Toolkit.getDefaultToolkit().sync();725sleep(info.flashTime);726}727graphics.setColor(oldColor);728}729graphics.drawArc(x, y, width, height, startAngle, arcAngle);730}731732/**733* Overrides <code>Graphics.fillArc</code>.734*/735public void fillArc(int x, int y, int width, int height,736int startAngle, int arcAngle) {737DebugGraphicsInfo info = info();738739if (debugLog()) {740info().log(toShortString() +741" Filling arc: " +742new Rectangle(x, y, width, height) +743" startAngle: " + startAngle +744" arcAngle: " + arcAngle);745}746if (isDrawingBuffer()) {747if (debugBuffered()) {748Graphics debugGraphics = debugGraphics();749750debugGraphics.fillArc(x, y, width, height,751startAngle, arcAngle);752debugGraphics.dispose();753}754} else if (debugFlash()) {755Color oldColor = getColor();756int i, count = (info.flashCount * 2) - 1;757758for (i = 0; i < count; i++) {759graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);760graphics.fillArc(x, y, width, height, startAngle, arcAngle);761Toolkit.getDefaultToolkit().sync();762sleep(info.flashTime);763}764graphics.setColor(oldColor);765}766graphics.fillArc(x, y, width, height, startAngle, arcAngle);767}768769/**770* Overrides <code>Graphics.drawPolyline</code>.771*/772public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints) {773DebugGraphicsInfo info = info();774775if (debugLog()) {776info().log(toShortString() +777" Drawing polyline: " +778" nPoints: " + nPoints +779" X's: " + xPoints +780" Y's: " + yPoints);781}782if (isDrawingBuffer()) {783if (debugBuffered()) {784Graphics debugGraphics = debugGraphics();785786debugGraphics.drawPolyline(xPoints, yPoints, nPoints);787debugGraphics.dispose();788}789} else if (debugFlash()) {790Color oldColor = getColor();791int i, count = (info.flashCount * 2) - 1;792793for (i = 0; i < count; i++) {794graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);795graphics.drawPolyline(xPoints, yPoints, nPoints);796Toolkit.getDefaultToolkit().sync();797sleep(info.flashTime);798}799graphics.setColor(oldColor);800}801graphics.drawPolyline(xPoints, yPoints, nPoints);802}803804/**805* Overrides <code>Graphics.drawPolygon</code>.806*/807public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) {808DebugGraphicsInfo info = info();809810if (debugLog()) {811info().log(toShortString() +812" Drawing polygon: " +813" nPoints: " + nPoints +814" X's: " + xPoints +815" Y's: " + yPoints);816}817if (isDrawingBuffer()) {818if (debugBuffered()) {819Graphics debugGraphics = debugGraphics();820821debugGraphics.drawPolygon(xPoints, yPoints, nPoints);822debugGraphics.dispose();823}824} else if (debugFlash()) {825Color oldColor = getColor();826int i, count = (info.flashCount * 2) - 1;827828for (i = 0; i < count; i++) {829graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);830graphics.drawPolygon(xPoints, yPoints, nPoints);831Toolkit.getDefaultToolkit().sync();832sleep(info.flashTime);833}834graphics.setColor(oldColor);835}836graphics.drawPolygon(xPoints, yPoints, nPoints);837}838839/**840* Overrides <code>Graphics.fillPolygon</code>.841*/842public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) {843DebugGraphicsInfo info = info();844845if (debugLog()) {846info().log(toShortString() +847" Filling polygon: " +848" nPoints: " + nPoints +849" X's: " + xPoints +850" Y's: " + yPoints);851}852if (isDrawingBuffer()) {853if (debugBuffered()) {854Graphics debugGraphics = debugGraphics();855856debugGraphics.fillPolygon(xPoints, yPoints, nPoints);857debugGraphics.dispose();858}859} else if (debugFlash()) {860Color oldColor = getColor();861int i, count = (info.flashCount * 2) - 1;862863for (i = 0; i < count; i++) {864graphics.setColor((i % 2) == 0 ? info.flashColor : oldColor);865graphics.fillPolygon(xPoints, yPoints, nPoints);866Toolkit.getDefaultToolkit().sync();867sleep(info.flashTime);868}869graphics.setColor(oldColor);870}871graphics.fillPolygon(xPoints, yPoints, nPoints);872}873874/**875* Overrides <code>Graphics.drawString</code>.876*/877public void drawString(String aString, int x, int y) {878DebugGraphicsInfo info = info();879880if (debugLog()) {881info().log(toShortString() +882" Drawing string: \"" + aString +883"\" at: " + new Point(x, y));884}885886if (isDrawingBuffer()) {887if (debugBuffered()) {888Graphics debugGraphics = debugGraphics();889890debugGraphics.drawString(aString, x, y);891debugGraphics.dispose();892}893} else if (debugFlash()) {894Color oldColor = getColor();895int i, count = (info.flashCount * 2) - 1;896897for (i = 0; i < count; i++) {898graphics.setColor((i % 2) == 0 ? info.flashColor899: oldColor);900graphics.drawString(aString, x, y);901Toolkit.getDefaultToolkit().sync();902sleep(info.flashTime);903}904graphics.setColor(oldColor);905}906graphics.drawString(aString, x, y);907}908909/**910* Overrides <code>Graphics.drawString</code>.911*/912public void drawString(AttributedCharacterIterator iterator, int x, int y) {913DebugGraphicsInfo info = info();914915if (debugLog()) {916info().log(toShortString() +917" Drawing text: \"" + iterator +918"\" at: " + new Point(x, y));919}920921if (isDrawingBuffer()) {922if (debugBuffered()) {923Graphics debugGraphics = debugGraphics();924925debugGraphics.drawString(iterator, x, y);926debugGraphics.dispose();927}928} else if (debugFlash()) {929Color oldColor = getColor();930int i, count = (info.flashCount * 2) - 1;931932for (i = 0; i < count; i++) {933graphics.setColor((i % 2) == 0 ? info.flashColor934: oldColor);935graphics.drawString(iterator, x, y);936Toolkit.getDefaultToolkit().sync();937sleep(info.flashTime);938}939graphics.setColor(oldColor);940}941graphics.drawString(iterator, x, y);942}943944/**945* Overrides <code>Graphics.drawBytes</code>.946*/947public void drawBytes(byte[] data, int offset, int length, int x, int y) {948DebugGraphicsInfo info = info();949950Font font = graphics.getFont();951952if (debugLog()) {953info().log(toShortString() +954" Drawing bytes at: " + new Point(x, y));955}956957if (isDrawingBuffer()) {958if (debugBuffered()) {959Graphics debugGraphics = debugGraphics();960961debugGraphics.drawBytes(data, offset, length, x, y);962debugGraphics.dispose();963}964} else if (debugFlash()) {965Color oldColor = getColor();966int i, count = (info.flashCount * 2) - 1;967968for (i = 0; i < count; i++) {969graphics.setColor((i % 2) == 0 ? info.flashColor970: oldColor);971graphics.drawBytes(data, offset, length, x, y);972Toolkit.getDefaultToolkit().sync();973sleep(info.flashTime);974}975graphics.setColor(oldColor);976}977graphics.drawBytes(data, offset, length, x, y);978}979980/**981* Overrides <code>Graphics.drawChars</code>.982*/983public void drawChars(char[] data, int offset, int length, int x, int y) {984DebugGraphicsInfo info = info();985986Font font = graphics.getFont();987988if (debugLog()) {989info().log(toShortString() +990" Drawing chars at " + new Point(x, y));991}992993if (isDrawingBuffer()) {994if (debugBuffered()) {995Graphics debugGraphics = debugGraphics();996997debugGraphics.drawChars(data, offset, length, x, y);998debugGraphics.dispose();999}1000} else if (debugFlash()) {1001Color oldColor = getColor();1002int i, count = (info.flashCount * 2) - 1;10031004for (i = 0; i < count; i++) {1005graphics.setColor((i % 2) == 0 ? info.flashColor1006: oldColor);1007graphics.drawChars(data, offset, length, x, y);1008Toolkit.getDefaultToolkit().sync();1009sleep(info.flashTime);1010}1011graphics.setColor(oldColor);1012}1013graphics.drawChars(data, offset, length, x, y);1014}10151016/**1017* Overrides <code>Graphics.drawImage</code>.1018*/1019public boolean drawImage(Image img, int x, int y,1020ImageObserver observer) {1021DebugGraphicsInfo info = info();10221023if (debugLog()) {1024info.log(toShortString() +1025" Drawing image: " + img +1026" at: " + new Point(x, y));1027}10281029if (isDrawingBuffer()) {1030if (debugBuffered()) {1031Graphics debugGraphics = debugGraphics();10321033debugGraphics.drawImage(img, x, y, observer);1034debugGraphics.dispose();1035}1036} else if (debugFlash()) {1037int i, count = (info.flashCount * 2) - 1;1038ImageProducer oldProducer = img.getSource();1039ImageProducer newProducer1040= new FilteredImageSource(oldProducer,1041new DebugGraphicsFilter(info.flashColor));1042Image newImage1043= Toolkit.getDefaultToolkit().createImage(newProducer);1044DebugGraphicsObserver imageObserver1045= new DebugGraphicsObserver();10461047Image imageToDraw;1048for (i = 0; i < count; i++) {1049imageToDraw = (i % 2) == 0 ? newImage : img;1050loadImage(imageToDraw);1051graphics.drawImage(imageToDraw, x, y,1052imageObserver);1053Toolkit.getDefaultToolkit().sync();1054sleep(info.flashTime);1055}1056}1057return graphics.drawImage(img, x, y, observer);1058}10591060/**1061* Overrides <code>Graphics.drawImage</code>.1062*/1063public boolean drawImage(Image img, int x, int y, int width, int height,1064ImageObserver observer) {1065DebugGraphicsInfo info = info();10661067if (debugLog()) {1068info.log(toShortString() +1069" Drawing image: " + img +1070" at: " + new Rectangle(x, y, width, height));1071}10721073if (isDrawingBuffer()) {1074if (debugBuffered()) {1075Graphics debugGraphics = debugGraphics();10761077debugGraphics.drawImage(img, x, y, width, height, observer);1078debugGraphics.dispose();1079}1080} else if (debugFlash()) {1081int i, count = (info.flashCount * 2) - 1;1082ImageProducer oldProducer = img.getSource();1083ImageProducer newProducer1084= new FilteredImageSource(oldProducer,1085new DebugGraphicsFilter(info.flashColor));1086Image newImage1087= Toolkit.getDefaultToolkit().createImage(newProducer);1088DebugGraphicsObserver imageObserver1089= new DebugGraphicsObserver();10901091Image imageToDraw;1092for (i = 0; i < count; i++) {1093imageToDraw = (i % 2) == 0 ? newImage : img;1094loadImage(imageToDraw);1095graphics.drawImage(imageToDraw, x, y,1096width, height, imageObserver);1097Toolkit.getDefaultToolkit().sync();1098sleep(info.flashTime);1099}1100}1101return graphics.drawImage(img, x, y, width, height, observer);1102}11031104/**1105* Overrides <code>Graphics.drawImage</code>.1106*/1107public boolean drawImage(Image img, int x, int y,1108Color bgcolor,1109ImageObserver observer) {1110DebugGraphicsInfo info = info();11111112if (debugLog()) {1113info.log(toShortString() +1114" Drawing image: " + img +1115" at: " + new Point(x, y) +1116", bgcolor: " + bgcolor);1117}11181119if (isDrawingBuffer()) {1120if (debugBuffered()) {1121Graphics debugGraphics = debugGraphics();11221123debugGraphics.drawImage(img, x, y, bgcolor, observer);1124debugGraphics.dispose();1125}1126} else if (debugFlash()) {1127int i, count = (info.flashCount * 2) - 1;1128ImageProducer oldProducer = img.getSource();1129ImageProducer newProducer1130= new FilteredImageSource(oldProducer,1131new DebugGraphicsFilter(info.flashColor));1132Image newImage1133= Toolkit.getDefaultToolkit().createImage(newProducer);1134DebugGraphicsObserver imageObserver1135= new DebugGraphicsObserver();11361137Image imageToDraw;1138for (i = 0; i < count; i++) {1139imageToDraw = (i % 2) == 0 ? newImage : img;1140loadImage(imageToDraw);1141graphics.drawImage(imageToDraw, x, y,1142bgcolor, imageObserver);1143Toolkit.getDefaultToolkit().sync();1144sleep(info.flashTime);1145}1146}1147return graphics.drawImage(img, x, y, bgcolor, observer);1148}11491150/**1151* Overrides <code>Graphics.drawImage</code>.1152*/1153public boolean drawImage(Image img, int x, int y,int width, int height,1154Color bgcolor,1155ImageObserver observer) {1156DebugGraphicsInfo info = info();11571158if (debugLog()) {1159info.log(toShortString() +1160" Drawing image: " + img +1161" at: " + new Rectangle(x, y, width, height) +1162", bgcolor: " + bgcolor);1163}11641165if (isDrawingBuffer()) {1166if (debugBuffered()) {1167Graphics debugGraphics = debugGraphics();11681169debugGraphics.drawImage(img, x, y, width, height,1170bgcolor, observer);1171debugGraphics.dispose();1172}1173} else if (debugFlash()) {1174int i, count = (info.flashCount * 2) - 1;1175ImageProducer oldProducer = img.getSource();1176ImageProducer newProducer1177= new FilteredImageSource(oldProducer,1178new DebugGraphicsFilter(info.flashColor));1179Image newImage1180= Toolkit.getDefaultToolkit().createImage(newProducer);1181DebugGraphicsObserver imageObserver1182= new DebugGraphicsObserver();11831184Image imageToDraw;1185for (i = 0; i < count; i++) {1186imageToDraw = (i % 2) == 0 ? newImage : img;1187loadImage(imageToDraw);1188graphics.drawImage(imageToDraw, x, y,1189width, height, bgcolor, imageObserver);1190Toolkit.getDefaultToolkit().sync();1191sleep(info.flashTime);1192}1193}1194return graphics.drawImage(img, x, y, width, height, bgcolor, observer);1195}11961197/**1198* Overrides <code>Graphics.drawImage</code>.1199*/1200public boolean drawImage(Image img,1201int dx1, int dy1, int dx2, int dy2,1202int sx1, int sy1, int sx2, int sy2,1203ImageObserver observer) {1204DebugGraphicsInfo info = info();12051206if (debugLog()) {1207info.log(toShortString() +1208" Drawing image: " + img +1209" destination: " + new Rectangle(dx1, dy1, dx2, dy2) +1210" source: " + new Rectangle(sx1, sy1, sx2, sy2));1211}12121213if (isDrawingBuffer()) {1214if (debugBuffered()) {1215Graphics debugGraphics = debugGraphics();12161217debugGraphics.drawImage(img, dx1, dy1, dx2, dy2,1218sx1, sy1, sx2, sy2, observer);1219debugGraphics.dispose();1220}1221} else if (debugFlash()) {1222int i, count = (info.flashCount * 2) - 1;1223ImageProducer oldProducer = img.getSource();1224ImageProducer newProducer1225= new FilteredImageSource(oldProducer,1226new DebugGraphicsFilter(info.flashColor));1227Image newImage1228= Toolkit.getDefaultToolkit().createImage(newProducer);1229DebugGraphicsObserver imageObserver1230= new DebugGraphicsObserver();12311232Image imageToDraw;1233for (i = 0; i < count; i++) {1234imageToDraw = (i % 2) == 0 ? newImage : img;1235loadImage(imageToDraw);1236graphics.drawImage(imageToDraw,1237dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2,1238imageObserver);1239Toolkit.getDefaultToolkit().sync();1240sleep(info.flashTime);1241}1242}1243return graphics.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2,1244observer);1245}12461247/**1248* Overrides <code>Graphics.drawImage</code>.1249*/1250public boolean drawImage(Image img,1251int dx1, int dy1, int dx2, int dy2,1252int sx1, int sy1, int sx2, int sy2,1253Color bgcolor,1254ImageObserver observer) {1255DebugGraphicsInfo info = info();12561257if (debugLog()) {1258info.log(toShortString() +1259" Drawing image: " + img +1260" destination: " + new Rectangle(dx1, dy1, dx2, dy2) +1261" source: " + new Rectangle(sx1, sy1, sx2, sy2) +1262", bgcolor: " + bgcolor);1263}12641265if (isDrawingBuffer()) {1266if (debugBuffered()) {1267Graphics debugGraphics = debugGraphics();12681269debugGraphics.drawImage(img, dx1, dy1, dx2, dy2,1270sx1, sy1, sx2, sy2, bgcolor, observer);1271debugGraphics.dispose();1272}1273} else if (debugFlash()) {1274int i, count = (info.flashCount * 2) - 1;1275ImageProducer oldProducer = img.getSource();1276ImageProducer newProducer1277= new FilteredImageSource(oldProducer,1278new DebugGraphicsFilter(info.flashColor));1279Image newImage1280= Toolkit.getDefaultToolkit().createImage(newProducer);1281DebugGraphicsObserver imageObserver1282= new DebugGraphicsObserver();12831284Image imageToDraw;1285for (i = 0; i < count; i++) {1286imageToDraw = (i % 2) == 0 ? newImage : img;1287loadImage(imageToDraw);1288graphics.drawImage(imageToDraw,1289dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2,1290bgcolor, imageObserver);1291Toolkit.getDefaultToolkit().sync();1292sleep(info.flashTime);1293}1294}1295return graphics.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2,1296bgcolor, observer);1297}12981299static void loadImage(Image img) {1300imageLoadingIcon.loadImage(img);1301}130213031304/**1305* Overrides <code>Graphics.copyArea</code>.1306*/1307public void copyArea(int x, int y, int width, int height,1308int destX, int destY) {1309if (debugLog()) {1310info().log(toShortString() +1311" Copying area from: " +1312new Rectangle(x, y, width, height) +1313" to: " + new Point(destX, destY));1314}1315graphics.copyArea(x, y, width, height, destX, destY);1316}13171318final void sleep(int mSecs) {1319try {1320Thread.sleep(mSecs);1321} catch (Exception e) {1322}1323}13241325/**1326* Overrides <code>Graphics.dispose</code>.1327*/1328public void dispose() {1329graphics.dispose();1330graphics = null;1331}13321333// ALERT!1334/**1335* Returns the drawingBuffer value.1336*1337* @return true if this object is drawing from a Buffer1338*/1339public boolean isDrawingBuffer() {1340return buffer != null;1341}13421343String toShortString() {1344return "Graphics" + (isDrawingBuffer() ? "<B>" : "") + "(" + graphicsID + "-" + debugOptions + ")";1345}13461347String pointToString(int x, int y) {1348return "(" + x + ", " + y + ")";1349}13501351/** Enables/disables diagnostic information about every graphics1352* operation. The value of <b>options</b> indicates how this information1353* should be displayed. LOG_OPTION causes a text message to be printed.1354* FLASH_OPTION causes the drawing to flash several times. BUFFERED_OPTION1355* creates a new Frame that shows each operation on an1356* offscreen buffer. The value of <b>options</b> is bitwise OR'd into1357* the current value. To disable debugging use NONE_OPTION.1358*1359* @param options indicates how diagnostic information should be displayed1360*/1361public void setDebugOptions(int options) {1362if (options != 0) {1363if (options == NONE_OPTION) {1364if (debugOptions != 0) {1365System.err.println(toShortString() + " Disabling debug");1366debugOptions = 0;1367}1368} else {1369if (debugOptions != options) {1370debugOptions |= options;1371if (debugLog()) {1372System.err.println(toShortString() + " Enabling debug");1373}1374}1375}1376}1377}13781379/**1380* Returns the current debugging options for this DebugGraphics.1381*1382* @return the current debugging options for this DebugGraphics1383* @see #setDebugOptions1384*/1385public int getDebugOptions() {1386return debugOptions;1387}13881389/** Static wrapper method for DebugGraphicsInfo.setDebugOptions(). Stores1390* options on a per component basis.1391*/1392static void setDebugOptions(JComponent component, int options) {1393info().setDebugOptions(component, options);1394}13951396/** Static wrapper method for DebugGraphicsInfo.getDebugOptions().1397*/1398static int getDebugOptions(JComponent component) {1399DebugGraphicsInfo debugGraphicsInfo = info();1400if (debugGraphicsInfo == null) {1401return 0;1402} else {1403return debugGraphicsInfo.getDebugOptions(component);1404}1405}14061407/** Returns non-zero if <b>component</b> should display with DebugGraphics,1408* zero otherwise. Walks the JComponent's parent tree to determine if1409* any debugging options have been set.1410*/1411static int shouldComponentDebug(JComponent component) {1412DebugGraphicsInfo info = info();1413if (info == null) {1414return 0;1415} else {1416Container container = (Container)component;1417int debugOptions = 0;14181419while (container != null && (container instanceof JComponent)) {1420debugOptions |= info.getDebugOptions((JComponent)container);1421container = container.getParent();1422}14231424return debugOptions;1425}1426}14271428/** Returns the number of JComponents that have debugging options turned1429* on.1430*/1431static int debugComponentCount() {1432DebugGraphicsInfo debugGraphicsInfo = info();1433if (debugGraphicsInfo != null &&1434debugGraphicsInfo.componentToDebug != null) {1435return debugGraphicsInfo.componentToDebug.size();1436} else {1437return 0;1438}1439}14401441boolean debugLog() {1442return (debugOptions & LOG_OPTION) == LOG_OPTION;1443}14441445boolean debugFlash() {1446return (debugOptions & FLASH_OPTION) == FLASH_OPTION;1447}14481449boolean debugBuffered() {1450return (debugOptions & BUFFERED_OPTION) == BUFFERED_OPTION;1451}14521453/** Returns a DebugGraphics for use in buffering window.1454*/1455@SuppressWarnings("deprecation")1456private Graphics debugGraphics() {1457DebugGraphics debugGraphics;1458DebugGraphicsInfo info = info();1459JFrame debugFrame;14601461if (info.debugFrame == null) {1462info.debugFrame = new JFrame();1463info.debugFrame.setSize(500, 500);1464}1465debugFrame = info.debugFrame;1466debugFrame.show();1467debugGraphics = new DebugGraphics(debugFrame.getGraphics());1468debugGraphics.setFont(getFont());1469debugGraphics.setColor(getColor());1470debugGraphics.translate(xOffset, yOffset);1471debugGraphics.setClip(getClipBounds());1472if (debugFlash()) {1473debugGraphics.setDebugOptions(FLASH_OPTION);1474}1475return debugGraphics;1476}14771478/** Returns DebugGraphicsInfo, or creates one if none exists.1479*/1480static DebugGraphicsInfo info() {1481DebugGraphicsInfo debugGraphicsInfo = (DebugGraphicsInfo)1482SwingUtilities.appContextGet(debugGraphicsInfoKey);1483if (debugGraphicsInfo == null) {1484debugGraphicsInfo = new DebugGraphicsInfo();1485SwingUtilities.appContextPut(debugGraphicsInfoKey,1486debugGraphicsInfo);1487}1488return debugGraphicsInfo;1489}1490private static final Class<DebugGraphicsInfo> debugGraphicsInfoKey = DebugGraphicsInfo.class;1491}149214931494