GNU Classpath (0.18) | ||
Frames | No Frames |
1: /* EtchedBorder.java -- 2: Copyright (C) 2003 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package javax.swing.border; 40: 41: import java.awt.Color; 42: import java.awt.Component; 43: import java.awt.Graphics; 44: import java.awt.Insets; 45: 46: 47: /** 48: * A border that looks like an engraving etched into the background 49: * surface, or (in its raised variant) coming out of the surface 50: * plane. Using different constructors, it is possible to either 51: * explicitly specify the border colors, or to let the colors derive 52: * from the background color of the enclosed Component. 53: * 54: * <p><img src="doc-files/EtchedBorder-1.png" width="500" height="200" 55: * alt="[An illustration of the two EtchedBorder variants]" /> 56: * 57: * @author Sascha Brawer (brawer@dandelis.ch) 58: */ 59: public class EtchedBorder 60: extends AbstractBorder 61: { 62: /** 63: * Determined using the <code>serialver</code> tool 64: * of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5. 65: */ 66: static final long serialVersionUID = 4001244046866360638L; 67: 68: 69: /** 70: * Indicates that the border appears as coming out of the 71: * background. 72: */ 73: public static final int RAISED = 0; 74: 75: 76: /** 77: * Indicates that the border appears as engraved into the 78: * background. 79: */ 80: public static final int LOWERED = 1; 81: 82: 83: /** 84: * The type of this EtchedBorder, which is either {@link #RAISED} 85: * or {@link #LOWERED}. 86: */ 87: protected int etchType; 88: 89: 90: /** 91: * The highlight color, or <code>null</code> to indicate that the 92: * color shall be derived from the background of the enclosed 93: * component. 94: */ 95: protected Color highlight; 96: 97: 98: /** 99: * The shadow color, or <code>null</code> to indicate that the 100: * color shall be derived from the background of the enclosed 101: * component. 102: */ 103: protected Color shadow; 104: 105: 106: /** 107: * Constructs a lowered EtchedBorder. The colors will be derived 108: * from the background color of the enclosed Component when the 109: * border gets painted. 110: */ 111: public EtchedBorder() 112: { 113: this(LOWERED); 114: } 115: 116: 117: /** 118: * Constructs an EtchedBorder with the specified appearance. The 119: * colors will be derived from the background color of the enclosed 120: * Component when the border gets painted. 121: * 122: * <p><img src="doc-files/EtchedBorder-1.png" width="500" height="200" 123: * alt="[An illustration of the two EtchedBorder variants]" /> 124: * 125: * @param etchType the desired appearance of the border. The value 126: * must be either {@link #RAISED} or {@link #LOWERED}. 127: * 128: * @throws IllegalArgumentException if <code>etchType</code> has 129: * an unsupported value. 130: */ 131: public EtchedBorder(int etchType) 132: { 133: if ((etchType != RAISED) && (etchType != LOWERED)) 134: throw new IllegalArgumentException(); 135: 136: this.etchType = etchType; 137: 138: /* The highlight and shadow fields already have a null value 139: * when the constructor gets called, so there is no need to 140: * assign a value here. 141: */ 142: } 143: 144: 145: /** 146: * Constructs a lowered EtchedBorder, explicitly selecting the 147: * colors that will be used for highlight and shadow. 148: * 149: * @param highlight the color that will be used for painting 150: * the highlight part of the border. 151: * 152: * @param shadow the color that will be used for painting 153: * the shadow part of the border. 154: * 155: * @see #EtchedBorder(int, Color, Color) 156: */ 157: public EtchedBorder(Color highlight, Color shadow) 158: { 159: this(LOWERED, highlight, shadow); 160: } 161: 162: 163: /** 164: * Constructs an EtchedBorder with the specified appearance, 165: * explicitly selecting the colors that will be used for 166: * highlight and shadow. 167: * 168: * <p><img src="doc-files/EtchedBorder-2.png" width="500" height="200" 169: * alt="[An illustration that shows which pixels get painted 170: * in what color]" /> 171: * 172: * @param etchType the desired appearance of the border. The value 173: * must be either {@link #RAISED} or {@link #LOWERED}. 174: * 175: * @param highlight the color that will be used for painting 176: * the highlight part of the border. 177: * 178: * @param shadow the color that will be used for painting 179: * the shadow part of the border. 180: * 181: * @throws IllegalArgumentException if <code>etchType</code> has 182: * an unsupported value. 183: */ 184: public EtchedBorder(int etchType, Color highlight, Color shadow) 185: { 186: this(etchType); // Checks the validity of the value. 187: this.highlight = highlight; 188: this.shadow = shadow; 189: } 190: 191: 192: /** 193: * Paints the border for a given component. 194: * 195: * @param c the component whose border is to be painted. 196: * @param g the graphics for painting. 197: * @param x the horizontal position for painting the border. 198: * @param y the vertical position for painting the border. 199: * @param width the width of the available area for painting the border. 200: * @param height the height of the available area for painting the border. 201: */ 202: public void paintBorder(Component c, Graphics g, 203: int x, int y, int width, int height) 204: { 205: switch (etchType) 206: { 207: case RAISED: 208: paintEtchedBorder(g, x, y, width, height, 209: getHighlightColor(c), getShadowColor(c)); 210: break; 211: 212: case LOWERED: 213: paintEtchedBorder(g, x, y, width, height, 214: getShadowColor(c), getHighlightColor(c)); 215: break; 216: } 217: } 218: 219: 220: /** 221: * Measures the width of this border. 222: * 223: * @param c the component whose border is to be measured. 224: * 225: * @return an Insets object whose <code>left</code>, <code>right</code>, 226: * <code>top</code> and <code>bottom</code> fields indicate the 227: * width of the border at the respective edge. 228: * 229: * @see #getBorderInsets(java.awt.Component, java.awt.Insets) 230: */ 231: public Insets getBorderInsets(Component c) 232: { 233: return new Insets(2, 2, 2, 2); 234: } 235: 236: 237: /** 238: * Measures the width of this border, storing the results into a 239: * pre-existing Insets object. 240: * 241: * @param insets an Insets object for holding the result values. 242: * After invoking this method, the <code>left</code>, 243: * <code>right</code>, <code>top</code> and 244: * <code>bottom</code> fields indicate the width of the 245: * border at the respective edge. 246: * 247: * @return the same object that was passed for <code>insets</code>. 248: * 249: * @see #getBorderInsets(Component) 250: */ 251: public Insets getBorderInsets(Component c, Insets insets) 252: { 253: insets.left = insets.right = insets.top = insets.bottom = 2; 254: return insets; 255: } 256: 257: 258: /** 259: * Determines whether this border fills every pixel in its area 260: * when painting. 261: * 262: * <p>If the border colors are derived from the background color of 263: * the enclosed component, the result is <code>true</code> because 264: * the derivation method always returns opaque colors. Otherwise, 265: * the result depends on the opacity of the individual colors. 266: * 267: * @return <code>true</code> if the border is fully opaque, or 268: * <code>false</code> if some pixels of the background 269: * can shine through the border. 270: */ 271: public boolean isBorderOpaque() 272: { 273: /* If the colors are to be drived from the enclosed Component's 274: * background color, the border is guaranteed to be fully opaque 275: * because Color.brighten() and Color.darken() always return an 276: * opaque color. 277: */ 278: return 279: ((highlight == null) || (highlight.getAlpha() == 255)) 280: && ((shadow == null) || (shadow.getAlpha() == 255)); 281: } 282: 283: 284: /** 285: * Returns the appearance of this EtchedBorder, which is either 286: * {@link #RAISED} or {@link #LOWERED}. 287: */ 288: public int getEtchType() 289: { 290: return etchType; 291: } 292: 293: 294: /** 295: * Determines the color that will be used for highlighted parts when 296: * painting the border around a given component. If a highlight 297: * color has been specified upon constructing the border, that color 298: * is returned. Otherwise, the background color of the enclosed 299: * component is brightened. 300: * 301: * @param c the component enclosed by this border. 302: * 303: * @see java.awt.Component#getBackground() 304: * @see java.awt.Color#brighter() 305: */ 306: public Color getHighlightColor(Component c) 307: { 308: if (highlight != null) 309: return highlight; 310: else 311: return c.getBackground().brighter(); 312: } 313: 314: 315: /** 316: * Returns the color that will be used for highlighted parts when 317: * painting the border, or <code>null</code> if that color will be 318: * derived from the background of the enclosed Component. 319: */ 320: public Color getHighlightColor() 321: { 322: return highlight; 323: } 324: 325: 326: /** 327: * Determines the color that will be used for shadowed parts when 328: * painting the border around a given component. If a shadow color 329: * has been specified upon constructing the border, that color is 330: * returned. Otherwise, the background color of the enclosed 331: * component is darkened. 332: * 333: * @param c the component enclosed by this border. 334: * 335: * @see java.awt.Component#getBackground() 336: * @see java.awt.Color#darker() 337: */ 338: public Color getShadowColor(Component c) 339: { 340: if (shadow != null) 341: return shadow; 342: else 343: return c.getBackground().darker(); 344: } 345: 346: 347: /** 348: * Returns the color that will be used for shadowed parts when 349: * painting the border, or <code>null</code> if that color will be 350: * derived from the background of the enclosed Component. 351: */ 352: public Color getShadowColor() 353: { 354: return shadow; 355: } 356: 357: 358: /** 359: * Paints a two-pixel etching in two colors. 360: * 361: * <pre> 362: * @@@@@@@@@@@. 363: * @.........@. @ = color a 364: * @. @. . = color b 365: * @. @. 366: * @@@@@@@@@@@. 367: * ............</pre> 368: * 369: * @param g the graphics for painting. 370: * @param x the horizontal position for painting the border. 371: * @param y the vertical position for painting the border. 372: * @param width the width of the available area for painting the border. 373: * @param height the height of the available area for painting the border. 374: * @param a one of the two colors. 375: * @param b the second of the two colors. 376: */ 377: private static void paintEtchedBorder(Graphics g, 378: int x, int y, int width, int height, 379: Color a, Color b) 380: { 381: Color oldColor; 382: 383: oldColor = g.getColor(); 384: g.translate(x, y); 385: width = width - 1; 386: height = height - 1; 387: 388: try 389: { 390: /* To understand this code, it might be helpful to look at the 391: * images that are included with the JavaDoc. They are located 392: * in the "doc-files" subdirectory. EtchedBorder-2.png might 393: * be especially informative. 394: */ 395: g.setColor(a); 396: g.drawRect(0, 0, width - 1, height - 1); 397: 398: g.setColor(b); 399: g.drawLine(1, 1, width - 2, 1); // top edge 400: g.drawLine(1, 2, 1, height - 2); // left edge 401: g.drawLine(0, height, width, height); // bottom edge 402: g.drawLine(width, 0, width, height - 1); // right edge 403: } 404: finally 405: { 406: g.translate(-x, -y); 407: g.setColor(oldColor); 408: } 409: } 410: }
GNU Classpath (0.18) |