Source for javax.swing.plaf.metal.MetalBorders

   1: /* MetalBorders.java
   2:    Copyright (C) 2005, 2006, 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.Color;
  42: import java.awt.Component;
  43: import java.awt.Graphics;
  44: import java.awt.Insets;
  45: 
  46: import javax.swing.AbstractButton;
  47: import javax.swing.ButtonModel;
  48: import javax.swing.JButton;
  49: import javax.swing.JInternalFrame;
  50: import javax.swing.JMenu;
  51: import javax.swing.JMenuBar;
  52: import javax.swing.JMenuItem;
  53: import javax.swing.JOptionPane;
  54: import javax.swing.JScrollPane;
  55: import javax.swing.JTextField;
  56: import javax.swing.JToggleButton;
  57: import javax.swing.JToolBar;
  58: import javax.swing.SwingConstants;
  59: import javax.swing.UIManager;
  60: import javax.swing.border.AbstractBorder;
  61: import javax.swing.border.Border;
  62: import javax.swing.border.CompoundBorder;
  63: import javax.swing.plaf.BorderUIResource;
  64: import javax.swing.plaf.UIResource;
  65: import javax.swing.plaf.basic.BasicBorders;
  66: import javax.swing.text.JTextComponent;
  67: 
  68: 
  69: /**
  70:  * A factory class that creates borders for the different Swing components.
  71:  *
  72:  * @author Roman Kennke (roman@kennke.org)
  73:  */
  74: public class MetalBorders
  75: {
  76: 
  77:   /** The shared instance for getButtonBorder(). */
  78:   private static Border buttonBorder;
  79: 
  80:   /** The shared instance for getToggleButtonBorder(). */
  81:   private static Border toggleButtonBorder;
  82: 
  83:   /** The shared instance for getDesktopIconBorder(). */
  84:   private static Border desktopIconBorder;
  85: 
  86:   /** The shared instance for getRolloverButtonBorder(). */
  87:   private static Border toolbarButtonBorder;
  88: 
  89:   /** The shared instance for getTextFieldBorder(). */
  90:   private static Border textFieldBorder;
  91: 
  92:   /** The shared instance for getTextBorder(). */
  93:   private static Border textBorder;
  94: 
  95:   /** The shared instance for getRolloverBorder(). */
  96:   private static Border rolloverBorder;
  97: 
  98:   /**
  99:    * A MarginBorder that gets shared by multiple components.
 100:    * Created on demand by the private helper function {@link
 101:    * #getMarginBorder()}.
 102:    */
 103:   private static BasicBorders.MarginBorder marginBorder;
 104: 
 105:   /**
 106:    * <p>A border used for {@link JButton} components.</p>
 107:    * 
 108:    * <p>This {@link Border} implementation can handle only instances of
 109:    * {@link AbstractButton} and their subclasses.</p>
 110:    * 
 111:    * <p>If the Metal Look and Feel's current theme is 'Ocean' the border
 112:    * will be painted with a special highlight when the mouse cursor if
 113:    * over the button (ie. the property <code>rollover</code> of the
 114:    * button's model is <code>true</code>) and is not a <b>direct</b>
 115:    * child of a {@link JToolBar}.</p> 
 116:    */
 117:   public static class ButtonBorder extends AbstractBorder implements UIResource
 118:   {
 119:     /** The borders insets. */
 120:     protected static Insets borderInsets = new Insets(3, 3, 3, 3);
 121: 
 122:     /**
 123:      * Creates a new instance of <code>ButtonBorder</code>.
 124:      */
 125:     public ButtonBorder()
 126:     {
 127:       // Nothing to do here.
 128:     }
 129: 
 130:     /**
 131:      * Paints the button border.
 132:      *
 133:      * @param c the component for which we paint the border
 134:      * @param g the Graphics context to use
 135:      * @param x the X coordinate of the upper left corner of c
 136:      * @param y the Y coordinate of the upper left corner of c
 137:      * @param w the width of c
 138:      * @param h the height of c
 139:      */
 140:     public void paintBorder(Component c, Graphics g, int x, int y, int w,
 141:                             int h)
 142:     {
 143:       // With the OceanTheme the button border is painted entirely different.
 144:       // However, I couldn't figure out how this is determined besides checking
 145:       // for instanceof OceanTheme. The button painting is definitely not
 146:       // influenced by a UI default property and it is definitely performed
 147:       // by the same Border class.
 148:       if (MetalLookAndFeel.getCurrentTheme() instanceof OceanTheme)
 149:         paintOceanButtonBorder(c, g, x, y, w, h);
 150:       else
 151:         paintDefaultButtonBorder(c, g, x, y, w, h);
 152:     }
 153: 
 154:     /**
 155:      * Paints the button border for the DefaultMetalTheme.
 156:      *
 157:      * @param c the component (button)
 158:      * @param g the graphics object to use
 159:      * @param x the upper left corner of the component, X coordinate
 160:      * @param y the upper left corner of the component, Y coordinate
 161:      * @param w the width of the component
 162:      * @param h the height of the component
 163:      */
 164:     private void paintDefaultButtonBorder(Component c, Graphics g, int x,
 165:                                           int y, int w, int h)
 166:     {
 167:       ButtonModel bmodel = null;
 168: 
 169:       // The RI will fail with a ClassCastException in such a situation.
 170:       // This code tries to be more helpful.
 171:       if (c instanceof AbstractButton)
 172:         bmodel = ((AbstractButton) c).getModel();
 173:       else
 174:         throw new IllegalStateException("A ButtonBorder is supposed to work "
 175:                                         + "only with AbstractButton and"
 176:                                         + "subclasses.");
 177: 
 178:       Color darkShadow = MetalLookAndFeel.getControlDarkShadow();
 179:       Color shadow = MetalLookAndFeel.getControlShadow();
 180:       Color light = MetalLookAndFeel.getControlHighlight();
 181:       Color middle = MetalLookAndFeel.getControl();
 182: 
 183:       if (c.isEnabled())
 184:         {
 185:           // draw dark border
 186:           g.setColor(darkShadow);
 187:           g.drawRect(x, y, w - 2, h - 2);
 188: 
 189:           // If the button is the default button, we paint a special border,
 190:           // regardless of the pressed state.
 191:           if (c instanceof JButton && ((JButton) c).isDefaultButton())
 192:             {
 193:               g.drawRect(x + 1, y + 1, w - 4, h - 4);
 194:               // Draw white highlight.
 195:               g.setColor(light);
 196:               g.drawLine(x + 2, y + 2, x + w - 4, y + 2);
 197:               g.drawLine(x + 2, y + 2, x + 2, y + h - 4);
 198:               g.drawLine(x + 2, y + h - 1, x + w - 1, y + h - 1);
 199:               g.drawLine(x + w - 1, y + 2, x + w - 1, y + h - 1);
 200:               // Draw crossing pixels.
 201:               g.setColor(middle);
 202:               g.fillRect(x + w - 2, y + 2, 1, 1);
 203:               g.fillRect(x + 2, y + h - 2, 1, 1);
 204:             }
 205:           else
 206:             {
 207:               // The normal border. This is used when the button is not
 208:               // pressed or the button is not armed.
 209:               if (! (bmodel.isPressed() && bmodel.isArmed()))
 210:                 {
 211:                   // draw light border
 212:                   g.setColor(light);
 213:                   g.drawRect(x + 1, y + 1, w - 2, h - 2);
 214: 
 215:                   // draw crossing pixels of both borders
 216:                   g.setColor(middle);
 217:                   g.drawLine(x + 1, y + h - 2, x + 1, y + h - 2);
 218:                   g.drawLine(x + w - 2, y + 1, x + w - 2, y + 1);
 219:                 }
 220:               // The pressed border. This border is painted only when
 221:               // the button is both pressed and armed.
 222:               else
 223:                 {
 224:                   // draw light border
 225:                   g.setColor(light);
 226:                   g.drawLine(x + w - 1, y + 1, x + w - 1, y + h - 1);
 227:                   g.drawLine(x + 1, y + h - 1, x + w - 1, y + h - 1);
 228: 
 229:                   // draw shadow border
 230:                   g.setColor(middle);
 231:                   g.drawLine(x + 1, y + 1, x + w - 2, y + 1);
 232:                   g.drawLine(x + 1, y + 1, x + 1, y + h - 2);
 233:  
 234:                   // draw crossing pixels of both borders
 235:                   g.setColor(shadow);
 236:                   g.drawRect(x + 1, y + h - 2, 0, 0);
 237:                   g.drawRect(x + w - 2, y + 1, 0, 0);
 238:                 }
 239:             }
 240:         }
 241:       else 
 242:         {
 243:           // draw disabled border
 244:           g.setColor(MetalLookAndFeel.getInactiveControlTextColor());
 245:           g.drawRect(x, y, w - 2, h - 2);          
 246:         }
 247:     }
 248: 
 249:     /**
 250:      * Paints the button border for the OceanTheme.
 251:      *
 252:      * @param c the button
 253:      * @param g the graphics context
 254:      * @param x the X coordinate of the upper left corner of the painting rect
 255:      * @param y the Y coordinate of the upper left corner of the painting rect
 256:      * @param w the width of the painting rect
 257:      * @param h the height of the painting rect
 258:      */
 259:     private void paintOceanButtonBorder(Component c, Graphics g, int x,
 260:                                         int y, int w, int h)
 261:     {
 262:       ButtonModel bmodel = null;
 263:       
 264:       // The RI will fail with a ClassCastException in such a situation.
 265:       // This code tries to be more helpful.
 266:       if (c instanceof AbstractButton)
 267:         bmodel = ((AbstractButton) c).getModel();
 268:       else
 269:         throw new IllegalStateException("A ButtonBorder is supposed to work "
 270:                                         + "only with AbstractButton and"
 271:                                         + "subclasses.");
 272: 
 273:       Color darkShadow = MetalLookAndFeel.getControlDarkShadow();
 274:       Color shadow = MetalLookAndFeel.getControlShadow();
 275:       Color light = MetalLookAndFeel.getControlHighlight();
 276:       Color middle = MetalLookAndFeel.getControl();
 277: 
 278:       if (c.isEnabled())
 279:         {
 280:           // Paint the pressed border if the button is pressed, or if
 281:           // the button is the default button. In the OceanTheme, the default
 282:           // button has the same border as a pressed button.
 283:           if (bmodel.isPressed() || ((c instanceof JButton)
 284:                                      && ((JButton) c).isDefaultButton()))
 285:             {
 286:               // Draw fat border.
 287:               g.setColor(darkShadow);
 288:               g.drawRect(x, y, w - 1, h - 1);
 289:               g.drawRect(x + 1, y + 1, w - 3, h - 3);
 290:             }
 291:           else if (bmodel.isRollover() && !(c.getParent() instanceof JToolBar))
 292:             {
 293:               // Paint a bigger border when the mouse is over the button but
 294:               // only if it is *not* part of a JToolBar.
 295:               g.setColor(shadow);
 296:               g.drawRect(x, y, w - 1, h - 1);
 297:               g.drawRect(x + 2, y + 2, w - 5, h - 5);
 298:               g.setColor(darkShadow);
 299:               g.drawRect(x + 1, y + 1, w - 3, h - 3);
 300:             }
 301:           else
 302:             {
 303:               g.setColor(darkShadow);
 304:               g.drawRect(x, y, w - 1, h - 1);
 305:             }
 306:         }
 307:       else 
 308:         {
 309:           // draw disabled border
 310:           g.setColor(MetalLookAndFeel.getInactiveControlTextColor());
 311:           g.drawRect(x, y, w - 2, h - 2);          
 312:         }
 313:     }
 314: 
 315:     /**
 316:      * Returns the insets of the <code>ButtonBorder</code>.
 317:      *
 318:      * @param c the component for which the border is used (ignored).
 319:      *
 320:      * @return The insets of the <code>ButtonBorder</code>.
 321:      */
 322:     public Insets getBorderInsets(Component c)
 323:     {
 324:       return borderInsets;
 325:     }
 326: 
 327:     /**
 328:      * Returns the insets of the <code>ButtonBorder</code> in the specified 
 329:      * <code>newInsets</code> object.
 330:      *
 331:      * @param c the component for which the border is used (ignored).
 332:      * @param newInsets the insets object where to put the values (
 333:      *                  <code>null</code> not permitted).
 334:      *
 335:      * @return The <code>newInsets</code> reference.
 336:      */
 337:     public Insets getBorderInsets(Component c, Insets newInsets)
 338:     {
 339:       newInsets.bottom = borderInsets.bottom;
 340:       newInsets.left = borderInsets.left;
 341:       newInsets.right = borderInsets.right;
 342:       newInsets.top = borderInsets.top;
 343:       return newInsets;
 344:     }
 345:   }
 346: 
 347:   /**
 348:    * A border used when painting {@link JInternalFrame} instances.
 349:    */
 350:   static class DesktopIconBorder extends AbstractBorder
 351:     implements UIResource
 352:   {
 353:     /**
 354:      * Creates a new border instance.
 355:      */
 356:     public DesktopIconBorder()
 357:     {
 358:       // Nothing to do here.
 359:     }
 360:     
 361:     /**
 362:      * Returns the border insets.
 363:      * 
 364:      * @param c  the component (ignored).
 365:      * 
 366:      * @return The border insets.
 367:      */
 368:     public Insets getBorderInsets(Component c)
 369:     {
 370:       return getBorderInsets(c, null);
 371:     }
 372:     
 373:     /**
 374:      * Returns the border insets.
 375:      * 
 376:      * @param c  the component (ignored).
 377:      * @return The border insets.
 378:      */
 379:     public Insets getBorderInsets(Component c, Insets newInsets)
 380:     {
 381:       if (newInsets == null)
 382:         newInsets = new Insets(3, 3, 2, 3);
 383:       else
 384:         {
 385:           newInsets.top = 3;
 386:           newInsets.left = 3;
 387:           newInsets.bottom = 2;
 388:           newInsets.right = 3;
 389:         }
 390:       return newInsets;  
 391:     }
 392:     
 393:     /**
 394:      * Paints the border for the specified component.
 395:      * 
 396:      * @param c  the component.
 397:      * @param g  the graphics device.
 398:      * @param x  the x-coordinate.
 399:      * @param y  the y-coordinate.
 400:      * @param w  the width.
 401:      * @param h  the height.
 402:      */
 403:     public void paintBorder(Component c, Graphics g, int x, int y, int w, 
 404:         int h)
 405:     {
 406:       g.setColor(MetalLookAndFeel.getControlDarkShadow());      
 407:       g.drawRect(x, y, w - 1, h - 1); 
 408:     }
 409:     
 410:   }
 411: 
 412:   /**
 413:    * A simple 3D border.
 414:    */
 415:   public static class Flush3DBorder extends AbstractBorder
 416:     implements UIResource
 417:   {
 418:     private static final Insets borderInsets = new Insets(2, 2, 2, 2);
 419:     
 420:     /**
 421:      * Creates a new border instance.
 422:      */
 423:     public Flush3DBorder()
 424:     {
 425:       // Nothing to do here.
 426:     }
 427:     
 428:     /**
 429:      * Returns the border insets.
 430:      * 
 431:      * @param c  the component (ignored).
 432:      * 
 433:      * @return The border insets.
 434:      */
 435:     public Insets getBorderInsets(Component c)
 436:     {
 437:       return borderInsets;
 438:     }
 439:     
 440:     /**
 441:      * Returns the border insets.
 442:      * 
 443:      * @param c  the component (ignored).
 444:      * @param newInsets  an existing insets instance, that will be populated
 445:      *                   with the border insets and returned as the result
 446:      *                   (<code>null</code> not permitted).
 447:      *                   
 448:      * @return The <code>newInsets</code> reference.
 449:      */
 450:     public Insets getBorderInsets(Component c, Insets newInsets)
 451:     {
 452:       newInsets.top = borderInsets.top;
 453:       newInsets.left = borderInsets.left;
 454:       newInsets.bottom = borderInsets.bottom;
 455:       newInsets.right = borderInsets.right;
 456:       return newInsets;  
 457:     }
 458:     
 459:     /**
 460:      * Paints the border for the specified component.
 461:      * 
 462:      * @param c  the component (ignored).
 463:      * @param g  the graphics device.
 464:      * @param x  the x-coordinate.
 465:      * @param y  the y-coordinate.
 466:      * @param w  the width.
 467:      * @param h  the height.
 468:      */
 469:     public void paintBorder(Component c, Graphics g, int x, int y, int w, 
 470:         int h)
 471:     {              
 472:       Color savedColor = g.getColor();
 473:       g.setColor(MetalLookAndFeel.getControlDarkShadow());
 474:       g.drawRect(x, y, w - 2, h - 2);
 475:       g.setColor(MetalLookAndFeel.getControlHighlight());
 476:       g.drawRect(x + 1, y + 1, w - 2, h - 2);
 477:       g.setColor(MetalLookAndFeel.getControl());
 478:       g.drawLine(x + 1, y + h - 2, x + 1, y + h - 2);
 479:       g.drawLine(x + w - 2, y + 1, x + w - 2, y + 1);
 480:       g.setColor(savedColor);
 481:     }
 482:     
 483:   }
 484:     
 485:   /**
 486:    * A border used for a {@link JInternalFrame} when it is being used as a 
 487:    * palette.
 488:    * 
 489:    * @since 1.3
 490:    */
 491:   public static class PaletteBorder extends AbstractBorder
 492:     implements UIResource
 493:   {
 494:     private static final Insets borderInsets = new Insets(1, 1, 1, 1);
 495: 
 496:     /**
 497:      * Creates a new <code>PaletteBorder</code>.
 498:      */
 499:     public PaletteBorder()
 500:     {
 501:       // Nothing to do here.
 502:     }
 503:     
 504:     /**
 505:      * Returns the border insets.
 506:      * 
 507:      * @param c  the component (ignored).
 508:      * 
 509:      * @return The border insets.
 510:      */
 511:     public Insets getBorderInsets(Component c)
 512:     {
 513:       return borderInsets;
 514:     }
 515: 
 516:     /**
 517:      * Returns the border insets.
 518:      * 
 519:      * @param c  the component (ignored).
 520:      * @param newInsets  an existing insets instance, that will be populated
 521:      *                   with the border insets and returned as the result
 522:      *                   (<code>null</code> not permitted).
 523:      *                   
 524:      * @return The <code>newInsets</code> reference.
 525:      */
 526:     public Insets getBorderInsets(Component c, Insets newInsets)
 527:     {        
 528:       newInsets.top = borderInsets.top;
 529:       newInsets.left = borderInsets.left;
 530:       newInsets.bottom = borderInsets.bottom;
 531:       newInsets.right = borderInsets.right;
 532:       return newInsets;  
 533:     }
 534:     
 535:     /**
 536:      * Paints the border for the specified component.
 537:      * 
 538:      * @param c  the component (ignored).
 539:      * @param g  the graphics device.
 540:      * @param x  the x-coordinate.
 541:      * @param y  the y-coordinate.
 542:      * @param w  the width.
 543:      * @param h  the height.
 544:      */
 545:     public void paintBorder(Component c, Graphics g, int x, int y, int w, 
 546:             int h)
 547:     {
 548:       Color savedColor = g.getColor();
 549:       
 550:       // draw the outline
 551:       g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
 552:       g.drawRect(x, y, w - 1, h - 1);
 553:       
 554:       // put a dot in each corner
 555:       g.setColor(MetalLookAndFeel.getControl());
 556:       g.fillRect(x, y, 1, 1);
 557:       g.fillRect(x + w - 1, y, 1, 1);
 558:       g.fillRect(x + w - 1, y + h - 1, 1, 1);
 559:       g.fillRect(x, y + h - 1, 1, 1);      
 560:       g.setColor(savedColor);
 561:     }
 562: 
 563:   }
 564:     
 565:   /**
 566:    * A border used for the {@link JTextField} component.
 567:    */
 568:   public static class TextFieldBorder extends Flush3DBorder
 569:     implements UIResource
 570:   {
 571:     /**
 572:      * Creates a new border instance.
 573:      */
 574:     public TextFieldBorder()
 575:     {
 576:       // Nothing to do here.
 577:     }
 578:     
 579:     /**
 580:      * Paints the border for the specified component.
 581:      * 
 582:      * @param c  the component (ignored).
 583:      * @param g  the graphics device.
 584:      * @param x  the x-coordinate.
 585:      * @param y  the y-coordinate.
 586:      * @param w  the width.
 587:      * @param h  the height.
 588:      */
 589:     public void paintBorder(Component c, Graphics g, int x, int y, int w, 
 590:         int h)
 591:     {
 592:       boolean enabledTextBorder;
 593:       if (c instanceof JTextComponent)
 594:         {
 595:           JTextComponent tc = (JTextComponent) c;
 596:           enabledTextBorder = tc.isEnabled() && tc.isEditable();
 597:         }
 598:       else
 599:         enabledTextBorder = false;
 600: 
 601:       if (enabledTextBorder)
 602:         super.paintBorder(c, g, x, y, w, h);
 603:       else
 604:         {
 605:           Color savedColor = g.getColor();
 606:           g.setColor(MetalLookAndFeel.getControlShadow());
 607:           g.drawRect(x, y, w - 1, h - 1);
 608:           g.setColor(savedColor);
 609:         }
 610:     }
 611:     
 612:   }
 613: 
 614:   /**
 615:    * A border used for the {@link JInternalFrame} component.
 616:    */
 617:   public static class InternalFrameBorder extends AbstractBorder
 618:     implements UIResource
 619:   {
 620:     private static final Insets borderInsets = new Insets(5, 5, 5, 5);
 621: 
 622:     /**
 623:      * Creates a new border instance.
 624:      */
 625:     public InternalFrameBorder()
 626:     {
 627:       // Nothing to do here.
 628:     }
 629:     
 630:     /**
 631:      * Returns the border insets.
 632:      * 
 633:      * @param c  the component (ignored).
 634:      * 
 635:      * @return The border insets.
 636:      */
 637:     public Insets getBorderInsets(Component c)
 638:     {
 639:       return borderInsets;
 640:     }
 641:     
 642:     /**
 643:      * Returns the border insets.
 644:      * 
 645:      * @param c  the component (ignored).
 646:      * @param newInsets  an existing insets instance, that will be populated
 647:      *                   with the border insets and returned as the result
 648:      *                   (<code>null</code> not permitted).
 649:      *                   
 650:      * @return The <code>newInsets</code> reference.
 651:      */
 652:     public Insets getBorderInsets(Component c, Insets newInsets)
 653:     {
 654:       newInsets.top = borderInsets.top;
 655:       newInsets.left = borderInsets.left;
 656:       newInsets.bottom = borderInsets.bottom;
 657:       newInsets.right = borderInsets.right;
 658:       return newInsets;  
 659:     }
 660:     
 661:     /**
 662:      * Paints the border for the specified component.
 663:      * 
 664:      * @param c  the component.
 665:      * @param g  the graphics device.
 666:      * @param x  the x-coordinate.
 667:      * @param y  the y-coordinate.
 668:      * @param w  the width.
 669:      * @param h  the height.
 670:      */
 671:     public void paintBorder(Component c, Graphics g, int x, int y, int w, 
 672:         int h)
 673:     {
 674:         
 675:       JInternalFrame f = (JInternalFrame) c;
 676:       if (f.isSelected())
 677:         g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
 678:       else
 679:         g.setColor(MetalLookAndFeel.getControlDarkShadow());
 680:       
 681:       // fill the border background
 682:       g.fillRect(x, y, w, 5);
 683:       g.fillRect(x, y, 5, h);
 684:       g.fillRect(x + w - 5, y, 5, h);
 685:       g.fillRect(x, y + h - 5, w, 5);
 686:       
 687:       // draw a dot in each corner
 688:       g.setColor(MetalLookAndFeel.getControl());
 689:       g.fillRect(x, y, 1, 1);
 690:       g.fillRect(x + w - 1, y, 1, 1);
 691:       g.fillRect(x + w - 1, y + h - 1, 1, 1);
 692:       g.fillRect(x, y + h - 1, 1, 1);
 693:       
 694:       // draw the lines
 695:       g.setColor(MetalLookAndFeel.getBlack());
 696:       g.drawLine(x + 14, y + 2, x + w - 15, y + 2);
 697:       g.drawLine(x + 14, y + h - 3, x + w - 15, y + h - 3);
 698:       g.drawLine(x + 2, y + 14, x + 2, y + h - 15);
 699:       g.drawLine(x + w - 3, y + 14, x + w - 3, y + h - 15);
 700:       
 701:       // draw the line highlights
 702:       if (f.isSelected())
 703:         g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
 704:       else 
 705:         g.setColor(MetalLookAndFeel.getControlShadow());
 706:       g.drawLine(x + 15, y + 3, x + w - 14, y + 3);
 707:       g.drawLine(x + 15, y + h - 2, x + w - 14, y + h - 2);
 708:       g.drawLine(x + 3, y + 15, x + 3, y + h - 14);
 709:       g.drawLine(x + w - 2, y + 15, x + w - 2, y + h - 14);
 710:     }
 711:     
 712:   }
 713: 
 714:   /**
 715:    * A border used for {@link JInternalFrame} components that are
 716:    * presented as dialogs (by the {@link JOptionPane} class).
 717:    */
 718:   public static class OptionDialogBorder extends AbstractBorder
 719:     implements UIResource
 720:   {
 721:       
 722:     /**
 723:      * Creates a new border instance.
 724:      */
 725:     public OptionDialogBorder()
 726:     {
 727:       // Nothing to do here.
 728:     }
 729:     
 730:     /**
 731:      * Returns the border insets.
 732:      * 
 733:      * @param c  the component (ignored).
 734:      * 
 735:      * @return The border insets.
 736:      */
 737:     public Insets getBorderInsets(Component c)
 738:     {
 739:       return getBorderInsets(c, null);
 740:     }
 741:     
 742:     /**
 743:      * Returns the border insets.
 744:      * 
 745:      * @param c  the component (ignored).
 746:      * @return The border insets.
 747:      */
 748:     public Insets getBorderInsets(Component c, Insets newInsets)
 749:     {
 750:       if (newInsets == null)
 751:         newInsets = new Insets(3, 3, 3, 3);
 752:       else
 753:         {
 754:           newInsets.top = 3;
 755:           newInsets.left = 3;
 756:           newInsets.bottom = 3;
 757:           newInsets.right = 3;
 758:         }
 759:       return newInsets;  
 760:     }
 761:         
 762:     /**
 763:      * Paints the border for the specified component.
 764:      * 
 765:      * @param c  the component.
 766:      * @param g  the graphics device.
 767:      * @param x  the x-coordinate.
 768:      * @param y  the y-coordinate.
 769:      * @param w  the width.
 770:      * @param h  the height.
 771:      */
 772:     public void paintBorder(Component c, Graphics g, int x, int y, int w, 
 773:         int h)
 774:     {
 775:         
 776:       JInternalFrame f = (JInternalFrame) c;
 777:       g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
 778:       if (f.getContentPane() instanceof JOptionPane)
 779:         {
 780:           JOptionPane pane = (JOptionPane) f.getContentPane();
 781:           int type = pane.getMessageType();
 782:           if (type == JOptionPane.QUESTION_MESSAGE)
 783:             {
 784:               Color bc = UIManager.getColor(
 785:                   "OptionPane.questionDialog.border.background");
 786:               if (bc != null)
 787:                 g.setColor(bc);
 788:             }
 789:           if (type == JOptionPane.WARNING_MESSAGE)
 790:             {
 791:               Color bc = UIManager.getColor(
 792:                   "OptionPane.warningDialog.border.background");
 793:               if (bc != null)
 794:                 g.setColor(bc);              
 795:             }
 796:           else if (type == JOptionPane.ERROR_MESSAGE)
 797:             {
 798:               Color bc = UIManager.getColor(
 799:                   "OptionPane.errorDialog.border.background");
 800:               if (bc != null)
 801:                 g.setColor(bc);              
 802:             }
 803:         }
 804:       
 805:       // fill the border background
 806:       g.fillRect(x, y, w, 3);
 807:       g.fillRect(x, y, 3, h);
 808:       g.fillRect(x + w - 3, y, 3, h);
 809:       g.fillRect(x, y + h - 3, w, 3);
 810:       
 811:       // draw a dot in each corner
 812:       g.setColor(MetalLookAndFeel.getControl());
 813:       g.fillRect(x, y, 1, 1);
 814:       g.fillRect(x + w - 1, y, 1, 1);
 815:       g.fillRect(x + w - 1, y + h - 1, 1, 1);
 816:       g.fillRect(x, y + h - 1, 1, 1);
 817:       
 818:     }
 819:     
 820:   }
 821: 
 822:   /**
 823:    * A border used for {@link JMenu} and {@link JMenuItem} components.
 824:    */
 825:   public static class MenuItemBorder extends AbstractBorder
 826:     implements UIResource
 827:   {
 828:     /** The border insets. */
 829:     protected static Insets borderInsets = new Insets(2, 2, 2, 2);
 830:     
 831:     /**
 832:      * Creates a new border instance.
 833:      */
 834:     public MenuItemBorder()
 835:     {
 836:       // Nothing to do here.
 837:     }
 838:     
 839:     /**
 840:      * Paints the border for the component.  A border is painted only if the
 841:      * component is a selected {@link JMenu} or an armed {@link JMenuItem}.
 842:      * 
 843:      * @param c  the component.
 844:      * @param g  the graphics device.
 845:      * @param x  the x-coordinate of the border area.
 846:      * @param y  the y-coordinate of the border area.
 847:      * @param w  the width of the border area.
 848:      * @param h  the height of the border area.
 849:      */
 850:     public void paintBorder(Component c, Graphics g, int x, int y, int w,
 851:         int h)
 852:     {
 853:       Color dark = MetalLookAndFeel.getPrimaryControlDarkShadow();
 854:       Color light = MetalLookAndFeel.getPrimaryControlHighlight();
 855:       if (c instanceof JMenu) 
 856:         {
 857:           JMenu menu = (JMenu) c;
 858:           if (menu.isSelected())
 859:             {
 860:               g.setColor(dark);
 861:               g.drawLine(x, y, x, y + h);
 862:               g.drawLine(x, y, x + w, y);
 863:               g.drawLine(x + w - 2, y + 1, x + w - 2, y + h);
 864:               g.setColor(light);
 865:               g.drawLine(x + w - 1, y + 1, x + w - 1, y + h);
 866:             }
 867:         }
 868:       else if (c instanceof JMenuItem)
 869:         {
 870:           JMenuItem item = (JMenuItem) c;
 871:           if (item.isArmed()) 
 872:             {
 873:               g.setColor(dark);
 874:               g.drawLine(x, y, x + w, y);
 875:               g.setColor(light);
 876:               g.drawLine(x, y + h - 1, x + w, y + h - 1);
 877:             }
 878:           else
 879:             {
 880:               // Normally we draw a light line on the left.
 881:               g.setColor(light);
 882:               g.drawLine(x, y, x, y + h);
 883:             }
 884:         }
 885:     }
 886:     
 887:     /**
 888:      * Returns the border insets.
 889:      * 
 890:      * @param c  the component (ignored).
 891:      * 
 892:      * @return The border insets.
 893:      */
 894:     public Insets getBorderInsets(Component c)
 895:     {
 896:       return borderInsets;
 897:     }
 898:     
 899:     /**
 900:      * Populates <code>insets</code> with the border insets, then returns it.
 901:      * 
 902:      * @param c  the component (ignored).
 903:      * @param insets  the object to populate with the border insets.
 904:      * 
 905:      * @return The border insets.
 906:      * 
 907:      * @throws NullPointerException if <code>insets</code> is <code>null</code>.
 908:      */
 909:     public Insets getBorderInsets(Component c, Insets insets)
 910:     {
 911:       insets.left = borderInsets.left;
 912:       insets.top = borderInsets.top;
 913:       insets.bottom = borderInsets.bottom;
 914:       insets.right = borderInsets.right;
 915:       return insets;
 916:     }
 917:   }
 918: 
 919:   /**
 920:    * A border used for {@link JMenuBar} components.
 921:    */
 922:   public static class MenuBarBorder
 923:       extends AbstractBorder
 924:       implements UIResource
 925:   {
 926:     /** The border insets. */
 927:     protected static Insets borderInsets = new Insets(1, 0, 1, 0);
 928:     
 929:     // TODO: find where this color really comes from
 930:     private static Color borderColor = new Color(153, 153, 153);
 931:     
 932:     /**
 933:      * Creates a new border instance.
 934:      */
 935:     public MenuBarBorder()
 936:     {
 937:       // Nothing to do here.
 938:     }
 939:     
 940:     /**
 941:      * Paints the border for the component.  A border is painted only if the
 942:      * component is a selected {@link JMenu} or an armed {@link JMenuItem}.
 943:      * 
 944:      * @param c  the component.
 945:      * @param g  the graphics device.
 946:      * @param x  the x-coordinate of the border area.
 947:      * @param y  the y-coordinate of the border area.
 948:      * @param w  the width of the border area.
 949:      * @param h  the height of the border area.
 950:      */
 951:     public void paintBorder(Component c, Graphics g, int x, int y, int w,
 952:         int h)
 953:     {
 954:       g.setColor(borderColor);
 955:       g.drawLine(x, y + h - 1, x + w, y + h - 1);
 956:     }
 957:     
 958:     /**
 959:      * Returns the border insets.
 960:      * 
 961:      * @param c  the component (ignored).
 962:      * 
 963:      * @return The border insets.
 964:      */
 965:     public Insets getBorderInsets(Component c)
 966:     {
 967:       return borderInsets;
 968:     }
 969:     
 970:     /**
 971:      * Populates <code>insets</code> with the border insets, then returns it.
 972:      * 
 973:      * @param c  the component (ignored).
 974:      * @param insets  the object to populate with the border insets.
 975:      * 
 976:      * @return The border insets.
 977:      * 
 978:      * @throws NullPointerException if <code>insets</code> is <code>null</code>.
 979:      */
 980:     public Insets getBorderInsets(Component c, Insets insets)
 981:     {
 982:       insets.left = borderInsets.left;
 983:       insets.top = borderInsets.top;
 984:       insets.bottom = borderInsets.bottom;
 985:       insets.right = borderInsets.right;
 986:       return insets;
 987:     }
 988:   }
 989: 
 990:   /**
 991:    * A border for {@link JScrollPane} components.
 992:    */
 993:   public static class ScrollPaneBorder
 994:     extends AbstractBorder
 995:     implements UIResource
 996:   {
 997:     /** The border insets. */
 998:     private static Insets insets = new Insets(1, 1, 2, 2);
 999:     
1000:     /**
1001:      * Constructs a new ScrollPaneBorder.
1002:      */
1003:     public ScrollPaneBorder()
1004:     {
1005:       // Nothing to do here.
1006:     }
1007:     
1008:     /**
1009:      * Returns the insets of the border for the Component <code>c</code>.
1010:      *
1011:      * @param c the Component for which we return the border insets
1012:      */
1013:     public Insets getBorderInsets(Component c)
1014:     {
1015:       return insets;
1016:     }
1017: 
1018:     /**
1019:      * Paints the border.
1020:      *
1021:      * @param c the Component for which the border is painted
1022:      * @param g the Graphics context
1023:      * @param x the X coordinate of the upper left corner of the border
1024:      * @param y the Y coordinate of the upper left corner of the border
1025:      * @param w the width of the border
1026:      * @param h the height of the border
1027:      */
1028:     public void paintBorder(Component c, Graphics g, int x, int y,
1029:                             int w, int h)
1030:     {
1031:       Color darkShadow = MetalLookAndFeel.getControlDarkShadow();
1032:       Color shadow = MetalLookAndFeel.getControlShadow();
1033:       Color light = MetalLookAndFeel.getWhite();
1034:       Color middle = MetalLookAndFeel.getControl();
1035: 
1036:       // paint top border line
1037:       g.setColor(darkShadow);
1038:       g.drawLine(x, y, x + w - 2, y);
1039: 
1040:       // paint left border line
1041:       g.drawLine(x, y, x, y + h - 2);
1042:  
1043:       // paint right inner border line
1044:       g.drawLine(x + w - 2, y, x + w - 2, y + h + 1);
1045: 
1046:       // paint bottom inner border line
1047:       g.drawLine(x + 2, y + h - 2, x + w - 2, y + h - 2);
1048: 
1049:       // draw right outer border line
1050:       g.setColor(light);
1051:       g.drawLine(x + w - 1, y, x + w - 1, y + h - 1);
1052: 
1053:       // draw bottom outer border line
1054:       g.drawLine(x, y + h - 1, x + w - 1, y + h - 1);
1055: 
1056:       // paint the lighter points
1057:       g.setColor(middle);
1058:       g.drawLine(x + w - 1, y, x + w - 1, y);
1059:       g.drawLine(x + w - 2, y + 2, x + w - 2, y + 2);
1060:       g.drawLine(x, y + h - 1, x, y + h - 1);
1061:       g.drawLine(x + 1, y + h - 2, x + 1, y + h - 2);
1062: 
1063:     }
1064:     
1065:   }
1066:   
1067:   /**
1068:    * A button border that is only visible when the mouse pointer is within 
1069:    * the button's bounds.
1070:    */
1071:   public static class RolloverButtonBorder
1072:     extends MetalBorders.ButtonBorder
1073:   {
1074:     /**
1075:      * Creates a new border instance.
1076:      */
1077:     public RolloverButtonBorder()
1078:     {
1079:       // Nothing to do here.
1080:     }
1081:     
1082:     /**
1083:      * Paints the border.
1084:      * 
1085:      * @param c  the component.
1086:      * @param g  the graphics device.
1087:      * @param x  the x-coordinate.
1088:      * @param y  the y-coordinate.
1089:      * @param w  the width.
1090:      * @param h  the height.
1091:      */
1092:     public void paintBorder(Component c, Graphics g, int x, int y, int w, 
1093:             int h)
1094:     {
1095:       // TODO: What should be done here? Obviously the ButtonBorder already
1096:       // handles the rollover state in Sun's impl. Maybe this is only there
1097:       // for backwards compatibility.
1098:       super.paintBorder(c, g, x, y, w, h);
1099:     }
1100:   }
1101:   
1102:   /**
1103:    * This border is used in Toolbar buttons as inner border.
1104:    */
1105:   static class RolloverMarginBorder extends AbstractBorder
1106:   {
1107:     /** The borders insets. */
1108:     protected static Insets borderInsets = new Insets(3, 3, 3, 3);
1109: 
1110:     /**
1111:      * Creates a new instance of RolloverBorder.
1112:      */
1113:     public RolloverMarginBorder()
1114:     {
1115:       // Nothing to do here.
1116:     }
1117:     
1118:     /**
1119:      * Returns the insets of the RolloverBorder.
1120:      *
1121:      * @param c the component for which the border is used
1122:      *
1123:      * @return the insets of the RolloverBorder
1124:      */
1125:     public Insets getBorderInsets(Component c)
1126:     {
1127:       return getBorderInsets(c, null);
1128:     }
1129: 
1130:     /**
1131:      * Returns the insets of the RolloverMarginBorder in the specified
1132:      * Insets object.
1133:      *
1134:      * @param c the component for which the border is used
1135:      * @param newInsets the insets object where to put the values
1136:      *
1137:      * @return the insets of the RolloverMarginBorder
1138:      */
1139:     public Insets getBorderInsets(Component c, Insets newInsets)
1140:     {
1141:       if (newInsets == null)
1142:         newInsets = new Insets(0, 0, 0, 0);
1143: 
1144:       AbstractButton b = (AbstractButton) c;
1145:       Insets margin = b.getMargin();
1146:       newInsets.bottom = borderInsets.bottom;
1147:       newInsets.left = borderInsets.left;
1148:       newInsets.right = borderInsets.right;
1149:       newInsets.top = borderInsets.top;
1150:       return newInsets;
1151:     }
1152:   }
1153: 
1154:   /**
1155:    * A border implementation for popup menus.
1156:    */
1157:   public static class PopupMenuBorder
1158:     extends AbstractBorder
1159:     implements UIResource
1160:   {
1161: 
1162:     /** The border's insets. */
1163:     protected static Insets borderInsets = new Insets(3, 1, 2, 1);
1164: 
1165:     /**
1166:      * Constructs a new PopupMenuBorder.
1167:      */
1168:     public PopupMenuBorder()
1169:     {
1170:       // Nothing to do here.
1171:     }
1172:     
1173:     /**
1174:      * Returns the insets of the border, creating a new Insets instance
1175:      * with each call.
1176:      *
1177:      * @param c the component for which we return the border insets
1178:      *          (not used here)
1179:      */
1180:     public Insets getBorderInsets(Component c)
1181:     {
1182:       return getBorderInsets(c, null);
1183:     }
1184:     
1185:     /**
1186:      * Returns the insets of the border, using the supplied Insets instance.
1187:      *
1188:      * @param c the component for which we return the border insets
1189:      *          (not used here)
1190:      * @param i the Insets instance to fill with the Insets values
1191:      */
1192:     public Insets getBorderInsets(Component c, Insets i)
1193:     {
1194:       Insets insets;
1195:       if (i == null)
1196:         insets = new Insets(borderInsets.top, borderInsets.left,
1197:                             borderInsets.bottom, borderInsets.right);
1198:       else
1199:         {
1200:           insets = i;
1201:           insets.top = borderInsets.top;
1202:           insets.left = borderInsets.left;
1203:           insets.bottom = borderInsets.bottom;
1204:           insets.right = borderInsets.right;
1205:         }
1206:       
1207:       return insets;
1208:     }
1209: 
1210:     /**
1211:      * Paints the border for component <code>c</code> using the
1212:      * Graphics context <code>g</code> with the dimension
1213:      * <code>x, y, w, h</code>.
1214:      *
1215:      * @param c the component for which we paint the border
1216:      * @param g the Graphics context to use
1217:      * @param x the X coordinate of the upper left corner of c
1218:      * @param y the Y coordinate of the upper left corner of c
1219:      * @param w the width of c
1220:      * @param h the height of c
1221:      */
1222:     public void paintBorder(Component c, Graphics g, int x, int y, int w,
1223:                             int h)
1224:     {
1225:       Color darkShadow = MetalLookAndFeel.getPrimaryControlDarkShadow();
1226:       Color light = MetalLookAndFeel.getPrimaryControlHighlight();
1227: 
1228:       // draw dark outer border
1229:       g.setColor(darkShadow);
1230:       g.drawRect(x, y, w - 1, h - 1);
1231:       
1232:       // draw highlighted inner border (only top and left)
1233:       g.setColor(light);
1234:       g.drawLine(x + 1, y + 1, x + w - 2, y + 1);
1235:     }
1236:     
1237:   }
1238: 
1239:   /**
1240:    * A border used for the {@link JToggleButton} component.
1241:    * 
1242:    * @since 1.3
1243:    */
1244:   public static class ToggleButtonBorder
1245:     extends ButtonBorder 
1246:   {
1247:     /**
1248:      * Creates a new border instance.
1249:      */
1250:     public ToggleButtonBorder()
1251:     {
1252:       // Nothing to do here.
1253:     }
1254:     
1255:     /**
1256:      * Paints the toggle button border.
1257:      *
1258:      * @param c the component for which we paint the border
1259:      * @param g the Graphics context to use
1260:      * @param x the X coordinate of the upper left corner of c
1261:      * @param y the Y coordinate of the upper left corner of c
1262:      * @param w the width of c
1263:      * @param h the height of c
1264:      */
1265:     public void paintBorder(Component c, Graphics g, int x, int y, int w,
1266:                             int h)
1267:     {
1268:       ButtonModel bmodel = null;
1269:       
1270:       if (c instanceof AbstractButton)
1271:         bmodel = ((AbstractButton) c).getModel();
1272: 
1273:       Color darkShadow = MetalLookAndFeel.getControlDarkShadow();
1274:       Color shadow = MetalLookAndFeel.getControlShadow();
1275:       Color light = MetalLookAndFeel.getWhite();
1276:       Color middle = MetalLookAndFeel.getControl();
1277: 
1278:       if (c.isEnabled())
1279:         {
1280:           // draw dark border
1281:           g.setColor(darkShadow);
1282:           g.drawRect(x, y, w - 2, h - 2);
1283: 
1284:           if (!bmodel.isArmed())
1285:             {
1286:               // draw light border
1287:               g.setColor(light);
1288:               g.drawLine(x + 1, y + h - 1, x + w - 1, y + h - 1);
1289:               g.drawLine(x + w - 1, y + 1, x + w - 1, y + h - 1);
1290:               if (bmodel.isSelected())
1291:                 g.setColor(middle);
1292:               g.drawLine(x + 1, y + 1, x + w - 3, y + 1);
1293:               g.drawLine(x + 1, y + 1, x + 1, y + h - 3);
1294: 
1295:               // draw crossing pixels of both borders
1296:               g.setColor(shadow);
1297:               g.drawLine(x + 1, y + h - 2, x + 1, y + h - 2);
1298:               g.drawLine(x + w - 2, y + 1, x + w - 2, y + 1);
1299:             }
1300:           else
1301:             {
1302:               // draw light border
1303:               g.setColor(light);
1304:               g.drawLine(x + w - 1, y + 1, x + w - 1, y + h - 1);
1305:               g.drawLine(x + 1, y + h - 1, x + w - 1, y + h - 1);
1306: 
1307:               // draw shadow border
1308:               g.setColor(shadow);
1309:               g.drawLine(x + 1, y + 1, x + w - 2, y + 1);
1310:               g.drawLine(x + 1, y + 1, x + 1, y + h - 2);
1311:  
1312:               // draw crossing pixels of both borders
1313:               g.setColor(shadow);
1314:               g.drawLine(x + 1, y + h - 2, x + 1, y + h - 2);
1315:               g.drawLine(x + w - 2, y + 1, x + w - 2, y + 1);
1316:               
1317:             }
1318:           // draw corners
1319:           g.setColor(middle);
1320:           g.drawLine(x, y + h - 1, x, y + h - 1);
1321:           g.drawLine(x + w - 1, y, x + w - 1, y);
1322:         }
1323:       else 
1324:         {
1325:           // draw disabled border
1326:           g.setColor(MetalLookAndFeel.getControlDisabled());
1327:           g.drawRect(x, y, w - 2, h - 2);          
1328:         }
1329:     }
1330:   }
1331: 
1332:   /**
1333:    * A border used for the {@link JToolBar} component.
1334:    */
1335:   public static class ToolBarBorder extends AbstractBorder
1336:     implements UIResource, SwingConstants
1337:   {
1338:     /**
1339:      * Creates a new border instance.
1340:      */
1341:     public ToolBarBorder()
1342:     {
1343:       // Nothing to do here.
1344:     }
1345:     
1346:     /**
1347:      * Returns the border insets.
1348:      * 
1349:      * @param c  the component (ignored).
1350:      * 
1351:      * @return The border insets.
1352:      */
1353:     public Insets getBorderInsets(Component c)
1354:     {
1355:       return getBorderInsets(c, null);
1356:     }
1357:     
1358:     /**
1359:      * Returns the border insets.
1360:      * 
1361:      * @param c  the component (ignored).
1362:      * @return The border insets.
1363:      */
1364:     public Insets getBorderInsets(Component c, Insets newInsets)
1365:     {
1366:       JToolBar tb = (JToolBar) c;
1367:       if (tb.getOrientation() == JToolBar.HORIZONTAL)
1368:         {   
1369:           if (newInsets == null)
1370:             newInsets = new Insets(2, 16, 2, 2);
1371:           else
1372:             {
1373:               newInsets.top = 2;
1374:               newInsets.left = 16;
1375:               newInsets.bottom = 2;
1376:               newInsets.right = 2;
1377:             }
1378:           return newInsets;  
1379:         }
1380:       else // assume JToolBar.VERTICAL
1381:         { 
1382:           if (newInsets == null)
1383:             newInsets = new Insets(16, 2, 2, 2);
1384:           else
1385:             {
1386:               newInsets.top = 16;
1387:               newInsets.left = 2;
1388:               newInsets.bottom = 2;
1389:               newInsets.right = 2;
1390:             }
1391:           return newInsets;  
1392:         }
1393: 
1394:     }
1395:     
1396:     /**
1397:      * Paints the border for the specified component.
1398:      * 
1399:      * @param c  the component.
1400:      * @param g  the graphics device.
1401:      * @param x  the x-coordinate.
1402:      * @param y  the y-coordinate.
1403:      * @param w  the width.
1404:      * @param h  the height.
1405:      */
1406:     public void paintBorder(Component c, Graphics g, int x, int y, int w, 
1407:         int h)
1408:     {
1409:         
1410:       JToolBar tb = (JToolBar) c;
1411:       if (tb.getOrientation() == JToolBar.HORIZONTAL)
1412:         {
1413:            MetalUtils.fillMetalPattern(tb, g, x + 2, y + 2, x + 11, y + h - 5, 
1414:                   MetalLookAndFeel.getControlHighlight(), 
1415:                   MetalLookAndFeel.getControlDarkShadow());
1416:         }
1417:       else
1418:         { 
1419:           MetalUtils.fillMetalPattern(tb, g, x + 2, y + 2, x + w - 5, y + 11, 
1420:                   MetalLookAndFeel.getControlHighlight(), 
1421:                   MetalLookAndFeel.getControlDarkShadow());
1422:         }
1423:     }
1424:     
1425:   }
1426:   
1427:   /**
1428:    * A border for table header cells.
1429:    *
1430:    * @since 1.3
1431:    */
1432:   public static class TableHeaderBorder extends AbstractBorder
1433:   {
1434:     /**
1435:      * The insets of this border.
1436:      */
1437:     // TODO: According to tests that I have done, this is really the border
1438:     // that should be returned by getBorderInsets(). However, the name
1439:     // is very distracting. Is there any deeper meaning in it?
1440:     protected Insets editorBorderInsets;
1441: 
1442:     /**
1443:      * Creates a new instance of <code>TableHeaderBorder</code>.
1444:      */
1445:     public TableHeaderBorder()
1446:     {
1447:       editorBorderInsets = new Insets(1, 1, 1, 1);
1448:     }
1449: 
1450:     /**
1451:      * Return the insets of this border.
1452:      *
1453:      * @return the insets of this border
1454:      */
1455:     public Insets getBorderInsets(Component c)
1456:     {
1457:       return editorBorderInsets;
1458:     }
1459: 
1460:     /**
1461:      * Paints the border.
1462:      *
1463:      * @param c the component for which to paint the border
1464:      * @param g the graphics context to use
1465:      * @param x the x cooridinate of the border rectangle
1466:      * @param y the y cooridinate of the border rectangle
1467:      * @param w the width of the border rectangle
1468:      * @param h the height of the border rectangle
1469:      */
1470:     public void paintBorder(Component c, Graphics g, int x, int y, int w, int h)
1471:     {
1472:       Color dark = MetalLookAndFeel.getControlDarkShadow();
1473:       Color light = MetalLookAndFeel.getWhite();
1474:       Color old = g.getColor();
1475:       g.setColor(light);
1476:       g.drawLine(x, y, x + w - 2, y);
1477:       g.drawLine(x, y, x, y + h - 2);
1478:       g.setColor(dark);
1479:       g.drawLine(x + w - 1, y, x + w - 1, y + h - 1);
1480:       g.drawLine(x + 1, y + h - 1, x + w - 1, y + h - 1);
1481:       g.setColor(old);
1482:     }
1483:   }
1484: 
1485:   /**
1486:    * Returns a border for Swing buttons in the Metal Look &amp; Feel.
1487:    *
1488:    * @return a border for Swing buttons in the Metal Look &amp; Feel
1489:    */
1490:   public static Border getButtonBorder()
1491:   {
1492:     if (buttonBorder == null)
1493:       {
1494:         Border outer = new ButtonBorder();
1495:         Border inner = getMarginBorder();
1496:         buttonBorder = new BorderUIResource.CompoundBorderUIResource(outer, 
1497:             inner);
1498:       }
1499:     return buttonBorder;
1500:   }
1501:   
1502:   /**
1503:    * Returns a border for use with {@link JToggleButton} components.
1504:    *
1505:    * @return A border.
1506:    * 
1507:    * @since 1.3
1508:    */
1509:   public static Border getToggleButtonBorder()
1510:   {
1511:     if (toggleButtonBorder == null)
1512:       {
1513:         Border outer = new ToggleButtonBorder();
1514:         Border inner = getMarginBorder();
1515:         toggleButtonBorder = new BorderUIResource.CompoundBorderUIResource(
1516:             outer, inner);
1517:       }
1518:     return toggleButtonBorder;
1519:   }
1520: 
1521:   /**
1522:    * Returns a border instance that is used with a {@link JInternalFrame} when
1523:    * it is in the iconified state.
1524:    * 
1525:    * @return A border.
1526:    * 
1527:    * @since 1.3
1528:    */
1529:   public static Border getDesktopIconBorder()
1530:   {
1531:     if (desktopIconBorder == null)
1532:       desktopIconBorder = new DesktopIconBorder();
1533:     return desktopIconBorder;      
1534:   }
1535: 
1536:   /**
1537:    * Returns a border for use by the {@link JTextField} component.
1538:    * 
1539:    * @return A border.
1540:    * 
1541:    * @since 1.3
1542:    */
1543:   public static Border getTextFieldBorder()
1544:   {
1545:     if (textFieldBorder == null)
1546:       {
1547:         Border inner = getMarginBorder();
1548:         Border outer = new TextFieldBorder();
1549:         textFieldBorder =
1550:           new BorderUIResource.CompoundBorderUIResource(outer, inner);
1551:       }
1552:     return textFieldBorder;
1553:   }
1554: 
1555:   /**
1556:    * Returns the border that is used for text components (except text fields,
1557:    * which use {@link #getTextFieldBorder}.
1558:    *
1559:    * @return the border that is used for text components
1560:    *
1561:    * @since 1.3
1562:    */
1563:   public static Border getTextBorder()
1564:   {
1565:     if (textBorder == null)
1566:       {
1567:         Border inner = getMarginBorder();
1568:         Border outer = new Flush3DBorder();
1569:         textBorder =
1570:           new BorderUIResource.CompoundBorderUIResource(outer, inner);
1571:       }
1572:     return textBorder;
1573:   }
1574: 
1575:   /**
1576:    * Returns a border for Toolbar buttons in the Metal Look &amp; Feel.
1577:    *
1578:    * @return a border for Toolbar buttons in the Metal Look &amp; Feel
1579:    */
1580:   static Border getToolbarButtonBorder()
1581:   {
1582:     if (toolbarButtonBorder == null)
1583:       {
1584:         Border outer = new ButtonBorder();
1585:         Border inner = new RolloverMarginBorder();
1586:         toolbarButtonBorder = new CompoundBorder(outer, inner);
1587:       }
1588:     return toolbarButtonBorder;
1589:   }
1590: 
1591:   /**
1592:    * Returns a shared instance of {@link BasicBorders.MarginBorder}.
1593:    *
1594:    * @return a shared instance of {@link BasicBorders.MarginBorder}
1595:    */
1596:   static Border getMarginBorder()
1597:   {
1598:     if (marginBorder == null)
1599:       marginBorder = new BasicBorders.MarginBorder();
1600:     return marginBorder;
1601:   }
1602: 
1603:   /**
1604:    * Returns a shared instance of a compound border for rollover buttons.
1605:    * 
1606:    * @return A shared border instance.
1607:    */
1608:   static Border getRolloverBorder()
1609:   {
1610:     if (rolloverBorder == null)
1611:       {
1612:         Border outer = new MetalBorders.RolloverButtonBorder();
1613:         Border inner = MetalBorders.getMarginBorder();
1614:         rolloverBorder = new BorderUIResource.CompoundBorderUIResource(outer, 
1615:             inner);
1616:       }
1617:     return rolloverBorder;
1618:   }
1619: 
1620: }