001 /* 002 * $Id: PinstripePainter.java,v 1.5 2006/05/14 15:55:54 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.Graphics2D; 025 import java.awt.Paint; 026 import java.awt.geom.Line2D; 027 import java.awt.geom.Point2D; 028 import java.awt.geom.Rectangle2D; 029 import javax.swing.JComponent; 030 031 /** 032 * <p>A fun Painter that paints pinstripes. You can specify the Paint to paint 033 * those pinstripes in (could even be a texture paint!), the angle at which 034 * to paint the pinstripes, and the spacing between stripes.</p> 035 * 036 * <p>The default PinstripePainter configuration will paint the pinstripes 037 * using the foreground color of the component (the default behavior if a 038 * Paint is not specified) at a 45 degree angle with 8 pixels between stripes</p> 039 * 040 * <p>Here is a custom code snippet that paints Color.GRAY pinstripes at a 135 041 * degree angle: 042 * <pre><code> 043 * PinstripePainter p = new PinstripePainter(); 044 * p.setAngle(135); 045 * p.setPaint(Color.GRAY); 046 * </code></pre> 047 * 048 * @author rbair 049 */ 050 public class PinstripePainter extends AbstractPainter { 051 /** 052 * The angle in degrees to paint the pinstripes at. The default 053 * value is 45. The value will be between 0 and 360 inclusive. The 054 * setAngle method will ensure this. 055 */ 056 private double angle = 45; 057 /** 058 * The spacing between pinstripes 059 */ 060 private double spacing = 8; 061 /** 062 * The Paint to use when drawing the pinstripes 063 */ 064 private Paint paint; 065 066 /** 067 * Create a new PinstripePainter. By default the angle with be 45 degrees, 068 * the spacing will be 8 pixels, and the color will be the Component foreground 069 * color. 070 */ 071 public PinstripePainter() { 072 } 073 074 /** 075 * Create a new PinstripePainter using an angle of 45, 8 pixel spacing, 076 * and the given Paint. 077 * 078 * @param paint the paint used when drawing the stripes 079 */ 080 public PinstripePainter(Paint paint) { 081 this(paint, 45); 082 } 083 084 /** 085 * Create a new PinstripePainter using the given angle, 8 pixel spacing, 086 * and the given Paint 087 * 088 * @param paint the paint used when drawing the stripes 089 * @param angle the angle, in degrees, in which to paint the pinstripes 090 */ 091 public PinstripePainter(Paint paint, double angle) { 092 this.paint = paint; 093 this.angle = angle; 094 } 095 096 /** 097 * Create a new PinstripePainter using the given angle, 8 pixel spacing, 098 * and the foreground color of the Component 099 * 100 * @param angle the angle, in degrees, in which to paint the pinstripes 101 */ 102 public PinstripePainter(double angle) { 103 this.angle = angle; 104 } 105 106 /** 107 * Set the paint to use for drawing the pinstripes 108 * 109 * @param p the Paint to use. May be a Color. 110 */ 111 public void setPaint(Paint p) { 112 Paint old = getPaint(); 113 this.paint = p; 114 firePropertyChange("paint", old, getPaint()); 115 } 116 117 /** 118 * @return the Paint to use to draw the pinstripes 119 */ 120 public Paint getPaint() { 121 return paint; 122 } 123 124 /** 125 * Sets the angle, in degrees, at which to paint the pinstripes. If the 126 * given angle is < 0 or > 360, it will be appropriately constrained. For 127 * example, if a value of 365 is given, it will result in 5 degrees. The 128 * conversion is not perfect, but "a man on a galloping horse won't be 129 * able to tell the difference". 130 * 131 * @param angle the Angle in degrees at which to paint the pinstripes 132 */ 133 public void setAngle(double angle) { 134 if (angle > 360) { 135 angle = angle % 360; 136 } 137 138 if (angle < 0) { 139 angle = 360 - ((angle * -1) % 360); 140 } 141 142 double old = getAngle(); 143 this.angle = angle; 144 firePropertyChange("angle", old, getAngle()); 145 } 146 147 /** 148 * @return the angle, in degrees, at which the pinstripes are painted 149 */ 150 public double getAngle() { 151 return angle; 152 } 153 154 /** 155 * Sets the spacing between pinstripes 156 * 157 * @param spacing spacing between pinstripes 158 */ 159 public void setSpacing(double spacing) { 160 double old = getSpacing(); 161 this.spacing = spacing; 162 firePropertyChange("spacing", old, getSpacing()); 163 } 164 165 /** 166 * @return the spacing between pinstripes 167 */ 168 public double getSpacing() { 169 return spacing; 170 } 171 172 /** 173 * @inheritDoc 174 */ 175 public void paintBackground(Graphics2D g, JComponent component) { 176 //draws pinstripes at the angle specified in this class 177 //and at the given distance apart 178 Paint p = getPaint(); 179 if (p == null) { 180 g.setColor(component.getForeground()); 181 } else { 182 g.setPaint(p); 183 } 184 185 double hypLength = Math.sqrt((component.getWidth() * component.getWidth()) + 186 (component.getHeight() * component.getHeight())); 187 188 double radians = Math.toRadians(getAngle()); 189 g.rotate(radians); 190 191 int numLines = (int)(hypLength / getSpacing()); 192 193 for (int i=0; i<numLines; i++) { 194 double x = i * getSpacing(); 195 Line2D line = new Line2D.Double(x, -hypLength, x, hypLength); 196 g.draw(line); 197 } 198 } 199 }