GNU Classpath (0.20) | |
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 extends AbstractBorder 60: { 61: /** 62: * Determined using the <code>serialver</code> tool 63: * of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5. 64: */ 65: static final long serialVersionUID = 4001244046866360638L; 66: 67: 68: /** 69: * Indicates that the border appears as coming out of the 70: * background. 71: */ 72: public static final int RAISED = 0; 73: 74: 75: /** 76: * Indicates that the border appears as engraved into the 77: * background. 78: */ 79: public static final int LOWERED = 1; 80: 81: 82: /** 83: * The type of this EtchedBorder, which is either {@link #RAISED} 84: * or {@link #LOWERED}. 85: */ 86: protected int etchType; 87: 88: 89: /** 90: * The highlight color, or <code>null</code> to indicate that the 91: * color shall be derived from the background of the enclosed 92: * component. 93: */ 94: protected Color highlight; 95: 96: 97: /** 98: * The shadow color, or <code>null</code> to indicate that the 99: * color shall be derived from the background of the enclosed 100: * component. 101: */ 102: protected Color shadow; 103: 104: 105: /** 106: * Constructs a lowered EtchedBorder. The colors will be derived 107: * from the background color of the enclosed Component when the 108: * border gets painted. 109: */ 110: public EtchedBorder() 111: { 112: this(LOWERED); 113: } 114: 115: 116: /** 117: * Constructs an EtchedBorder with the specified appearance. The 118: * colors will be derived from the background color of the enclosed 119: * Component when the border gets painted. 120: * 121: * <p><img src="doc-files/EtchedBorder-1.png" width="500" height="200" 122: * alt="[An illustration of the two EtchedBorder variants]" /> 123: * 124: * @param etchType the desired appearance of the border. The value 125: * must be either {@link #RAISED} or {@link #LOWERED}. 126: * 127: * @throws IllegalArgumentException if <code>etchType</code> has 128: * an unsupported value. 129: */ 130: public EtchedBorder(int etchType) 131: { 132: if ((etchType != RAISED) && (etchType != LOWERED)) 133: throw new IllegalArgumentException(); 134: 135: this.etchType = etchType; 136: 137: /* The highlight and shadow fields already have a null value 138: * when the constructor gets called, so there is no need to 139: * assign a value here. 140: */ 141: } 142: 143: 144: /** 145: * Constructs a lowered EtchedBorder, explicitly selecting the 146: * colors that will be used for highlight and shadow. 147: * 148: * @param highlight the color that will be used for painting 149: * the highlight part of the border. 150: * 151: * @param shadow the color that will be used for painting 152: * the shadow part of the border. 153: * 154: * @see #EtchedBorder(int, Color, Color) 155: */ 156: public EtchedBorder(Color highlight, Color shadow) 157: { 158: this(LOWERED, highlight, shadow); 159: } 160: 161: 162: /** 163: * Constructs an EtchedBorder with the specified appearance, 164: * explicitly selecting the colors that will be used for 165: * highlight and shadow. 166: * 167: * <p><img src="doc-files/EtchedBorder-2.png" width="500" height="200" 168: * alt="[An illustration that shows which pixels get painted 169: * in what color]" /> 170: * 171: * @param etchType the desired appearance of the border. The value 172: * must be either {@link #RAISED} or {@link #LOWERED}. 173: * 174: * @param highlight the color that will be used for painting 175: * the highlight part of the border. 176: * 177: * @param shadow the color that will be used for painting 178: * the shadow part of the border. 179: * 180: * @throws IllegalArgumentException if <code>etchType</code> has 181: * an unsupported value. 182: */ 183: public EtchedBorder(int etchType, Color highlight, Color shadow) 184: { 185: this(etchType); // Checks the validity of the value. 186: this.highlight = highlight; 187: this.shadow = shadow; 188: } 189: 190: 191: /** 192: * Paints the border for a given component. 193: * 194: * @param c the component whose border is to be painted. 195: * @param g the graphics for painting. 196: * @param x the horizontal position for painting the border. 197: * @param y the vertical position for painting the border. 198: * @param width the width of the available area for painting the border. 199: * @param height the height of the available area for painting the border. 200: */ 201: public void paintBorder(Component c, Graphics g, int x, int y, int width, 202: int height) 203: { 204: switch (etchType) 205: { 206: case RAISED: 207: paintEtchedBorder(g, x, y, width, height, 208: getHighlightColor(c), getShadowColor(c)); 209: break; 210: 211: case LOWERED: 212: paintEtchedBorder(g, x, y, width, height, 213: getShadowColor(c), getHighlightColor(c)); 214: break; 215: } 216: } 217: 218: 219: /** 220: * Measures the width of this border. 221: * 222: * @param c the component whose border is to be measured. 223: * 224: * @return an Insets object whose <code>left</code>, <code>right</code>, 225: * <code>top</code> and <code>bottom</code> fields indicate the 226: * width of the border at the respective edge. 227: * 228: * @see #getBorderInsets(java.awt.Component, java.awt.Insets) 229: */ 230: public Insets getBorderInsets(Component c) 231: { 232: return new Insets(2, 2, 2, 2); 233: } 234: 235: 236: /** 237: * Measures the width of this border, storing the results into a 238: * pre-existing Insets object. 239: * 240: * @param insets an Insets object for holding the result values. 241: * After invoking this method, the <code>left</code>, 242: * <code>right</code>, <code>top</code> and 243: * <code>bottom</code> fields indicate the width of the 244: * border at the respective edge. 245: * 246: * @return the same object that was passed for <code>insets</code>. 247: * 248: * @see #getBorderInsets(Component) 249: */ 250: public Insets getBorderInsets(Component c, Insets insets) 251: { 252: insets.left = insets.right = insets.top = insets.bottom = 2; 253: return insets; 254: } 255: 256: 257: /** 258: * Determines whether this border fills every pixel in its area 259: * when painting. 260: * 261: * <p>If the border colors are derived from the background color of 262: * the enclosed component, the result is <code>true</code> because 263: * the derivation method always returns opaque colors. Otherwise, 264: * the result depends on the opacity of the individual colors. 265: * 266: * @return <code>true</code> if the border is fully opaque, or 267: * <code>false</code> if some pixels of the background 268: * can shine through the border. 269: */ 270: public boolean isBorderOpaque() 271: { 272: // If the colors are to be derived from the enclosed Component's 273: // background color, the border is guaranteed to be fully opaque 274: // because Color.brighten() and Color.darken() always return an 275: // opaque color. 276: return 277: ((highlight == null) || (highlight.getAlpha() == 255)) 278: && ((shadow == null) || (shadow.getAlpha() == 255)); 279: } 280: 281: /** 282: * Returns the appearance of this EtchedBorder, which is either 283: * {@link #RAISED} or {@link #LOWERED}. 284: */ 285: public int getEtchType() 286: { 287: return etchType; 288: } 289: 290: 291: /** 292: * Determines the color that will be used for highlighted parts when 293: * painting the border around a given component. If a highlight 294: * color has been specified upon constructing the border, that color 295: * is returned. Otherwise, the background color of the enclosed 296: * component is brightened. 297: * 298: * @param c the component enclosed by this border. 299: * 300: * @see java.awt.Component#getBackground() 301: * @see java.awt.Color#brighter() 302: */ 303: public Color getHighlightColor(Component c) 304: { 305: if (highlight != null) 306: return highlight; 307: else 308: return c.getBackground().brighter(); 309: } 310: 311: /** 312: * Returns the color that will be used for highlighted parts when 313: * painting the border, or <code>null</code> if that color will be 314: * derived from the background of the enclosed Component. 315: */ 316: public Color getHighlightColor() 317: { 318: return highlight; 319: } 320: 321: 322: /** 323: * Determines the color that will be used for shadowed parts when 324: * painting the border around a given component. If a shadow color 325: * has been specified upon constructing the border, that color is 326: * returned. Otherwise, the background color of the enclosed 327: * component is darkened. 328: * 329: * @param c the component enclosed by this border. 330: * 331: * @see java.awt.Component#getBackground() 332: * @see java.awt.Color#darker() 333: */ 334: public Color getShadowColor(Component c) 335: { 336: if (shadow != null) 337: return shadow; 338: else 339: return c.getBackground().darker(); 340: } 341: 342: 343: /** 344: * Returns the color that will be used for shadowed parts when 345: * painting the border, or <code>null</code> if that color will be 346: * derived from the background of the enclosed Component. 347: */ 348: public Color getShadowColor() 349: { 350: return shadow; 351: } 352: 353: 354: /** 355: * Paints a two-pixel etching in two colors. 356: * 357: * <pre> 358: * +++++++++++. 359: * +.........+. + = color a 360: * +. +. . = color b 361: * +. +. 362: * +++++++++++. 363: * ............</pre> 364: * 365: * @param g the graphics for painting. 366: * @param x the horizontal position for painting the border. 367: * @param y the vertical position for painting the border. 368: * @param width the width of the available area for painting the border. 369: * @param height the height of the available area for painting the border. 370: * @param a one of the two colors. 371: * @param b the second of the two colors. 372: */ 373: private static void paintEtchedBorder(Graphics g, int x, int y, int width, 374: int height, Color a, Color b) 375: { 376: Color oldColor; 377: 378: oldColor = g.getColor(); 379: g.translate(x, y); 380: width = width - 1; 381: height = height - 1; 382: 383: try 384: { 385: // To understand this code, it might be helpful to look at the 386: // images that are included with the JavaDoc. They are located 387: // in the "doc-files" subdirectory. EtchedBorder-2.png might 388: // be especially informative. 389: g.setColor(a); 390: g.drawRect(0, 0, width - 1, height - 1); 391: 392: g.setColor(b); 393: g.drawLine(1, 1, width - 2, 1); // top edge 394: g.drawLine(1, 2, 1, height - 2); // left edge 395: g.drawLine(0, height, width, height); // bottom edge 396: g.drawLine(width, 0, width, height - 1); // right edge 397: } 398: finally 399: { 400: g.translate(-x, -y); 401: g.setColor(oldColor); 402: } 403: } 404: }
GNU Classpath (0.20) |