001: /*
002: * $Id: CheckerboardPainter.java,v 1.6 2006/05/14 08:12:14 dmouse Exp $
003: *
004: * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005: * Santa Clara, California 95054, U.S.A. All rights reserved.
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
020: */
021:
022: package org.jdesktop.swingx.painter;
023:
024: import java.awt.Color;
025: import java.awt.Graphics2D;
026: import java.awt.Paint;
027: import java.awt.Rectangle;
028: import java.awt.TexturePaint;
029: import java.awt.image.BufferedImage;
030: import javax.swing.JComponent;
031:
032: /**
033: * <p>A Painter implementation that paints a checkerboard pattern. The light
034: * and dark colors (Paint instances) are configurable, as are the size of the
035: * squares (squareLength).</p>
036: *
037: * <p>To configure a checkerboard pattern that used a gradient for the dark
038: * tiles and Color.WHITE for the light tiles, you could:
039: * <pre><code>
040: * GradientPaint gp = new GradientPaint(
041: * new Point2D.Double(0, 0),
042: * Color.BLACK,
043: * new Point2D.Double(0, 32),
044: * Color.GRAY);
045: * CheckerboardPainter p = new CheckerboardPainter();
046: * p.setDarkPaint(gp);
047: * p.setLightPaint(Color.WHITE);
048: * p.setSquareLength(32);
049: * panel.seBackgroundPainter(p);
050: * </code></pre></p>
051: *
052: * <p>Note that in this example, the "32" in the GradientPaint matches the "32"
053: * set for the squareLength. This is necessary because GradientPaints don't
054: * readjust themselves for the size of the square. They are fixed and immutable
055: * at the time of creation.</p>
056: *
057: *
058: *
059: * @author rbair
060: */
061: public class CheckerboardPainter extends AbstractPainter {
062: private transient Paint checkerPaint;
063:
064: private Paint darkPaint = new Color(204, 204, 204);
065: private Paint lightPaint = Color.WHITE;
066: private int squareLength = 8;
067:
068: /**
069: * Create a new CheckerboardPainter. By default the light color is Color.WHITE,
070: * the dark color is a light gray, and the square length is 8.
071: */
072: public CheckerboardPainter() {
073: }
074:
075: /**
076: * Create a new CheckerboardPainter with the specified light and dark paints.
077: * By default the square length is 8.
078: *
079: * @param darkPaint the paint used to draw the dark squares
080: * @param lightPaint the paint used to draw the light squares
081: */
082: public CheckerboardPainter(Paint darkPaint, Paint lightPaint) {
083: this (darkPaint, lightPaint, 8);
084: }
085:
086: /**
087: * Create a new CheckerboardPainter with the specified light and dark paints
088: * and the specified square size.
089: *
090: * @param darkPaint the paint used to draw the dark squares
091: * @param lightPaint the paint used to draw the light squares
092: * @param length the length of the checker board squares
093: */
094: public CheckerboardPainter(Paint darkPaint, Paint lightPaint,
095: int length) {
096: this .darkPaint = darkPaint;
097: this .lightPaint = lightPaint;
098: this .squareLength = length;
099: }
100:
101: /**
102: * Specifies the length of the squares. By default, it is 8. A length of <=
103: * 0 will cause an IllegalArgumentException to be thrown.
104: *
105: * @param length the length of one side of a square tile. Must be > 0.
106: */
107: public void setSquareLength(int length) {
108: if (length <= 0) {
109: throw new IllegalArgumentException("Length must be > 0");
110: }
111:
112: int old = getSquareLength();
113: this .squareLength = length;
114: checkerPaint = null;
115: firePropertyChange("squareLength", old, getSquareLength());
116: }
117:
118: /**
119: * @return the squareLength. Will be > 0
120: */
121: public int getSquareLength() {
122: return squareLength;
123: }
124:
125: /**
126: * Specifies the paint to use for dark tiles. This is a Paint and
127: * may be anything, including a TexturePaint for painting images. If null,
128: * the background color of the component is used.
129: *
130: * @param color the Paint to use for painting the "dark" tiles. May be null.
131: */
132: public void setDarkPaint(Paint color) {
133: Paint old = getDarkPaint();
134: this .darkPaint = color;
135: checkerPaint = null;
136: firePropertyChange("darkPaint", old, getDarkPaint());
137: }
138:
139: /**
140: * @return the Paint used for painting the "dark" tiles. May be null
141: */
142: public Paint getDarkPaint() {
143: return darkPaint;
144: }
145:
146: /**
147: * Specifies the paint to use for light tiles. This is a Paint and
148: * may be anything, including a TexturePaint for painting images. If null,
149: * the foreground color of the component is used.
150: *
151: * @param color the Paint to use for painting the "light" tiles. May be null.
152: */
153: public void setLightPaint(Paint color) {
154: Paint old = getLightPaint();
155: this .lightPaint = color;
156: checkerPaint = null;
157: firePropertyChange("lightPaint", old, getLightPaint());
158: }
159:
160: /**
161: * @return the Paint used for painting the "light" tiles. May be null
162: */
163: public Paint getLightPaint() {
164: return lightPaint;
165: }
166:
167: /**
168: * Helper method that creates and returns the Paint that incorporates the
169: * sizes and light and dark Paints in one TexturePaint. I may want to cache
170: * this value in the future for performance reasons
171: */
172: private Paint getCheckerPaint(JComponent c) {
173: if (checkerPaint == null) {
174: int sqlength = getSquareLength();
175: int length = sqlength * 2;
176: BufferedImage image = new BufferedImage(length, length,
177: BufferedImage.TYPE_INT_ARGB);
178: Graphics2D gfx = image.createGraphics();
179: Paint p = getLightPaint();
180: if (p == null) {
181: p = c.getForeground();
182: }
183: gfx.setPaint(p);
184: gfx.fillRect(0, 0, length, length);
185: p = getDarkPaint();
186: if (p == null) {
187: p = c.getBackground();
188: }
189: gfx.setPaint(p);
190: gfx.fillRect(0, 0, sqlength - 1, sqlength - 1);
191: gfx
192: .fillRect(sqlength, sqlength, sqlength - 1,
193: sqlength - 1);
194: gfx.dispose();
195:
196: checkerPaint = new TexturePaint(image, new Rectangle(0, 0,
197: image.getWidth(), image.getHeight()));
198: }
199: return checkerPaint;
200: }
201:
202: /**
203: * @inheritDoc
204: */
205: public void paintBackground(Graphics2D g, JComponent component) {
206: g.setPaint(getCheckerPaint(component));
207: g.fillRect(0, 0, component.getWidth(), component.getHeight());
208: }
209: }
|