Source for javax.swing.plaf.metal.MetalScrollButton

   1: /* MetalScrollButton.java
   2:    Copyright (C) 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.metal;
  40: 
  41: import java.awt.Dimension;
  42: import java.awt.Graphics;
  43: import java.awt.Rectangle;
  44: 
  45: import javax.swing.SwingUtilities;
  46: import javax.swing.plaf.basic.BasicArrowButton;
  47: 
  48: /**
  49:  * A button used by the {@link MetalScrollBarUI}.  The button appearance
  50:  * varies according to the button direction, whether or not it is part of a
  51:  * "free standing" scroll bar, and the current state of the button.
  52:  */
  53: public class MetalScrollButton extends BasicArrowButton
  54: {
  55: 
  56:   /**
  57:    * The maximum size for buttons.
  58:    * @see #getMaximumSize()
  59:    */
  60:   private static Dimension maximumSize;
  61: 
  62:   /** The width of the button. */
  63:   private int buttonWidth;
  64: 
  65:   /**
  66:    * A flag that indicates whether the button is part of a free standing
  67:    * scroll bar.  This affects how the border is drawn.
  68:    */
  69:   private boolean freeStanding;
  70: 
  71:   /**
  72:    * Creates a new button.
  73:    *
  74:    * @param direction  the direction (this should be one of {@link #NORTH},
  75:    *                   {@link #SOUTH}, {@link #EAST} and {@link #WEST}, but
  76:    *                   this is not enforced).
  77:    * @param width  the button width.
  78:    * @param freeStanding  a flag indicating whether the scroll button is free
  79:    *                      standing or not.
  80:    */
  81:   public MetalScrollButton(int direction, int width, boolean freeStanding)
  82:   {
  83:     super(direction);
  84:     buttonWidth = width;
  85:     this.freeStanding = freeStanding;
  86:     setFocusable(false);
  87:   }
  88: 
  89:   /**
  90:    * Returns the button width.
  91:    *
  92:    * @return The button width.
  93:    */
  94:   public int getButtonWidth()
  95:   {
  96:     return buttonWidth;
  97:   }
  98: 
  99:   /**
 100:    * Sets the free standing flag.  This controls how the button border is
 101:    * drawn.
 102:    *
 103:    * @param freeStanding  the new value of the flag.
 104:    */
 105:   public void setFreeStanding(boolean freeStanding)
 106:   {
 107:     this.freeStanding = freeStanding;
 108:   }
 109: 
 110:   /**
 111:    * Paints the button.
 112:    *
 113:    * @param g  the graphics device.
 114:    */
 115:   public void paint(Graphics g)
 116:   {
 117:     Rectangle bounds = SwingUtilities.getLocalBounds(this);
 118: 
 119:     // fill the background
 120:     if (getModel().isPressed())
 121:       g.setColor(MetalLookAndFeel.getControlShadow());
 122:     else
 123:       g.setColor(MetalLookAndFeel.getControl());
 124:     g.fillRect(0, 0, bounds.width, bounds.height);
 125: 
 126:     paintArrow(g, bounds.width, bounds.height);
 127: 
 128:     // paint a border manually - I tried using a real (custom) Border
 129:     // but couldn't get it to stay set for the button, something was
 130:     // overwriting it...
 131:     if (freeStanding)
 132:       {
 133:         if (direction == WEST)
 134:           paintWestBorderFreeStanding(g, bounds.width, bounds.height);
 135:         else if (direction == EAST)
 136:           paintEastBorderFreeStanding(g, bounds.width, bounds.height);
 137:         else if (direction == SOUTH)
 138:           paintSouthBorderFreeStanding(g, bounds.width, bounds.height);
 139:         else // asume NORTH
 140:           paintNorthBorderFreeStanding(g, bounds.width, bounds.height);
 141:       }
 142:     else
 143:       {
 144:         if (direction == WEST)
 145:           paintWestBorder(g, bounds.width, bounds.height);
 146:         else if (direction == EAST)
 147:           paintEastBorder(g, bounds.width, bounds.height);
 148:         else if (direction == SOUTH)
 149:           paintSouthBorder(g, bounds.width, bounds.height);
 150:         else // asume NORTH
 151:           paintNorthBorder(g, bounds.width, bounds.height);
 152:       }
 153:   }
 154: 
 155:   private void paintArrow(Graphics g, int w, int h)
 156:   {
 157:     if (isEnabled())
 158:       g.setColor(MetalLookAndFeel.getBlack());
 159:     else
 160:       g.setColor(MetalLookAndFeel.getControlDisabled());
 161: 
 162:     if (direction == SOUTH)
 163:       {
 164:         int x = w / 2;
 165:         int y = h / 2 + 2;
 166:         for (int i = 1; i < 5; i++)
 167:           g.drawLine(x - i, y - i, x + i - 1, y - i);
 168:       }
 169:     else if (direction == EAST)
 170:       {
 171:         int x = w / 2 + 2;
 172:         int y = h / 2;
 173:         for (int i = 1; i < 5; i++)
 174:           g.drawLine(x - i, y - i, x - i, y + i - 1);
 175:       }
 176:     else if (direction == WEST)
 177:       {
 178:         int x = w / 2 - 3;
 179:         int y = h / 2;
 180:         for (int i = 1; i < 5; i++)
 181:           g.drawLine(x + i, y - i, x + i, y + i - 1);
 182:       }
 183:     else // assume NORTH
 184:       {
 185:         int x = w / 2;
 186:         int y = h / 2 - 3;
 187:         for (int i = 1; i < 5; i++)
 188:           g.drawLine(x - i, y + i, x + i - 1, y + i);
 189:       }
 190:   }
 191:   /**
 192:    * Paints the border for a button with a {@link #NORTH} direction that
 193:    * belongs to a free standing scroll bar.
 194:    *
 195:    * @param g  the graphics device.
 196:    * @param w  the button width.
 197:    * @param h  the button height.
 198:    */
 199:   private void paintNorthBorderFreeStanding(Graphics g, int w, int h)
 200:   {
 201:     if (isEnabled())
 202:       {
 203:         g.setColor(MetalLookAndFeel.getControlDarkShadow());
 204:         g.drawLine(0, 0, w - 2, 0);
 205:         g.drawLine(0, 0, 0, h - 1);
 206:         g.drawLine(2, h - 1, w - 2, h - 1);
 207:         g.drawLine(w - 2, 2, w - 2, h - 1);
 208: 
 209:         g.setColor(MetalLookAndFeel.getControlHighlight());
 210:         g.drawLine(1, 1, 1, h - 2);
 211:         g.drawLine(1, 1, w - 3, 1);
 212:         g.drawLine(w - 1, 1, w - 1, h - 1);
 213: 
 214:         g.setColor(MetalLookAndFeel.getControl());
 215:         g.drawLine(1, h - 1, 1, h - 1);
 216:         g.drawLine(w - 2, 1, w - 2, 1);
 217:       }
 218:     else
 219:       {
 220:         g.setColor(MetalLookAndFeel.getControlDisabled());
 221:         g.drawLine(0, 0, w - 1, 0);
 222:         g.drawLine(w - 1, 0, w - 1, h - 1);
 223:         g.drawLine(0, 0, 0, h - 1);
 224:       }
 225:   }
 226: 
 227:   /**
 228:    * Paints the border for a button with a {@link #SOUTH} direction that
 229:    * belongs to a free standing scroll bar.
 230:    *
 231:    * @param g  the graphics device.
 232:    * @param w  the button width.
 233:    * @param h  the button height.
 234:    */
 235:   private void paintSouthBorderFreeStanding(Graphics g, int w, int h)
 236:   {
 237:     if (isEnabled())
 238:       {
 239:         g.setColor(MetalLookAndFeel.getControlDarkShadow());
 240:         g.drawLine(0, 0, w - 2, 0);
 241:         g.drawLine(0, 0, 0, h - 1);
 242:         g.drawLine(2, h - 1, w - 2, h - 1);
 243:         g.drawLine(w - 2, 2, w - 2, h - 1);
 244: 
 245:         g.setColor(MetalLookAndFeel.getControlHighlight());
 246:         g.drawLine(1, 1, 1, h - 1);
 247:         g.drawLine(1, 1, w - 1, 1);
 248:         g.drawLine(w - 1, 1, w - 1, h - 1);
 249: 
 250:         g.setColor(MetalLookAndFeel.getControl());
 251:         g.drawLine(1, h - 1, 1, h - 1);
 252:         g.drawLine(w - 1, 1, w - 1, 1);
 253:       }
 254:     else
 255:       {
 256:         g.setColor(MetalLookAndFeel.getControlDisabled());
 257:         g.drawLine(0, h - 1, w - 1, h - 1);
 258:         g.drawLine(w - 1, 0, w - 1, h - 1);
 259:         g.drawLine(0, 0, 0, h - 1);
 260:       }
 261:   }
 262: 
 263:   /**
 264:    * Paints the border for a button with an {@link #EAST} direction that
 265:    * belongs to a free standing scroll bar.
 266:    *
 267:    * @param g  the graphics device.
 268:    * @param w  the button width.
 269:    * @param h  the button height.
 270:    */
 271:   private void paintEastBorderFreeStanding(Graphics g, int w, int h)
 272:   {
 273:     if (isEnabled())
 274:       {
 275:         g.setColor(MetalLookAndFeel.getControlDarkShadow());
 276:         g.drawLine(0, 0, w - 2, 0);
 277:         g.drawLine(w - 2, 0, w - 2, h - 2);
 278:         g.drawLine(0, h - 2, w - 2, h - 2);
 279: 
 280:         g.setColor(MetalLookAndFeel.getControlHighlight());
 281:         g.drawLine(0, 1, w - 1, 1);
 282:         g.drawLine(w - 1, 1, w - 1, h - 1);
 283:         g.drawLine(0, h - 1, w - 1, h - 1);
 284: 
 285:         g.setColor(MetalLookAndFeel.getControl());
 286:         g.drawLine(w - 2, 1, w - 2, 1);
 287:       }
 288:     else
 289:       {
 290:         g.setColor(MetalLookAndFeel.getControlDisabled());
 291:         g.drawLine(0, 0, w - 1, 0);
 292:         g.drawLine(w - 1, 0, w - 1, h - 1);
 293:         g.drawLine(0, h - 1, w - 1, h - 1);
 294:       }
 295:   }
 296: 
 297:   /**
 298:    * Paints the border for a button with a {@link #WEST} direction that
 299:    * belongs to a free standing scroll bar.
 300:    *
 301:    * @param g  the graphics device.
 302:    * @param w  the button width.
 303:    * @param h  the button height.
 304:    */
 305:   private void paintWestBorderFreeStanding(Graphics g, int w, int h)
 306:   {
 307:     if (isEnabled())
 308:       {
 309:         g.setColor(MetalLookAndFeel.getControlDarkShadow());
 310:         g.drawLine(0, 0, w - 1, 0);
 311:         g.drawLine(0, 0, 0, h - 2);
 312:         g.drawLine(0, h - 2, w - 1, h - 2);
 313: 
 314:         g.setColor(MetalLookAndFeel.getControlHighlight());
 315:         g.drawLine(1, 1, w - 1, 1);
 316:         g.drawLine(1, 1, 1, h - 1);
 317:         g.drawLine(1, h - 1, w - 1, h - 1);
 318: 
 319:         g.setColor(MetalLookAndFeel.getControl());
 320:         g.drawLine(1, h - 2, 1, h - 2);
 321:       }
 322:     else
 323:       {
 324:         g.setColor(MetalLookAndFeel.getControlDisabled());
 325:         g.drawLine(0, 0, w - 1, 0);
 326:         g.drawLine(0, 0, 0, h - 1);
 327:         g.drawLine(0, h - 1, w - 1, h - 1);
 328:       }
 329:   }
 330: 
 331:   /**
 332:    * Paints the border for a button with a {@link #NORTH} direction that
 333:    * belongs to a scroll bar that is not free standing.
 334:    *
 335:    * @param g  the graphics device.
 336:    * @param w  the button width.
 337:    * @param h  the button height.
 338:    */
 339:   private void paintNorthBorder(Graphics g, int w, int h)
 340:   {
 341:     if (isEnabled())
 342:       {
 343:         g.setColor(MetalLookAndFeel.getControlDarkShadow());
 344:         g.drawLine(0, 0, 0, h - 1);
 345: 
 346:         g.setColor(MetalLookAndFeel.getControlHighlight());
 347:         g.drawLine(1, 0, 1, h - 1);
 348:         g.drawLine(1, 0, w - 1, 0);
 349:       }
 350:     else
 351:       {
 352:         g.setColor(MetalLookAndFeel.getControlDisabled());
 353:         g.drawLine(0, 0, 0, h - 1);
 354:       }
 355:   }
 356: 
 357:   /**
 358:    * Paints the border for a button with a {@link #SOUTH} direction that
 359:    * belongs to a scroll bar that is not free standing.
 360:    *
 361:    * @param g  the graphics device.
 362:    * @param w  the button width.
 363:    * @param h  the button height.
 364:    */
 365:   private void paintSouthBorder(Graphics g, int w, int h)
 366:   {
 367:     if (isEnabled())
 368:       {
 369:         g.setColor(MetalLookAndFeel.getControlDarkShadow());
 370:         g.drawLine(0, 0, 0, h - 1);
 371:         g.drawLine(0, h - 1, w - 1, h - 1);
 372: 
 373:         g.setColor(MetalLookAndFeel.getControlHighlight());
 374:         g.drawLine(1, 0, 1, h - 1);
 375:         g.drawLine(1, 0, w - 1, 0);
 376: 
 377:         g.setColor(MetalLookAndFeel.getControl());
 378:         g.drawLine(1, h - 1, 1, h - 1);
 379:       }
 380:     else
 381:       {
 382:         g.setColor(MetalLookAndFeel.getControlDisabled());
 383:         g.drawLine(0, 0, 0, h - 1);
 384:       }
 385:   }
 386: 
 387:   /**
 388:    * Paints the border for a button with an {@link #EAST} direction that
 389:    * belongs to a scroll bar that is not free standing.
 390:    *
 391:    * @param g  the graphics device.
 392:    * @param w  the button width.
 393:    * @param h  the button height.
 394:    */
 395:   private void paintEastBorder(Graphics g, int w, int h)
 396:   {
 397:     if (isEnabled())
 398:       {
 399:         g.setColor(MetalLookAndFeel.getControlDarkShadow());
 400:         g.drawLine(0, 0, w - 1, 0);
 401:         g.drawLine(w - 1, 2, w - 1, h - 1);
 402:         g.setColor(MetalLookAndFeel.getControlHighlight());
 403:         g.drawLine(0, 1, w - 2, 1);
 404:         g.drawLine(0, 1, 0, h - 1);
 405:       }
 406:     else
 407:       {
 408:         g.setColor(MetalLookAndFeel.getControlDisabled());
 409:         g.drawLine(0, 0, w - 1, 0);
 410:       }
 411:   }
 412: 
 413:   /**
 414:    * Paints the border for a button with a {@link #WEST} direction that
 415:    * belongs to a scroll bar that is not free standing.
 416:    *
 417:    * @param g  the graphics device.
 418:    * @param w  the button width.
 419:    * @param h  the button height.
 420:    */
 421:   private void paintWestBorder(Graphics g, int w, int h)
 422:   {
 423:     Rectangle bounds = SwingUtilities.getLocalBounds(this);
 424:     if (isEnabled())
 425:       {
 426:         g.setColor(MetalLookAndFeel.getControlDarkShadow());
 427:         g.drawLine(0, 0, bounds.width - 1, 0);
 428:         g.setColor(MetalLookAndFeel.getControlHighlight());
 429:         g.drawLine(0, 1, bounds.width - 1, 1);
 430:         g.drawLine(0, 1, 0, bounds.height - 1);
 431:       }
 432:     else
 433:       {
 434:         g.setColor(MetalLookAndFeel.getControlDisabled());
 435:         g.drawLine(0, 0, bounds.width - 1, 0);
 436:       }
 437:   }
 438: 
 439:   /**
 440:    * Returns the preferred size for the button, which varies depending on
 441:    * the direction of the button and whether or not it is free standing.
 442:    *
 443:    * @return The preferred size.
 444:    */
 445:   public Dimension getPreferredSize()
 446:   {
 447:     int adj = 1;
 448:     if (!freeStanding)
 449:       adj = 2;
 450: 
 451:     if (direction == EAST)
 452:       return new Dimension(buttonWidth - adj, buttonWidth);
 453:     else if (direction == WEST)
 454:       return new Dimension(buttonWidth - 2, buttonWidth);
 455:     else if (direction == SOUTH)
 456:       return new Dimension(buttonWidth, buttonWidth - adj);
 457:     else // assume NORTH
 458:       return new Dimension(buttonWidth, buttonWidth - 2);
 459:   }
 460: 
 461:   /**
 462:    * Returns the minimum size for the button.
 463:    *
 464:    * @return The minimum size for the button.
 465:    */
 466:   public Dimension getMinimumSize()
 467:   {
 468:     return getPreferredSize();
 469:   }
 470: 
 471:   /**
 472:    * Returns the maximum size for the button.
 473:    *
 474:    * @return <code>Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE)</code>.
 475:    */
 476:   public Dimension getMaximumSize()
 477:   {
 478:     if (maximumSize == null)
 479:       maximumSize = new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
 480:     return maximumSize;
 481:   }
 482: 
 483: }