Source for javax.swing.plaf.basic.BasicArrowButton

   1: /* BasicArrowButton.java --
   2:    Copyright (C) 2004, 2005 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.plaf.basic;
  40: 
  41: import java.awt.Color;
  42: import java.awt.Component;
  43: import java.awt.Dimension;
  44: import java.awt.Graphics;
  45: import java.awt.Insets;
  46: import java.awt.Polygon;
  47: import java.awt.Rectangle;
  48: 
  49: import javax.swing.JButton;
  50: import javax.swing.SwingConstants;
  51: import javax.swing.border.Border;
  52: 
  53: /**
  54:  * This class draws simple arrow buttons for the Basic Look and Feel.
  55:  */
  56: public class BasicArrowButton extends JButton implements SwingConstants
  57: {
  58:   /** The default size of the Arrow buttons. */
  59:   private static int defaultSize = 12;
  60: 
  61:   /** The Polygon that points up. */
  62:   private static Polygon upIcon = new Polygon(new int[] { 0, 5, 9 },
  63:                                               new int[] { 7, 2, 7 }, 3);
  64: 
  65:   /** The Polygon that points down. */
  66:   private static Polygon downIcon = new Polygon(new int[] { 1, 5, 9 },
  67:                                                 new int[] { 3, 7, 3 }, 3);
  68: 
  69:   /** The Polygon that points left. */
  70:   private static Polygon leftIcon = new Polygon(new int[] { 7, 3, 7 },
  71:                                                 new int[] { 1, 5, 9 }, 3);
  72: 
  73:   /** The Polygon that points right. */
  74:   private static Polygon rightIcon = new Polygon(new int[] { 3, 7, 3 },
  75:                                                  new int[] { 1, 5, 9 }, 3);
  76: 
  77:   /** The direction to point in. */
  78:   protected int direction;
  79: 
  80:   /**
  81:    * The color the arrow is painted in if disabled and the bottom and right
  82:    * edges of the button.
  83:    * This is package-private to avoid an accessor method.
  84:    */
  85:   transient Color shadow = Color.GRAY;
  86: 
  87:   /**
  88:    * The color the arrow is painted in if enabled and the bottom and right
  89:    * edges of the button.
  90:    * This is package-private to avoid an accessor method.
  91:    */
  92:   transient Color darkShadow = Color.DARK_GRAY;
  93: 
  94:   /**
  95:    * The top and left edges of the button.
  96:    * This is package-private to avoid an accessor method.
  97:    */
  98:   transient Color highlight = Color.WHITE;
  99: 
 100:   /** The border around the ArrowButton. */
 101:   private transient Border buttonBorder = new Border()
 102:     {
 103:       public Insets getBorderInsets(Component c)
 104:       {
 105:     return new Insets(2, 2, 2, 2);
 106:       }
 107: 
 108:       public boolean isBorderOpaque()
 109:       {
 110:     return true;
 111:       }
 112: 
 113:       public void paintBorder(Component c, Graphics g, int x, int y, int w,
 114:                               int h)
 115:       {
 116:     Color saved = g.getColor();
 117:     g.setColor(highlight);
 118: 
 119:     g.drawLine(x + 1, y + 1, x + w - 1, y + 1);
 120:     g.drawLine(x + 1, y + 1, x + 1, y + h - 1);
 121: 
 122:     g.setColor(shadow);
 123: 
 124:     g.drawLine(x + 1, y + h - 1, x + w - 1, y + h - 1);
 125:     g.drawLine(x + w - 1, y + 1, x + w - 1, y + h - 1);
 126: 
 127:     g.setColor(darkShadow);
 128: 
 129:     g.drawLine(x, y + h, x + w, y + h);
 130:     g.drawLine(x + w, y, x + w, y + h);
 131: 
 132:     g.setColor(saved);
 133:       }
 134:     };
 135: 
 136:   /**
 137:    * Creates a new BasicArrowButton object.
 138:    *
 139:    * @param direction The direction the arrow points in.
 140:    */
 141:   public BasicArrowButton(int direction)
 142:   {
 143:     super();
 144:     setBorder(buttonBorder);
 145:     setDirection(direction);
 146:   }
 147: 
 148:   /**
 149:    * Creates a new BasicArrowButton object with the given colors and
 150:    * direction.
 151:    *
 152:    * @param direction The direction to point in.
 153:    * @param background The background color.
 154:    * @param shadow The shadow color.
 155:    * @param darkShadow The dark shadow color.
 156:    * @param highlight The highlight color.
 157:    */
 158:   public BasicArrowButton(int direction, Color background, Color shadow,
 159:                           Color darkShadow, Color highlight)
 160:   {
 161:     this(direction);
 162:     setBackground(background);
 163:     this.shadow = shadow;
 164:     this.darkShadow = darkShadow;
 165:     this.highlight = highlight;
 166:   }
 167: 
 168:   /**
 169:    * This method returns whether the focus can traverse to this component.
 170:    *
 171:    * @return Whether the focus can traverse to this component.
 172:    */
 173:   public boolean isFocusTraversable()
 174:   {
 175:     return false;
 176:   }
 177: 
 178:   /**
 179:    * This method returns the direction of the arrow.
 180:    *
 181:    * @return The direction of the arrow.
 182:    */
 183:   public int getDirection()
 184:   {
 185:     return direction;
 186:   }
 187: 
 188:   /**
 189:    * This method changes the direction of the arrow.
 190:    *
 191:    * @param dir The new direction of the arrow.
 192:    */
 193:   public void setDirection(int dir)
 194:   {
 195:     this.direction = dir;
 196:   }
 197: 
 198:   /**
 199:    * This method paints the arrow button. The painting is delegated to the
 200:    * paintTriangle method.
 201:    *
 202:    * @param g The Graphics object to paint with.
 203:    */
 204:   public void paint(Graphics g)
 205:   {
 206:     super.paint(g);
 207:     Insets insets = getInsets();
 208:     Rectangle bounds = getBounds();
 209:     int x = insets.left
 210:             + (bounds.width - insets.left - insets.right - defaultSize) / 2;
 211:     int y = insets.top
 212:             + (bounds.height - insets.left - insets.right - defaultSize) / 2;
 213:     paintTriangle(g, x, y, defaultSize, direction, isEnabled());
 214:   }
 215: 
 216:   /**
 217:    * This method returns the preferred size of the arrow button.
 218:    *
 219:    * @return The preferred size.
 220:    */
 221:   public Dimension getPreferredSize()
 222:   {
 223:     Insets insets = getInsets();
 224:     int w = defaultSize + insets.left + insets.right;
 225:     int h = defaultSize + insets.top + insets.bottom;
 226: 
 227:     return new Dimension(w, h);
 228:   }
 229: 
 230:   /**
 231:    * This method returns the minimum size of the arrow button.
 232:    *
 233:    * @return The minimum size.
 234:    */
 235:   public Dimension getMinimumSize()
 236:   {
 237:     return getPreferredSize();
 238:   }
 239: 
 240:   /**
 241:    * This method returns the maximum size of the arrow button.
 242:    *
 243:    * @return The maximum size.
 244:    */
 245:   public Dimension getMaximumSize()
 246:   {
 247:     return getPreferredSize();
 248:   }
 249: 
 250:   /**
 251:    * The method paints a triangle with the given size and direction at the
 252:    * given x and y coordinates.
 253:    *
 254:    * @param g The Graphics object to paint with.
 255:    * @param x The x coordinate to paint at.
 256:    * @param y The y coordinate to paint at.
 257:    * @param size The size of the icon.
 258:    * @param direction The direction of the icon.
 259:    * @param isEnabled Whether it is enabled.
 260:    */
 261:   public void paintTriangle(Graphics g, int x, int y, int size, int direction,
 262:                             boolean isEnabled)
 263:   {
 264:     Polygon arrow = null;
 265:     switch (direction)
 266:       {
 267:       case NORTH:
 268:     arrow = upIcon;
 269:     break;
 270:       case SOUTH:
 271:     arrow = downIcon;
 272:     break;
 273:       case EAST:
 274:       case RIGHT:
 275:     arrow = rightIcon;
 276:     break;
 277:       case WEST:
 278:       case LEFT:
 279:     arrow = leftIcon;
 280:     break;
 281:       }
 282: 
 283:     int[] xPoints = arrow.xpoints;
 284:     int[] yPoints = arrow.ypoints;
 285:     int x1;
 286:     int y1;
 287:     int x2;
 288:     int y2;
 289:     x1 = y1 = x2 = y2 = 0;
 290: 
 291:     if (size != defaultSize)
 292:       {
 293:     float scale = size * 1f / defaultSize;
 294:     for (int i = 0; i < 3; i++)
 295:       {
 296:         xPoints[i] *= scale;
 297:         yPoints[i] *= scale;
 298:       }
 299:       }
 300:     g.translate(x, y);
 301: 
 302:     switch (direction)
 303:       {
 304:       case NORTH:
 305:     x1 = xPoints[0] + 2;
 306:     y1 = yPoints[0];
 307:     y2 = y1;
 308:     x2 = xPoints[2] - 1;
 309:     break;
 310:       case SOUTH:
 311:     x1 = xPoints[1];
 312:     y1 = yPoints[1] + 1;
 313:     x2 = xPoints[2] - 1;
 314:     y2 = yPoints[2];
 315:     break;
 316:       case LEFT:
 317:       case WEST:
 318:     x1 = xPoints[0] + 1;
 319:     y1 = yPoints[0] + 1;
 320:     x2 = x1;
 321:     y2 = yPoints[2] + 1;
 322:     break;
 323:       case RIGHT:
 324:       case EAST:
 325:     x1 = xPoints[2];
 326:     y1 = yPoints[2] + 1;
 327:     x2 = xPoints[1] - 1;
 328:     y2 = yPoints[1] + 1;
 329:     break;
 330:       }
 331:     Color saved = g.getColor();
 332: 
 333:     if (isEnabled)
 334:       {
 335:     g.setColor(Color.DARK_GRAY);
 336: 
 337:     if (arrow != null)
 338:       g.fillPolygon(xPoints, yPoints, 3);
 339:       }
 340:     else
 341:       {
 342:     g.setColor(Color.GRAY);
 343:     g.fillPolygon(xPoints, yPoints, 3);
 344:     g.setColor(Color.WHITE);
 345:     g.drawLine(x1, y1, x2, y2);
 346:       }
 347:     g.setColor(saved);
 348:     g.translate(-x, -y);
 349:   }
 350: }