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