Source for javax.swing.border.CompoundBorder

   1: /* CompoundBorder.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.Component;
  42: import java.awt.Graphics;
  43: import java.awt.Insets;
  44: 
  45: /**
  46:  * A Border that is composed of an interior and an exterior border,
  47:  * where the interior border is tightly nested into the exterior.
  48:  *
  49:  * @author Sascha Brawer (brawer@dandelis.ch)
  50:  */
  51: public class CompoundBorder
  52:   extends AbstractBorder
  53: {
  54:   /**
  55:    * Determined using the <code>serialver</code> tool
  56:    * of Apple/Sun JDK 1.3.1 on MacOS X 10.1.5.
  57:    */
  58:   static final long serialVersionUID = 9054540377030555103L;
  59: 
  60: 
  61:   /**
  62:    * The inside border, which is painted between the bordered
  63:    * Component and the outside border. It is valid for
  64:    * <code>insideBorder</code> to be <code>null</code>.
  65:    */
  66:   protected Border insideBorder;
  67: 
  68: 
  69:   /**
  70:    * The outside border, which is painted outside both the
  71:    * bordered Component and the inside border. It is valid for
  72:    * <code>outsideBorder</code> to be <code>null</code>.
  73:    */
  74:   protected Border outsideBorder;
  75: 
  76: 
  77:   /**
  78:    * Constructs a CompoundBorder whose inside and outside borders
  79:    * are both <code>null</code>. While this does not really make
  80:    * any sense (there exists a class EmptyBorder as well, and not
  81:    * every Component needs to have a border at all), the API
  82:    * specification requires the existence of this constructor.
  83:    *
  84:    * @see EmptyBorder
  85:    */
  86:   public CompoundBorder ()
  87:   {
  88:     this (null, null);
  89:   }
  90: 
  91: 
  92:   /**
  93:    * Constructs a CompoundBorder with the specified inside and
  94:    * outside borders.
  95:    *
  96:    * @param outsideBorder the outside border, which is painted to the
  97:    *        outside of both <code>insideBorder</code> and the enclosed
  98:    *        component. It is acceptable to pass <code>null</code>, in
  99:    *        which case no outside border is painted.
 100:    *
 101:    * @param insideBorder the inside border, which is painted to
 102:    *        between <code>outsideBorder</code> and the enclosed
 103:    *        component. It is acceptable to pass <code>null</code>, in
 104:    *        which case no inside border is painted.
 105:    */
 106:   public CompoundBorder (Border outsideBorder, Border insideBorder)
 107:   {
 108:     this.outsideBorder = outsideBorder;
 109:     this.insideBorder = insideBorder;
 110:   }
 111: 
 112: 
 113:   /**
 114:    * Determines whether or not this border is opaque. An opaque
 115:    * border fills every pixel in its area when painting. Partially
 116:    * translucent borders must return <code>false</code>, or ugly
 117:    * artifacts can appear on screen.
 118:    *
 119:    * @return <code>true</code> if both the inside and outside borders
 120:    *         are opaque, or <code>false</code> otherwise.
 121:    */
 122:   public boolean isBorderOpaque ()
 123:   {
 124:     /* While it would be safe to assume true for the opacity of
 125:      * a null border, this behavior would not be according to
 126:      * the API specification. Also, it is pathological to have
 127:      * null borders anyway.
 128:      */
 129:     if ((insideBorder == null) || (outsideBorder == null))
 130:       return false;
 131: 
 132:     return insideBorder.isBorderOpaque()
 133:       && outsideBorder.isBorderOpaque();
 134:   }
 135:     
 136: 
 137:   /**
 138:    * Paints the compound border by first painting the outside border,
 139:    * then painting the inside border tightly nested into the outside. 
 140:    *
 141:    * @param c the component whose border is to be painted.
 142:    * @param g the graphics for painting.
 143:    * @param x the horizontal position for painting the border.
 144:    * @param y the vertical position for painting the border.
 145:    * @param width the width of the available area for painting the border.
 146:    * @param height the height of the available area for painting the border.
 147:    */
 148:   public void paintBorder(Component c, Graphics g,
 149:                           int x, int y, int width, int height)
 150:   {
 151:     /* If there is an outside border, paint it and reduce the
 152:      * bounding box by its insets.
 153:      */
 154:     if (outsideBorder != null)
 155:     {
 156:       Insets outsideInsets;
 157: 
 158:       outsideBorder.paintBorder(c, g, x, y, width, height);
 159:       outsideInsets = outsideBorder.getBorderInsets(c);
 160: 
 161:       x += outsideInsets.left;
 162:       y += outsideInsets.top;
 163: 
 164:       /* Reduce width and height by the respective extent of the
 165:        * outside border.
 166:        */
 167:       width -= outsideInsets.left + outsideInsets.right;
 168:       height -= outsideInsets.top + outsideInsets.bottom;
 169:     }
 170: 
 171:     if (insideBorder != null)
 172:       insideBorder.paintBorder(c, g, x, y, width, height);
 173:   }
 174: 
 175: 
 176:   /**
 177:    * Changes the specified insets to the insets of this border,
 178:    * which is the sum of the insets of the inside and the outside
 179:    * border.
 180:    *
 181:    * @param c the component in the center of this border.
 182:    * @param insets an Insets object for holding the added insets.
 183:    *
 184:    * @return the <code>insets</code> object.
 185:    */
 186:   public Insets getBorderInsets(Component c, Insets insets)
 187:   {
 188:     Insets borderInsets;
 189: 
 190:     if (insets == null)
 191:       insets = new Insets (0,0,0,0);
 192:     else
 193:       insets.left = insets.right = insets.top = insets.bottom = 0;
 194: 
 195:     /* If there is an outside border, add it to insets. */
 196:     if (outsideBorder != null)
 197:     {
 198:       borderInsets = outsideBorder.getBorderInsets(c);
 199:       insets.left += borderInsets.left;
 200:       insets.right += borderInsets.right;
 201:       insets.top += borderInsets.top;
 202:       insets.bottom += borderInsets.bottom;
 203:     }
 204: 
 205:     /* If there is an inside border, add it to insets. */
 206:     if (insideBorder != null)
 207:     {
 208:       borderInsets = insideBorder.getBorderInsets(c);
 209:       insets.left += borderInsets.left;
 210:       insets.right += borderInsets.right;
 211:       insets.top += borderInsets.top;
 212:       insets.bottom += borderInsets.bottom;
 213:     }
 214: 
 215:     return insets;
 216:   }
 217: 
 218: 
 219:   /**
 220:    * Determines the insets of this border, which is the sum of the
 221:    * insets of the inside and the outside border.
 222:    *
 223:    * @param c the component in the center of this border.
 224:    */
 225:   public Insets getBorderInsets (Component c)
 226:   {
 227:     /* It is not clear why CompoundBorder does not simply inherit
 228:      * the implementation from AbstractBorder. However, we want
 229:      * to be compatible with the API specification, which overrides
 230:      * the getBorderInsets(Component) method.
 231:      */
 232:     return getBorderInsets (c, null);
 233:   }
 234: 
 235: 
 236:   /**
 237:    * Returns the outside border, which is painted outside both the
 238:    * bordered Component and the inside border. It is valid for the
 239:    * result to be <code>null</code>.
 240:    */
 241:   public Border getOutsideBorder ()
 242:   {
 243:     return outsideBorder;
 244:   }
 245: 
 246: 
 247:   /**
 248:    * Returns the inside border, which is painted between the bordered
 249:    * Component and the outside border. It is valid for the result to
 250:    * be <code>null</code>.
 251:    */
 252:   public Border getInsideBorder ()
 253:   {
 254:     return insideBorder;
 255:   }
 256: }