blob: 5cc89da6509d854436a7663ad2b9a8a02111c59a [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1997-2006 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25package javax.swing.border;
26
27import java.awt.Graphics;
28import java.awt.Insets;
29import java.awt.Rectangle;
30import java.awt.Component;
31import java.awt.Color;
32
33import javax.swing.Icon;
34
35/**
36 * A class which provides a matte-like border of either a solid color
37 * or a tiled icon.
38 * <p>
39 * <strong>Warning:</strong>
40 * Serialized objects of this class will not be compatible with
41 * future Swing releases. The current serialization support is
42 * appropriate for short term storage or RMI between applications running
43 * the same version of Swing. As of 1.4, support for long term storage
44 * of all JavaBeans<sup><font size="-2">TM</font></sup>
45 * has been added to the <code>java.beans</code> package.
46 * Please see {@link java.beans.XMLEncoder}.
47 *
48 * @author Amy Fowler
49 */
50public class MatteBorder extends EmptyBorder
51{
52 protected Color color;
53 protected Icon tileIcon;
54
55 /**
56 * Creates a matte border with the specified insets and color.
57 * @param top the top inset of the border
58 * @param left the left inset of the border
59 * @param bottom the bottom inset of the border
60 * @param right the right inset of the border
61 * @param matteColor the color rendered for the border
62 */
63 public MatteBorder(int top, int left, int bottom, int right, Color matteColor) {
64 super(top, left, bottom, right);
65 this.color = matteColor;
66 }
67
68 /**
69 * Creates a matte border with the specified insets and color.
70 * @param borderInsets the insets of the border
71 * @param matteColor the color rendered for the border
72 * @since 1.3
73 */
74 public MatteBorder(Insets borderInsets, Color matteColor) {
75 super(borderInsets);
76 this.color = matteColor;
77 }
78
79 /**
80 * Creates a matte border with the specified insets and tile icon.
81 * @param top the top inset of the border
82 * @param left the left inset of the border
83 * @param bottom the bottom inset of the border
84 * @param right the right inset of the border
85 * @param tileIcon the icon to be used for tiling the border
86 */
87 public MatteBorder(int top, int left, int bottom, int right, Icon tileIcon) {
88 super(top, left, bottom, right);
89 this.tileIcon = tileIcon;
90 }
91
92 /**
93 * Creates a matte border with the specified insets and tile icon.
94 * @param borderInsets the insets of the border
95 * @param tileIcon the icon to be used for tiling the border
96 * @since 1.3
97 */
98 public MatteBorder(Insets borderInsets, Icon tileIcon) {
99 super(borderInsets);
100 this.tileIcon = tileIcon;
101 }
102
103 /**
104 * Creates a matte border with the specified tile icon. The
105 * insets will be calculated dynamically based on the size of
106 * the tile icon, where the top and bottom will be equal to the
107 * tile icon's height, and the left and right will be equal to
108 * the tile icon's width.
109 * @param tileIcon the icon to be used for tiling the border
110 */
111 public MatteBorder(Icon tileIcon) {
112 this(-1,-1,-1,-1, tileIcon);
113 }
114
115 /**
116 * Paints the matte border.
117 */
118 public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
119 Insets insets = getBorderInsets(c);
120 Color oldColor = g.getColor();
121 g.translate(x, y);
122
123 // If the tileIcon failed loading, paint as gray.
124 if (tileIcon != null) {
125 color = (tileIcon.getIconWidth() == -1) ? Color.gray : null;
126 }
127
128 if (color != null) {
129 g.setColor(color);
130 g.fillRect(0, 0, width - insets.right, insets.top);
131 g.fillRect(0, insets.top, insets.left, height - insets.top);
132 g.fillRect(insets.left, height - insets.bottom, width - insets.left, insets.bottom);
133 g.fillRect(width - insets.right, 0, insets.right, height - insets.bottom);
134
135 } else if (tileIcon != null) {
136
137 int tileW = tileIcon.getIconWidth();
138 int tileH = tileIcon.getIconHeight();
139 int xpos, ypos, startx, starty;
140 Graphics cg;
141
142 // Paint top matte edge
143 cg = g.create();
144 cg.setClip(0, 0, width, insets.top);
145 for (ypos = 0; insets.top - ypos > 0; ypos += tileH) {
146 for (xpos = 0; width - xpos > 0; xpos += tileW) {
147 tileIcon.paintIcon(c, cg, xpos, ypos);
148 }
149 }
150 cg.dispose();
151
152 // Paint left matte edge
153 cg = g.create();
154 cg.setClip(0, insets.top, insets.left, height - insets.top);
155 starty = insets.top - (insets.top%tileH);
156 startx = 0;
157 for (ypos = starty; height - ypos > 0; ypos += tileH) {
158 for (xpos = startx; insets.left - xpos > 0; xpos += tileW) {
159 tileIcon.paintIcon(c, cg, xpos, ypos);
160 }
161 }
162 cg.dispose();
163
164 // Paint bottom matte edge
165 cg = g.create();
166 cg.setClip(insets.left, height - insets.bottom, width - insets.left, insets.bottom);
167 starty = (height - insets.bottom) - ((height - insets.bottom)%tileH);
168 startx = insets.left - (insets.left%tileW);
169 for (ypos = starty; height - ypos > 0; ypos += tileH) {
170 for (xpos = startx; width - xpos > 0; xpos += tileW) {
171 tileIcon.paintIcon(c, cg, xpos, ypos);
172 }
173 }
174 cg.dispose();
175
176 // Paint right matte edge
177 cg = g.create();
178 cg.setClip(width - insets.right, insets.top, insets.right, height - insets.top - insets.bottom);
179 starty = insets.top - (insets.top%tileH);
180 startx = width - insets.right - ((width - insets.right)%tileW);
181 for (ypos = starty; height - ypos > 0; ypos += tileH) {
182 for (xpos = startx; width - xpos > 0; xpos += tileW) {
183 tileIcon.paintIcon(c, cg, xpos, ypos);
184 }
185 }
186 cg.dispose();
187 }
188 g.translate(-x, -y);
189 g.setColor(oldColor);
190
191 }
192
193 /**
194 * Reinitialize the insets parameter with this Border's current Insets.
195 * @param c the component for which this border insets value applies
196 * @param insets the object to be reinitialized
197 * @since 1.3
198 */
199 public Insets getBorderInsets(Component c, Insets insets) {
200 return computeInsets(insets);
201 }
202
203 /**
204 * Returns the insets of the border.
205 * @since 1.3
206 */
207 public Insets getBorderInsets() {
208 return computeInsets(new Insets(0,0,0,0));
209 }
210
211 /* should be protected once api changes area allowed */
212 private Insets computeInsets(Insets insets) {
213 if (tileIcon != null && top == -1 && bottom == -1 &&
214 left == -1 && right == -1) {
215 int w = tileIcon.getIconWidth();
216 int h = tileIcon.getIconHeight();
217 insets.top = h;
218 insets.right = w;
219 insets.bottom = h;
220 insets.left = w;
221 } else {
222 insets.left = left;
223 insets.top = top;
224 insets.right = right;
225 insets.bottom = bottom;
226 }
227 return insets;
228 }
229
230 /**
231 * Returns the color used for tiling the border or null
232 * if a tile icon is being used.
233 * @since 1.3
234 */
235 public Color getMatteColor() {
236 return color;
237 }
238
239 /**
240 * Returns the icon used for tiling the border or null
241 * if a solid color is being used.
242 * @since 1.3
243 */
244 public Icon getTileIcon() {
245 return tileIcon;
246 }
247
248 /**
249 * Returns whether or not the border is opaque.
250 */
251 public boolean isBorderOpaque() {
252 // If a tileIcon is set, then it may contain transparent bits
253 return color != null;
254 }
255
256}