001 /*
002 * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025 package javax.swing.border;
026
027 import java.awt.Graphics;
028 import java.awt.Insets;
029 import java.awt.Rectangle;
030 import java.awt.Component;
031 import java.awt.Color;
032
033 import javax.swing.Icon;
034
035 /**
036 * A class which provides a matte-like border of either a solid color
037 * or a tiled icon.
038 * <p>
039 * <strong>Warning:</strong>
040 * Serialized objects of this class will not be compatible with
041 * future Swing releases. The current serialization support is
042 * appropriate for short term storage or RMI between applications running
043 * the same version of Swing. As of 1.4, support for long term storage
044 * of all JavaBeans<sup><font size="-2">TM</font></sup>
045 * has been added to the <code>java.beans</code> package.
046 * Please see {@link java.beans.XMLEncoder}.
047 *
048 * @version 1.30 05/05/07
049 * @author Amy Fowler
050 */
051 public class MatteBorder extends EmptyBorder {
052 protected Color color;
053 protected Icon tileIcon;
054
055 /**
056 * Creates a matte border with the specified insets and color.
057 * @param top the top inset of the border
058 * @param left the left inset of the border
059 * @param bottom the bottom inset of the border
060 * @param right the right inset of the border
061 * @param matteColor the color rendered for the border
062 */
063 public MatteBorder(int top, int left, int bottom, int right,
064 Color matteColor) {
065 super (top, left, bottom, right);
066 this .color = matteColor;
067 }
068
069 /**
070 * Creates a matte border with the specified insets and color.
071 * @param borderInsets the insets of the border
072 * @param matteColor the color rendered for the border
073 * @since 1.3
074 */
075 public MatteBorder(Insets borderInsets, Color matteColor) {
076 super (borderInsets);
077 this .color = matteColor;
078 }
079
080 /**
081 * Creates a matte border with the specified insets and tile icon.
082 * @param top the top inset of the border
083 * @param left the left inset of the border
084 * @param bottom the bottom inset of the border
085 * @param right the right inset of the border
086 * @param tileIcon the icon to be used for tiling the border
087 */
088 public MatteBorder(int top, int left, int bottom, int right,
089 Icon tileIcon) {
090 super (top, left, bottom, right);
091 this .tileIcon = tileIcon;
092 }
093
094 /**
095 * Creates a matte border with the specified insets and tile icon.
096 * @param borderInsets the insets of the border
097 * @param tileIcon the icon to be used for tiling the border
098 * @since 1.3
099 */
100 public MatteBorder(Insets borderInsets, Icon tileIcon) {
101 super (borderInsets);
102 this .tileIcon = tileIcon;
103 }
104
105 /**
106 * Creates a matte border with the specified tile icon. The
107 * insets will be calculated dynamically based on the size of
108 * the tile icon, where the top and bottom will be equal to the
109 * tile icon's height, and the left and right will be equal to
110 * the tile icon's width.
111 * @param tileIcon the icon to be used for tiling the border
112 */
113 public MatteBorder(Icon tileIcon) {
114 this (-1, -1, -1, -1, tileIcon);
115 }
116
117 /**
118 * Paints the matte border.
119 */
120 public void paintBorder(Component c, Graphics g, int x, int y,
121 int width, int height) {
122 Insets insets = getBorderInsets(c);
123 Color oldColor = g.getColor();
124 g.translate(x, y);
125
126 // If the tileIcon failed loading, paint as gray.
127 if (tileIcon != null) {
128 color = (tileIcon.getIconWidth() == -1) ? Color.gray : null;
129 }
130
131 if (color != null) {
132 g.setColor(color);
133 g.fillRect(0, 0, width - insets.right, insets.top);
134 g.fillRect(0, insets.top, insets.left, height - insets.top);
135 g.fillRect(insets.left, height - insets.bottom, width
136 - insets.left, insets.bottom);
137 g.fillRect(width - insets.right, 0, insets.right, height
138 - insets.bottom);
139
140 } else if (tileIcon != null) {
141
142 int tileW = tileIcon.getIconWidth();
143 int tileH = tileIcon.getIconHeight();
144 int xpos, ypos, startx, starty;
145 Graphics cg;
146
147 // Paint top matte edge
148 cg = g.create();
149 cg.setClip(0, 0, width, insets.top);
150 for (ypos = 0; insets.top - ypos > 0; ypos += tileH) {
151 for (xpos = 0; width - xpos > 0; xpos += tileW) {
152 tileIcon.paintIcon(c, cg, xpos, ypos);
153 }
154 }
155 cg.dispose();
156
157 // Paint left matte edge
158 cg = g.create();
159 cg.setClip(0, insets.top, insets.left, height - insets.top);
160 starty = insets.top - (insets.top % tileH);
161 startx = 0;
162 for (ypos = starty; height - ypos > 0; ypos += tileH) {
163 for (xpos = startx; insets.left - xpos > 0; xpos += tileW) {
164 tileIcon.paintIcon(c, cg, xpos, ypos);
165 }
166 }
167 cg.dispose();
168
169 // Paint bottom matte edge
170 cg = g.create();
171 cg.setClip(insets.left, height - insets.bottom, width
172 - insets.left, insets.bottom);
173 starty = (height - insets.bottom)
174 - ((height - insets.bottom) % tileH);
175 startx = insets.left - (insets.left % tileW);
176 for (ypos = starty; height - ypos > 0; ypos += tileH) {
177 for (xpos = startx; width - xpos > 0; xpos += tileW) {
178 tileIcon.paintIcon(c, cg, xpos, ypos);
179 }
180 }
181 cg.dispose();
182
183 // Paint right matte edge
184 cg = g.create();
185 cg.setClip(width - insets.right, insets.top, insets.right,
186 height - insets.top - insets.bottom);
187 starty = insets.top - (insets.top % tileH);
188 startx = width - insets.right
189 - ((width - insets.right) % tileW);
190 for (ypos = starty; height - ypos > 0; ypos += tileH) {
191 for (xpos = startx; width - xpos > 0; xpos += tileW) {
192 tileIcon.paintIcon(c, cg, xpos, ypos);
193 }
194 }
195 cg.dispose();
196 }
197 g.translate(-x, -y);
198 g.setColor(oldColor);
199
200 }
201
202 /**
203 * Returns the insets of the border.
204 * @param c the component for which this border insets value applies
205 * @since 1.3
206 */
207 public Insets getBorderInsets(Component c) {
208 return getBorderInsets();
209 }
210
211 /**
212 * Reinitialize the insets parameter with this Border's current Insets.
213 * @param c the component for which this border insets value applies
214 * @param insets the object to be reinitialized
215 * @since 1.3
216 */
217 public Insets getBorderInsets(Component c, Insets insets) {
218 return computeInsets(insets);
219 }
220
221 /**
222 * Returns the insets of the border.
223 * @since 1.3
224 */
225 public Insets getBorderInsets() {
226 return computeInsets(new Insets(0, 0, 0, 0));
227 }
228
229 /* should be protected once api changes area allowed */
230 private Insets computeInsets(Insets insets) {
231 if (tileIcon != null && top == -1 && bottom == -1 && left == -1
232 && right == -1) {
233 int w = tileIcon.getIconWidth();
234 int h = tileIcon.getIconHeight();
235 insets.top = h;
236 insets.right = w;
237 insets.bottom = h;
238 insets.left = w;
239 } else {
240 insets.left = left;
241 insets.top = top;
242 insets.right = right;
243 insets.bottom = bottom;
244 }
245 return insets;
246 }
247
248 /**
249 * Returns the color used for tiling the border or null
250 * if a tile icon is being used.
251 * @since 1.3
252 */
253 public Color getMatteColor() {
254 return color;
255 }
256
257 /**
258 * Returns the icon used for tiling the border or null
259 * if a solid color is being used.
260 * @since 1.3
261 */
262 public Icon getTileIcon() {
263 return tileIcon;
264 }
265
266 /**
267 * Returns whether or not the border is opaque.
268 */
269 public boolean isBorderOpaque() {
270 // If a tileIcon is set, then it may contain transparent bits
271 return color != null;
272 }
273
274 }
|