001: /*
002: * $Id: MatteBorderExt.java,v 1.4 2005/10/10 18:02:55 rbair 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.border;
023:
024: import java.awt.Color;
025: import java.awt.Component;
026: import java.awt.Graphics;
027: import java.awt.Insets;
028:
029: import javax.swing.Icon;
030: import javax.swing.border.MatteBorder;
031:
032: /**
033: * Matte border that allows specialized icons for corners and sides.
034: *
035: * @author Ramesh Gupta
036: */
037:
038: public class MatteBorderExt extends MatteBorder {
039: protected Icon[] tileIcons = null;
040: private Icon defaultIcon = null;
041:
042: /**
043: * Draws a matte border using specialized icons for corners and sides. If
044: * tileIcons is null, or if the length of tileIcons array is less than 2, this
045: * defaults to the {@link javax.swing.border.MatteBorder superclass} behavior.
046: * Otherwise, tileIcons must specify icons in clockwise order, starting with
047: * the top-left icon at index zero, culminating with the left icon at index 7.
048: * If the length of the tileIcons array is greater than 1, but less than 8,
049: * then tileIcons[0] is used to paint the corners, and tileIcons[1] is used
050: * to paint the sides, with icons rotated as necessary. Other icons, if any,
051: * are ignored.
052: *
053: * @param top top inset
054: * @param left left inset
055: * @param bottom bottom inset
056: * @param right right inset
057: * @param tileIcons array of icons starting with top-left in index 0,
058: * continuing clockwise through the rest of the indices
059: */
060: public MatteBorderExt(int top, int left, int bottom, int right,
061: Icon[] tileIcons) {
062: super (top, left, bottom, right, (tileIcons == null)
063: || (tileIcons.length == 0) ? null : tileIcons[0]);
064: this .tileIcons = tileIcons;
065: }
066:
067: /**
068: * @see MatteBorder#MatteBorder(int, int, int, int, java.awt.Color)
069: */
070: public MatteBorderExt(int top, int left, int bottom, int right,
071: Color matteColor) {
072: super (top, left, bottom, right, matteColor);
073: }
074:
075: /**
076: * @see MatteBorder#MatteBorder(java.awt.Insets, java.awt.Color)
077: */
078: public MatteBorderExt(Insets borderInsets, Color matteColor) {
079: super (borderInsets, matteColor);
080: }
081:
082: /**
083: * @see MatteBorder#MatteBorder(int, int, int, int, javax.swing.Icon)
084: */
085: public MatteBorderExt(int top, int left, int bottom, int right,
086: Icon tileIcon) {
087: super (top, left, bottom, right, tileIcon);
088: }
089:
090: /**
091: * @see MatteBorder#MatteBorder(java.awt.Insets, javax.swing.Icon)
092: */
093: public MatteBorderExt(Insets borderInsets, Icon tileIcon) {
094: super (borderInsets, tileIcon);
095: }
096:
097: /**
098: * @see MatteBorder#MatteBorder(javax.swing.Icon)
099: */
100: public MatteBorderExt(Icon tileIcon) {
101: super (tileIcon);
102: }
103:
104: /**
105: * Returns the icons used by this border
106: *
107: * @return the icons used by this border
108: */
109: public Icon[] getTileIcons() {
110: return tileIcons;
111: }
112:
113: /**
114: * {@inheritDoc}
115: */
116: public void paintBorder(Component c, Graphics g, int x, int y,
117: int width, int height) {
118: if ((tileIcons == null) || (tileIcons.length < 2)) {
119: super .paintBorder(c, g, x, y, width, height);
120: return;
121: }
122:
123: Insets insets = getBorderInsets(c);
124: int clipWidth, clipHeight;
125:
126: clipWidth = Math.min(width, insets.left); // clip to component width or insets
127: clipHeight = Math.min(height, insets.top); // clip to component height or insets
128:
129: if ((clipWidth <= 0) || (clipHeight <= 0)) {
130: return; // nothing to paint
131: }
132:
133: // We now know that we have at least two icons!
134:
135: Color oldColor = g.getColor(); // restore before exiting
136: g.translate(x, y); // restore before exiting
137:
138: for (int i = 0; i < tileIcons.length; i++) {
139: // Make sure we have an icon to paint with
140: if (tileIcons[i] == null) {
141: tileIcons[i] = getDefaultIcon();
142: }
143: }
144:
145: paintTopLeft(c, g, 0, 0, insets.left, insets.top);
146: paintTop(c, g, insets.left, 0, width - insets.left
147: - insets.right, insets.top);
148: paintTopRight(c, g, width - insets.right, 0, insets.right,
149: insets.top);
150: paintRight(c, g, width - insets.right, insets.top,
151: insets.right, height - insets.top - insets.bottom);
152: paintBottomRight(c, g, width - insets.right, height
153: - insets.bottom, insets.right, insets.bottom);
154: paintBottom(c, g, insets.left, height - insets.bottom, width
155: - insets.left - insets.right, insets.bottom);
156: paintBottomLeft(c, g, 0, height - insets.bottom, insets.left,
157: insets.bottom);
158: paintLeft(c, g, 0, insets.top, insets.left, height - insets.top
159: - insets.bottom);
160:
161: g.translate(-x, -y); // restore
162: g.setColor(oldColor); // restore
163:
164: }
165:
166: protected void paint(Icon icon, Component c, Graphics g, int x,
167: int y, int width, int height) {
168: Graphics cg = g.create();
169: cg.setClip(x, y, width, height);
170: int tileW = icon.getIconWidth();
171: int tileH = icon.getIconHeight();
172: int xpos, ypos, startx, starty;
173: for (ypos = 0; height - ypos > 0; ypos += tileH) {
174: for (xpos = 0; width - xpos > 0; xpos += tileW) {
175: icon.paintIcon(c, cg, x + xpos, y + ypos);
176: }
177: }
178: cg.dispose();
179: }
180:
181: /**
182: * Only called by paintBorder()
183: */
184: protected void paintTopLeft(Component c, Graphics g, int x, int y,
185: int width, int height) {
186: Graphics cg = g.create();
187: cg.setClip(x, y, width, height);
188: tileIcons[0].paintIcon(c, cg, x, y);
189: cg.dispose();
190: }
191:
192: /**
193: * Only called by paintBorder()
194: */
195: protected void paintTop(Component c, Graphics g, int x, int y,
196: int width, int height) {
197: paint(tileIcons[1], c, g, x, y, width, height);
198: }
199:
200: /**
201: * Only called by paintBorder()
202: */
203: protected void paintTopRight(Component c, Graphics g, int x, int y,
204: int width, int height) {
205: if (tileIcons.length == 8) {
206: paint(tileIcons[2], c, g, x, y, width, height);
207: } else {
208: Icon icon = tileIcons[0];
209: /** @todo Rotate -90 and paint icon */
210: }
211: }
212:
213: /**
214: * Only called by paintBorder()
215: */
216: protected void paintRight(Component c, Graphics g, int x, int y,
217: int width, int height) {
218: if (tileIcons.length == 8) {
219: paint(tileIcons[3], c, g, x, y, width, height);
220: } else {
221: Icon icon = tileIcons[1];
222: /** @todo Rotate -90 and paint icon */
223: }
224: }
225:
226: /**
227: * Only called by paintBorder()
228: */
229: protected void paintBottomRight(Component c, Graphics g, int x,
230: int y, int width, int height) {
231: if (tileIcons.length == 8) {
232: paint(tileIcons[4], c, g, x, y, width, height);
233: } else {
234: Icon icon = tileIcons[0];
235: /** @todo Rotate -180 and paint icon */
236: }
237: }
238:
239: /**
240: * Only called by paintBorder()
241: */
242: protected void paintBottom(Component c, Graphics g, int x, int y,
243: int width, int height) {
244: if (tileIcons.length == 8) {
245: paint(tileIcons[5], c, g, x, y, width, height);
246: } else {
247: Icon icon = tileIcons[1];
248: /** @todo Rotate -180 and paint icon */
249: }
250: }
251:
252: /**
253: * Only called by paintBorder()
254: */
255: protected void paintBottomLeft(Component c, Graphics g, int x,
256: int y, int width, int height) {
257: if (tileIcons.length == 8) {
258: paint(tileIcons[6], c, g, x, y, width, height);
259: } else {
260: Icon icon = tileIcons[0];
261: /** @todo Rotate -270 and paint icon */
262: }
263: }
264:
265: /**
266: * Only called by paintBorder()
267: */
268: protected void paintLeft(Component c, Graphics g, int x, int y,
269: int width, int height) {
270: if (tileIcons.length == 8) {
271: paint(tileIcons[7], c, g, x, y, width, height);
272: } else {
273: Icon icon = tileIcons[1];
274: /** @todo Rotate -270 and paint icon */
275: }
276: }
277:
278: /**
279: * Only called by paintBorder()
280: */
281: protected Icon getDefaultIcon() {
282: if (defaultIcon == null) {
283: defaultIcon = new Icon() {
284: private int width = 3;
285: private int height = 3;
286:
287: public int getIconWidth() {
288: return width;
289: }
290:
291: public int getIconHeight() {
292: return height;
293: }
294:
295: public void paintIcon(Component c, Graphics g, int x,
296: int y) {
297: g.setColor(c.getBackground().darker().darker());
298: //g.translate(x, y);
299: g.fillRect(x, y, width, height);
300: }
301: };
302: }
303: return defaultIcon;
304: }
305: }
|