GNU Classpath (0.20) | |
Frames | No Frames |
1: /* BevelBorder.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: package javax.swing.border; 39: 40: import java.awt.Color; 41: import java.awt.Component; 42: import java.awt.Graphics; 43: import java.awt.Insets; 44: 45: 46: /** 47: * A rectangular, two pixel thick border that causes the enclosed area 48: * to appear as if it was raising out of or lowered into the screen. Some 49: * LookAndFeels use this kind of border for rectangular buttons. 50: * 51: * <p>A BevelBorder has a highlight and a shadow color. In the raised 52: * variant, the highlight color is used for the top and left edges, 53: * and the shadow color is used for the bottom and right edge. For an 54: * image, see the documentation of the individual constructors. 55: * 56: * @author Sascha Brawer (brawer@dandelis.ch) 57: */ 58: public class BevelBorder extends AbstractBorder 59: { 60: /** 61: * Determined using the <code>serialver</code> tool 62: * of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5. 63: */ 64: static final long serialVersionUID = -1034942243356299676L; 65: 66: 67: /** 68: * Indicates that the BevelBorder looks like if the enclosed area was 69: * raising out of the screen. 70: */ 71: public static final int RAISED = 0; 72: 73: 74: /** 75: * Indicates that the BevelBorder looks like if the enclosed area was 76: * pressed into the screen. 77: */ 78: public static final int LOWERED = 1; 79: 80: 81: /** 82: * The type of this BevelBorder, which is either {@link #RAISED} 83: * or {@link #LOWERED}. 84: */ 85: protected int bevelType; 86: 87: 88: /** 89: * The outer highlight color, or <code>null</code> to indicate that 90: * the color shall be derived from the background of the component 91: * whose border is being painted. 92: */ 93: protected Color highlightOuter; 94: 95: 96: /** 97: * The inner highlight color, or <code>null</code> to indicate that 98: * the color shall be derived from the background of the component 99: * whose border is being painted. 100: */ 101: protected Color highlightInner; 102: 103: 104: /** 105: * The outer shadow color, or <code>null</code> to indicate that the 106: * color shall be derived from the background of the component whose 107: * border is being painted. 108: */ 109: protected Color shadowOuter; 110: 111: 112: /** 113: * The inner shadow color, or <code>null</code> to indicate that the 114: * color shall be derived from the background of the component whose 115: * border is being painted. 116: */ 117: protected Color shadowInner; 118: 119: 120: /** 121: * Constructs a BevelBorder whose colors will be derived from the 122: * background of the enclosed component. The background color is 123: * retrieved each time the border is painted, so a BevelBorder 124: * constructed by this method will automatically reflect a change 125: * to the component’s background color. 126: * 127: * <p><img src="doc-files/BevelBorder-1.png" width="500" height="150" 128: * alt="[An illustration showing raised and lowered BevelBorders]" /> 129: * 130: * @param bevelType the desired appearance of the border. The value 131: * must be either {@link #RAISED} or {@link #LOWERED}. 132: * 133: * @throws IllegalArgumentException if <code>bevelType</code> has 134: * an unsupported value. 135: */ 136: public BevelBorder(int bevelType) 137: { 138: if ((bevelType != RAISED) && (bevelType != LOWERED)) 139: throw new IllegalArgumentException(); 140: 141: this.bevelType = bevelType; 142: } 143: 144: 145: /** 146: * Constructs a BevelBorder given its appearance type and two colors 147: * for its highlight and shadow. 148: * 149: * <p><img src="doc-files/BevelBorder-2.png" width="500" height="150" 150: * alt="[An illustration showing BevelBorders that were constructed 151: * with this method]" /> 152: * 153: * @param bevelType the desired appearance of the border. The value 154: * must be either {@link #RAISED} or {@link #LOWERED}. 155: * 156: * @param highlight the color that will be used for the inner 157: * side of the highlighted edges (top and left if 158: * if <code>bevelType</code> is {@link #RAISED}; bottom 159: * and right otherwise). The color for the outer side 160: * is a brightened version of this color. 161: * 162: * @param shadow the color that will be used for the outer 163: * side of the shadowed edges (bottom and right 164: * if <code>bevelType</code> is {@link #RAISED}; top 165: * and left otherwise). The color for the inner side 166: * is a brightened version of this color. 167: * 168: * @throws IllegalArgumentException if <code>bevelType</code> has 169: * an unsupported value. 170: * 171: * @throws NullPointerException if <code>highlight</code> or 172: * <code>shadow</code> is <code>null</code>. 173: * 174: * @see java.awt.Color#brighter() 175: */ 176: public BevelBorder(int bevelType, Color highlight, Color shadow) 177: { 178: this(bevelType, 179: /* highlightOuter */ highlight.brighter(), 180: /* highlightInner */ highlight, 181: /* shadowOuter */ shadow, 182: /* shadowInner */ shadow.brighter()); 183: } 184: 185: 186: /** 187: * Constructs a BevelBorder given its appearance type and all 188: * colors. 189: * 190: * <p><img src="doc-files/BevelBorder-3.png" width="500" height="150" 191: * alt="[An illustration showing BevelBorders that were constructed 192: * with this method]" /> 193: * 194: * @param bevelType the desired appearance of the border. The value 195: * must be either {@link #RAISED} or {@link #LOWERED}. 196: * 197: * @param highlightOuter the color that will be used for the outer 198: * side of the highlighted edges (top and left if 199: * <code>bevelType</code> is {@link #RAISED}; bottom and 200: * right otherwise). 201: * 202: * @param highlightInner the color that will be used for the inner 203: * side of the highlighted edges. 204: * 205: * @param shadowOuter the color that will be used for the outer 206: * side of the shadowed edges (bottom and right 207: * if <code>bevelType</code> is {@link #RAISED}; top 208: * and left otherwise). 209: * 210: * @param shadowInner the color that will be used for the inner 211: * side of the shadowed edges. 212: * 213: * @throws IllegalArgumentException if <code>bevelType</code> has 214: * an unsupported value. 215: * 216: * @throws NullPointerException if one of the passed colors 217: * is <code>null</code>. 218: */ 219: public BevelBorder(int bevelType, 220: Color highlightOuter, Color highlightInner, 221: Color shadowOuter, Color shadowInner) 222: { 223: this(bevelType); // checks the validity of bevelType 224: 225: if ((highlightOuter == null) || (highlightInner == null) 226: || (shadowOuter == null) || (shadowInner == null)) 227: throw new NullPointerException(); 228: 229: this.highlightOuter = highlightOuter; 230: this.highlightInner = highlightInner; 231: this.shadowOuter = shadowOuter; 232: this.shadowInner = shadowInner; 233: } 234: 235: 236: /** 237: * Paints the border for a given component. 238: * 239: * @param c the component whose border is to be painted. 240: * @param g the graphics for painting. 241: * @param x the horizontal position for painting the border. 242: * @param y the vertical position for painting the border. 243: * @param width the width of the available area for painting the border. 244: * @param height the height of the available area for painting the border. 245: */ 246: public void paintBorder(Component c, Graphics g, 247: int x, int y, int width, int height) 248: { 249: switch (bevelType) 250: { 251: case RAISED: 252: paintRaisedBevel(c, g, x, y, width, height); 253: break; 254: 255: case LOWERED: 256: paintLoweredBevel(c, g, x, y, width, height); 257: break; 258: } 259: } 260: 261: 262: /** 263: * Measures the width of this border. 264: * 265: * @param c the component whose border is to be measured. 266: * 267: * @return an Insets object whose <code>left</code>, <code>right</code>, 268: * <code>top</code> and <code>bottom</code> fields indicate the 269: * width of the border at the respective edge. 270: * 271: * @see #getBorderInsets(java.awt.Component, java.awt.Insets) 272: */ 273: public Insets getBorderInsets(Component c) 274: { 275: return new Insets(2, 2, 2, 2); 276: } 277: 278: 279: /** 280: * Measures the width of this border, storing the results into a 281: * pre-existing Insets object. 282: * 283: * @param insets an Insets object for holding the result values. 284: * After invoking this method, the <code>left</code>, 285: * <code>right</code>, <code>top</code> and 286: * <code>bottom</code> fields indicate the width of the 287: * border at the respective edge. 288: * 289: * @return the same object that was passed for <code>insets</code>. 290: * 291: * @see #getBorderInsets(Component) 292: */ 293: public Insets getBorderInsets(Component c, Insets insets) 294: { 295: insets.left = insets.right = insets.top = insets.bottom = 2; 296: return insets; 297: } 298: 299: 300: /** 301: * Determines the color that will be used for the outer side of 302: * highlighted edges when painting the border. If a highlight color 303: * has been specified upon constructing the border, that color is 304: * returned. Otherwise, the inner highlight color is brightened. 305: * 306: * @param c the component enclosed by this border. 307: * 308: * @see #getHighlightInnerColor(java.awt.Component) 309: * @see java.awt.Color#brighter() 310: */ 311: public Color getHighlightOuterColor(Component c) 312: { 313: if (highlightOuter != null) 314: return highlightOuter; 315: else 316: return getHighlightInnerColor(c).brighter(); 317: } 318: 319: 320: /** 321: * Determines the color that will be used for the inner side of 322: * highlighted edges when painting the border. If a highlight color 323: * has been specified upon constructing the border, that color is 324: * returned. Otherwise, the background color of the enclosed 325: * component is brightened. 326: * 327: * @param c the component enclosed by this border. 328: * 329: * @see java.awt.Component#getBackground() 330: * @see java.awt.Color#brighter() 331: */ 332: public Color getHighlightInnerColor(Component c) 333: { 334: if (highlightInner != null) 335: return highlightInner; 336: else 337: return c.getBackground().brighter(); 338: } 339: 340: 341: /** 342: * Determines the color that will be used for the inner side of 343: * shadowed edges when painting the border. If a shadow color has 344: * been specified upon constructing the border, that color is 345: * returned. Otherwise, the background color of the enclosed 346: * component is darkened. 347: * 348: * @param c the component enclosed by this border. 349: * 350: * @see java.awt.Component#getBackground() 351: * @see java.awt.Color#darker() 352: */ 353: public Color getShadowInnerColor(Component c) 354: { 355: if (shadowInner != null) 356: return shadowInner; 357: else 358: return c.getBackground().darker(); 359: } 360: 361: 362: /** 363: * Determines the color that will be used for the outer side of 364: * shadowed edges when painting the border. If a shadow color 365: * has been specified upon constructing the border, that color is 366: * returned. Otherwise, the inner shadow color is darkened. 367: * 368: * @param c the component enclosed by this border. 369: * 370: * @see #getShadowInnerColor(java.awt.Component) 371: * @see java.awt.Color#darker() 372: */ 373: public Color getShadowOuterColor(Component c) 374: { 375: if (shadowOuter != null) 376: return shadowOuter; 377: else 378: return getShadowInnerColor(c).darker(); 379: } 380: 381: 382: /** 383: * Returns the color that will be used for the outer side of 384: * highlighted edges when painting the border, or <code>null</code> 385: * if that color will be derived from the background of the enclosed 386: * Component. 387: */ 388: public Color getHighlightOuterColor() 389: { 390: return highlightOuter; 391: } 392: 393: 394: /** 395: * Returns the color that will be used for the inner side of 396: * highlighted edges when painting the border, or <code>null</code> 397: * if that color will be derived from the background of the enclosed 398: * Component. 399: */ 400: public Color getHighlightInnerColor() 401: { 402: return highlightInner; 403: } 404: 405: 406: /** 407: * Returns the color that will be used for the inner side of 408: * shadowed edges when painting the border, or <code>null</code> if 409: * that color will be derived from the background of the enclosed 410: * Component. 411: */ 412: public Color getShadowInnerColor() 413: { 414: return shadowInner; 415: } 416: 417: 418: /** 419: * Returns the color that will be used for the outer side of 420: * shadowed edges when painting the border, or <code>null</code> if 421: * that color will be derived from the background of the enclosed 422: * Component. 423: */ 424: public Color getShadowOuterColor() 425: { 426: return shadowOuter; 427: } 428: 429: 430: /** 431: * Returns the appearance of this border, which is either {@link 432: * #RAISED} or {@link #LOWERED}. 433: */ 434: public int getBevelType() 435: { 436: return bevelType; 437: } 438: 439: 440: /** 441: * Determines whether this border fills every pixel in its area 442: * when painting. 443: * 444: * <p>If the border colors are derived from the background color of 445: * the enclosed component, the result is <code>true</code> because 446: * the derivation method always returns opaque colors. Otherwise, 447: * the result depends on the opacity of the individual colors. 448: * 449: * @return <code>true</code> if the border is fully opaque, or 450: * <code>false</code> if some pixels of the background 451: * can shine through the border. 452: */ 453: public boolean isBorderOpaque() 454: { 455: /* If the colors are to be drived from the enclosed Component's 456: * background color, the border is guaranteed to be fully opaque 457: * because Color.brighten() and Color.darken() always return an 458: * opaque color. 459: */ 460: return 461: ((highlightOuter == null) || (highlightOuter.getAlpha() == 255)) 462: && ((highlightInner == null) || (highlightInner.getAlpha() == 255)) 463: && ((shadowInner == null) || (shadowInner.getAlpha() == 255)) 464: && ((shadowOuter == null) ||(shadowOuter.getAlpha() == 255)); 465: } 466: 467: 468: /** 469: * Paints a raised bevel border around a component. 470: * 471: * @param c the component whose border is to be painted. 472: * @param g the graphics for painting. 473: * @param x the horizontal position for painting the border. 474: * @param y the vertical position for painting the border. 475: * @param width the width of the available area for painting the border. 476: * @param height the height of the available area for painting the border. 477: */ 478: protected void paintRaisedBevel(Component c, Graphics g, 479: int x, int y, int width, int height) 480: { 481: paintBevel(g, x, y, width, height, 482: getHighlightOuterColor(c), getHighlightInnerColor(c), 483: getShadowInnerColor(c), getShadowOuterColor(c)); 484: } 485: 486: 487: /** 488: * Paints a lowered bevel border around a component. 489: * 490: * @param c the component whose border is to be painted. 491: * @param g the graphics for painting. 492: * @param x the horizontal position for painting the border. 493: * @param y the vertical position for painting the border. 494: * @param width the width of the available area for painting the border. 495: * @param height the height of the available area for painting the border. 496: */ 497: protected void paintLoweredBevel(Component c, Graphics g, 498: int x, int y, int width, int height) 499: { 500: paintBevel(g, x, y, width, height, 501: getShadowInnerColor(c), getShadowOuterColor(c), 502: getHighlightInnerColor(c), getHighlightOuterColor(c)); 503: } 504: 505: 506: /** 507: * Paints a two-pixel bevel in four colors. 508: * 509: * <pre> 510: * ++++++++++++ 511: * +..........# + = color a 512: * +. X# . = color b 513: * +. X# X = color c 514: * +.XXXXXXXXX# # = color d 515: * ############</pre> 516: * 517: * @param g the graphics for painting. 518: * @param x the horizontal position for painting the border. 519: * @param y the vertical position for painting the border. 520: * @param width the width of the available area for painting the border. 521: * @param height the height of the available area for painting the border. 522: * @param a the color for the outer side of the top and left edges. 523: * @param b the color for the inner side of the top and left edges. 524: * @param c the color for the inner side of the bottom and right edges. 525: * @param d the color for the outer side of the bottom and right edges. 526: */ 527: private static void paintBevel(Graphics g, 528: int x, int y, int width, int height, 529: Color a, Color b, Color c, Color d) 530: { 531: Color oldColor; 532: 533: oldColor = g.getColor(); 534: g.translate(x, y); 535: width = width - 1; 536: height = height - 1; 537: 538: try 539: { 540: /* To understand this code, it might be helpful to look at the 541: * images that are included with the JavaDoc. They are located 542: * in the "doc-files" subdirectory. 543: */ 544: g.setColor(a); 545: g.drawLine(0, 0, width, 0); // a, horizontal 546: g.drawLine(0, 1, 0, height); // a, vertical 547: 548: g.setColor(b); 549: g.drawLine(1, 1, width - 1, 1); // b, horizontal 550: g.drawLine(1, 2, 1, height - 1); // b, vertical 551: 552: g.setColor(c); 553: g.drawLine(2, height - 1, width - 1, height - 1); // c, horizontal 554: g.drawLine(width - 1, 2, width - 1, height - 2); // c, vertical 555: 556: g.setColor(d); 557: g.drawLine(1, height, width, height); // d, horizontal 558: g.drawLine(width, 1, width, height - 1); // d, vertical 559: } 560: finally 561: { 562: g.translate(-x, -y); 563: g.setColor(oldColor); 564: } 565: } 566: }
GNU Classpath (0.20) |