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