Source for javax.swing.plaf.metal.MetalIconFactory

   1: /* MetalIconFactory.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.io.Serializable;
  45: 
  46: import javax.swing.AbstractButton;
  47: import javax.swing.Icon;
  48: import javax.swing.JCheckBox;
  49: import javax.swing.JCheckBoxMenuItem;
  50: import javax.swing.JFileChooser;
  51: import javax.swing.JInternalFrame;
  52: import javax.swing.JRadioButton;
  53: import javax.swing.JRadioButtonMenuItem;
  54: import javax.swing.JSlider;
  55: import javax.swing.SwingConstants;
  56: import javax.swing.UIManager;
  57: import javax.swing.plaf.IconUIResource;
  58: import javax.swing.plaf.UIResource;
  59: 
  60: 
  61: /**
  62:  * Creates icons for the {@link MetalLookAndFeel}.
  63:  */
  64: public class MetalIconFactory implements Serializable 
  65: {
  66: 
  67:   /** A constant representing "dark". */
  68:   public static final boolean DARK = false;
  69:     
  70:   /** A constant representing "light". */
  71:   public static final boolean LIGHT = true;
  72:   
  73:   /** A shared instance of the MenuArrowIcon. */
  74:   private static Icon menuArrow;
  75:   
  76:   /** A shared instance of the MenuItemArrowIcon. */
  77:   private static Icon menuItemArrow;
  78:     
  79:   /**
  80:    * An icon displayed for {@link JCheckBoxMenuItem} components.
  81:    */
  82:   private static class CheckBoxMenuItemIcon 
  83:     implements Icon, UIResource, Serializable 
  84:   {
  85:     /**
  86:      * Creates a new icon instance.
  87:      */
  88:     public CheckBoxMenuItemIcon() 
  89:     {
  90:       // Nothing to do here.
  91:     }
  92:       
  93:     /**
  94:      * Returns the width of the icon, in pixels.
  95:      * 
  96:      * @return The width of the icon (10 pixels).
  97:      */
  98:     public int getIconWidth() 
  99:     {
 100:       return 10;
 101:     }
 102:     
 103:     /**
 104:      * Returns the height of the icon, in pixels.
 105:      * 
 106:      * @return The height of the icon (10 pixels).
 107:      */
 108:     public int getIconHeight() 
 109:     {
 110:       return 10;
 111:     }
 112:     
 113:     /**
 114:      * Paints the icon.
 115:      * 
 116:      * @param c  the component.
 117:      * @param g  the graphics device.
 118:      * @param x  the x-coordinate.
 119:      * @param y  the y-coordinate.
 120:      */
 121:     public void paintIcon(Component c, Graphics g, int x, int y) 
 122:     {
 123:       JCheckBoxMenuItem item = (JCheckBoxMenuItem) c;
 124:         
 125:       if (item.isArmed())
 126:         g.setColor(MetalLookAndFeel.getBlack());
 127:       else
 128:         g.setColor(MetalLookAndFeel.getControlDarkShadow());
 129:       g.drawLine(x, y, x + 8, y);
 130:       g.drawLine(x, y + 1, x, y + 8);
 131:       g.drawLine(x + 2, y + 8, x + 8, y + 8);
 132:       g.drawLine(x + 8, y + 2, x + 8, y + 7);
 133:       
 134:       g.setColor(MetalLookAndFeel.getWhite());
 135:       g.drawLine(x + 1, y + 1, x + 7, y + 1);
 136:       g.drawLine(x + 1, y + 2, x + 1, y + 7);
 137:       g.drawLine(x + 1, y + 9, x + 9, y + 9);
 138:       g.drawLine(x + 9, y + 1, x + 9, y + 8);
 139: 
 140:       // if the item is selected, we should draw a tick
 141:       if (item.isSelected())
 142:       {
 143:         g.setColor(MetalLookAndFeel.getBlack());
 144:         g.fillRect(x + 2, y + 2, 2, 5);
 145:         for (int i = 0; i < 6; i++)
 146:           g.drawLine(x + 8 - i, y + i, x + 9 - i, y + i);
 147:       }
 148: 
 149:     }        
 150:   }
 151: 
 152:   /**
 153:    * An icon used for the "detail view" button on a {@link JFileChooser} under
 154:    * the {@link MetalLookAndFeel}.
 155:    * 
 156:    * @see MetalIconFactory#getFileChooserDetailViewIcon()
 157:    */
 158:   private static class FileChooserDetailViewIcon 
 159:     implements Icon, UIResource, Serializable
 160:   {
 161: 
 162:     /**
 163:      * Creates a new icon.
 164:      */
 165:     public FileChooserDetailViewIcon() 
 166:     {
 167:       // Nothing to do here.
 168:     }
 169:       
 170:     /**
 171:      * Returns the width of the icon, in pixels.
 172:      * 
 173:      * @return The width of the icon.
 174:      */
 175:     public int getIconWidth() 
 176:     {
 177:       return 18;
 178:     }
 179:     
 180:     /**
 181:      * Returns the height of the icon, in pixels.
 182:      * 
 183:      * @return The height of the icon.
 184:      */
 185:     public int getIconHeight() 
 186:     {
 187:       return 18;
 188:     }
 189:     
 190:     /**
 191:      * Paints the icon using colors from the {@link MetalLookAndFeel}.
 192:      * 
 193:      * @param c  the component (ignored).
 194:      * @param g  the graphics device.
 195:      * @param x  the x-coordinate for the top-left of the icon.
 196:      * @param y  the y-coordinate for the top-left of the icon.
 197:      */
 198:     public void paintIcon(Component c, Graphics g, int x, int y) 
 199:     {
 200:       Color savedColor = g.getColor();
 201:       g.setColor(MetalLookAndFeel.getBlack());
 202: 
 203:       // file 1 outline
 204:       g.drawLine(x + 2, y + 2, x + 5, y + 2);
 205:       g.drawLine(x + 6, y + 3, x + 6, y + 7);
 206:       g.drawLine(x + 2, y + 7, x + 6, y + 7);
 207:       g.drawLine(x + 2, y + 2, x + 2, y + 7);
 208:       
 209:       // file 2 outline
 210:       g.drawLine(x + 2, y + 10, x + 5, y + 10);
 211:       g.drawLine(x + 6, y + 11, x + 6, y + 15);
 212:       g.drawLine(x + 2, y + 15, x + 6, y + 15);
 213:       g.drawLine(x + 2, y + 10, x + 2, y + 15);
 214: 
 215:       // detail lines
 216:       g.drawLine(x + 8, y + 5, x + 15, y + 5);
 217:       g.drawLine(x + 8, y + 13, x + 15, y + 13);
 218:       
 219:       // fill files
 220:       g.setColor(MetalLookAndFeel.getPrimaryControl());
 221:       g.fillRect(x + 3, y + 3, 3, 4);
 222:       g.fillRect(x + 3, y + 11, 3, 4);
 223:       
 224:       // highlight files
 225:       g.setColor(MetalLookAndFeel.getPrimaryControlHighlight());
 226:       g.drawLine(x + 4, y + 4, x + 4, y + 5);
 227:       g.drawLine(x + 4, y + 12, x + 4, y + 13);
 228:       
 229:       g.setColor(savedColor);
 230:     }        
 231:   }
 232: 
 233:   /**
 234:    * An icon used for the "home folder" button on a {@link JFileChooser} under
 235:    * the {@link MetalLookAndFeel}.
 236:    * 
 237:    * @see MetalIconFactory#getFileChooserHomeFolderIcon()
 238:    */
 239:   private static class FileChooserHomeFolderIcon 
 240:     implements Icon, UIResource, Serializable
 241:   {
 242: 
 243:     /**
 244:      * Creates a new icon.
 245:      */
 246:     public FileChooserHomeFolderIcon() 
 247:     {
 248:       // Nothing to do here.
 249:     }
 250: 
 251:     /**
 252:      * Returns the width of the icon, in pixels.
 253:      * 
 254:      * @return The width of the icon.
 255:      */
 256:     public int getIconWidth() 
 257:     {
 258:       return 18;
 259:     }
 260:     
 261:     /**
 262:      * Returns the height of the icon, in pixels.
 263:      * 
 264:      * @return The height of the icon.
 265:      */
 266:     public int getIconHeight() 
 267:     {
 268:       return 18;
 269:     }
 270:     
 271:     /**
 272:      * Paints the icon using colors from the {@link MetalLookAndFeel}.
 273:      * 
 274:      * @param c  the component (ignored).
 275:      * @param g  the graphics device.
 276:      * @param x  the x-coordinate for the top-left of the icon.
 277:      * @param y  the y-coordinate for the top-left of the icon.
 278:      */
 279:     public void paintIcon(Component c, Graphics g, int x, int y) 
 280:     {   
 281:       Color savedColor = g.getColor();
 282:       g.setColor(MetalLookAndFeel.getBlack());
 283:       
 284:       // roof
 285:       g.drawLine(x + 1, y + 8, x + 8, y + 1);
 286:       g.drawLine(x + 8, y + 1, x + 15, y + 8);
 287:       
 288:       // base of house
 289:       g.drawLine(x + 3, y + 6, x + 3, y + 15);
 290:       g.drawLine(x + 3, y + 15, x + 13, y + 15);
 291:       g.drawLine(x + 13, y + 6, x + 13, y + 15);
 292:       
 293:       // door frame
 294:       g.drawLine(x + 6, y + 9, x + 6, y + 15);
 295:       g.drawLine(x + 6, y + 9, x + 10, y + 9);
 296:       g.drawLine(x + 10, y + 9, x + 10, y + 15);
 297:       
 298:       // chimney
 299:       g.drawLine(x + 11, y + 2, x + 11, y + 4);
 300:       g.drawLine(x + 12, y + 2, x + 12, y + 5);
 301:       
 302:       g.setColor(MetalLookAndFeel.getControlDarkShadow());
 303:       
 304:       // roof paint
 305:       int xx = x + 8;
 306:       for (int i = 0; i < 4; i++)
 307:         g.drawLine(xx - i, y + 2 + i, xx + i, y + 2 + i);
 308:       g.fillRect(x + 4, y + 6, 9, 2);
 309:       
 310:       // door knob
 311:       g.drawLine(x + 9, y + 12, x + 9, y + 12);
 312:       
 313:       // house paint
 314:       g.setColor(MetalLookAndFeel.getPrimaryControl());
 315:       g.drawLine(x + 4, y + 8, x + 12, y + 8);
 316:       g.fillRect(x + 4, y + 9, 2, 6);
 317:       g.fillRect(x + 11, y + 9, 2, 6);
 318:       
 319:       g.setColor(savedColor);
 320:     }        
 321:   }
 322:     
 323:   /**
 324:    * An icon used for the "list view" button on a {@link JFileChooser} under
 325:    * the {@link MetalLookAndFeel}.
 326:    * 
 327:    * @see MetalIconFactory#getFileChooserListViewIcon()
 328:    */
 329:   private static class FileChooserListViewIcon 
 330:     implements Icon, UIResource, Serializable 
 331:   {
 332:     /**
 333:      * Creates a new icon.
 334:      */
 335:     public FileChooserListViewIcon() 
 336:     {
 337:       // Nothing to do here.
 338:     }
 339:     
 340:     /**
 341:      * Returns the width of the icon, in pixels.
 342:      * 
 343:      * @return The width of the icon.
 344:      */
 345:     public int getIconWidth() 
 346:     {
 347:       return 18;
 348:     }
 349:     
 350:     /**
 351:      * Returns the height of the icon, in pixels.
 352:      * 
 353:      * @return The height of the icon.
 354:      */
 355:     public int getIconHeight() 
 356:     {
 357:       return 18;
 358:     }
 359:     
 360:     /**
 361:      * Paints the icon using colors from the {@link MetalLookAndFeel}.
 362:      * 
 363:      * @param c  the component (ignored).
 364:      * @param g  the graphics device.
 365:      * @param x  the x-coordinate for the top-left of the icon.
 366:      * @param y  the y-coordinate for the top-left of the icon.
 367:      */
 368:     public void paintIcon(Component c, Graphics g, int x, int y) 
 369:     {
 370:       Color savedColor = g.getColor();
 371:       g.setColor(MetalLookAndFeel.getBlack());
 372: 
 373:       // file 1 outline
 374:       g.drawLine(x + 2, y + 2, x + 5, y + 2);
 375:       g.drawLine(x + 6, y + 3, x + 6, y + 7);
 376:       g.drawLine(x + 2, y + 7, x + 6, y + 7);
 377:       g.drawLine(x + 2, y + 2, x + 2, y + 7);
 378:       
 379:       // file 2 outline
 380:       g.drawLine(x + 2, y + 10, x + 5, y + 10);
 381:       g.drawLine(x + 6, y + 11, x + 6, y + 15);
 382:       g.drawLine(x + 2, y + 15, x + 6, y + 15);
 383:       g.drawLine(x + 2, y + 10, x + 2, y + 15);
 384:       
 385:       // file 3 outline
 386:       g.drawLine(x + 10, y + 2, x + 13, y + 2);
 387:       g.drawLine(x + 14, y + 3, x + 14, y + 7);
 388:       g.drawLine(x + 10, y + 7, x + 14, y + 7);
 389:       g.drawLine(x + 10, y + 2, x + 10, y + 7);
 390:       
 391:       // file 4 outline
 392:       g.drawLine(x + 10, y + 10, x + 13, y + 10);
 393:       g.drawLine(x + 14, y + 11, x + 14, y + 15);
 394:       g.drawLine(x + 10, y + 15, x + 14, y + 15);
 395:       g.drawLine(x + 10, y + 10, x + 10, y + 15);
 396:       
 397:       g.drawLine(x + 8, y + 5, x + 8, y + 5);
 398:       g.drawLine(x + 8, y + 13, x + 8, y + 13);
 399:       g.drawLine(x + 16, y + 5, x + 16, y + 5);
 400:       g.drawLine(x + 16, y + 13, x + 16, y + 13);
 401:       
 402:       // fill files
 403:       g.setColor(MetalLookAndFeel.getPrimaryControl());
 404:       g.fillRect(x + 3, y + 3, 3, 4);
 405:       g.fillRect(x + 3, y + 11, 3, 4);
 406:       g.fillRect(x + 11, y + 3, 3, 4);
 407:       g.fillRect(x + 11, y + 11, 3, 4);
 408:       
 409:       // highlight files
 410:       g.setColor(MetalLookAndFeel.getPrimaryControlHighlight());
 411:       g.drawLine(x + 4, y + 4, x + 4, y + 5);
 412:       g.drawLine(x + 4, y + 12, x + 4, y + 13);
 413:       g.drawLine(x + 12, y + 4, x + 12, y + 5);
 414:       g.drawLine(x + 12, y + 12, x + 12, y + 13);
 415: 
 416:       g.setColor(savedColor);
 417:     }        
 418:   }
 419:     
 420:   /**
 421:    * An icon used for the "new folder" button on a {@link JFileChooser} under
 422:    * the {@link MetalLookAndFeel}.
 423:    * 
 424:    * @see MetalIconFactory#getFileChooserNewFolderIcon()
 425:    */
 426:   private static class FileChooserNewFolderIcon 
 427:     implements Icon, UIResource, Serializable
 428:   {
 429:     /** 
 430:      * Creates a new icon.
 431:      */
 432:     public FileChooserNewFolderIcon() 
 433:     {
 434:       // Nothing to do here.
 435:     }
 436:     
 437:     /**
 438:      * Returns the width of the icon, in pixels.
 439:      * 
 440:      * @return The width of the icon.
 441:      */
 442:     public int getIconWidth() 
 443:     {
 444:       return 18;
 445:     }
 446:     
 447:     /**
 448:      * Returns the height of the icon, in pixels.
 449:      * 
 450:      * @return The height of the icon.
 451:      */
 452:     public int getIconHeight() 
 453:     {
 454:       return 18;
 455:     }
 456:     
 457:     /**
 458:      * Paints the icon using colors from the {@link MetalLookAndFeel}.
 459:      * 
 460:      * @param c  the component (ignored).
 461:      * @param g  the graphics device.
 462:      * @param x  the x-coordinate for the top-left of the icon.
 463:      * @param y  the y-coordinate for the top-left of the icon.
 464:      */
 465:     public void paintIcon(Component c, Graphics g, int x, int y) 
 466:     {      
 467:       Color savedColor = g.getColor();
 468:       g.setColor(MetalLookAndFeel.getBlack());
 469:       
 470:       g.drawLine(x + 2, y + 5, x + 9, y + 5);
 471:       g.drawLine(x + 10, y + 6, x + 15, y + 6);
 472:       g.drawLine(x + 15, y + 5, x + 15, y + 14);
 473:       g.drawLine(x + 2, y + 14, x + 15, y + 14);
 474:       g.drawLine(x + 1, y + 6, x + 1, y + 14);
 475:       
 476:       g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
 477:       g.drawLine(x + 11, y + 3, x + 15, y + 3);
 478:       g.drawLine(x + 10, y + 4, x + 15, y + 4);
 479:       
 480:       g.setColor(MetalLookAndFeel.getPrimaryControl());
 481:       g.fillRect(x + 3, y + 7, 7, 7);
 482:       g.fillRect(x + 10, y + 8, 5, 6);
 483:       g.drawLine(x + 10, y + 5, x + 14, y + 5);
 484:       
 485:       g.setColor(MetalLookAndFeel.getPrimaryControlHighlight());
 486:       g.drawLine(x + 10, y + 7, x + 14, y + 7);
 487:       g.drawLine(x + 2, y + 6, x + 9, y + 6);
 488:       g.drawLine(x + 2, y + 6, x + 2, y + 13);
 489:       g.setColor(savedColor);
 490:     }        
 491:   }
 492: 
 493:   /**
 494:    * An icon used for the "up folder" button on a {@link JFileChooser} under
 495:    * the {@link MetalLookAndFeel}.
 496:    * 
 497:    * @see MetalIconFactory#getFileChooserNewFolderIcon()
 498:    */
 499:   private static class FileChooserUpFolderIcon extends FileChooserNewFolderIcon 
 500:   {
 501:     /**
 502:      * Creates a new icon.
 503:      */
 504:     public FileChooserUpFolderIcon() 
 505:     {
 506:       // Nothing to do here.
 507:     }
 508:     
 509:     /**
 510:      * Paints the icon using colors from the {@link MetalLookAndFeel}.
 511:      * 
 512:      * @param c  the component (ignored).
 513:      * @param g  the graphics device.
 514:      * @param x  the x-coordinate for the top-left of the icon.
 515:      * @param y  the y-coordinate for the top-left of the icon.
 516:      */
 517:     public void paintIcon(Component c, Graphics g, int x, int y) 
 518:     {
 519:       Color savedColor = g.getColor();
 520: 
 521:       // draw the folder
 522:       super.paintIcon(c, g, x, y);
 523:       
 524:       // now draw the up arrow
 525:       g.setColor(MetalLookAndFeel.getBlack());
 526:       g.drawLine(x + 8, y + 9, x + 8, y + 16);
 527:       int xx = x + 8;
 528:       for (int i = 0; i < 4; i++)
 529:         g.drawLine(xx - i, y + 9 + i, xx + i, y + 9 + i);
 530:       g.setColor(savedColor);
 531:     }        
 532:   }
 533: 
 534:   /**
 535:    * An icon representing a file (drawn as a piece of paper with the top-right
 536:    * corner turned down).
 537:    */
 538:   public static class FileIcon16 implements Icon, Serializable 
 539:   {
 540:     /**
 541:      * Returns the width of the icon, in pixels.
 542:      * 
 543:      * @return The width of the icon.
 544:      */
 545:     public int getIconWidth() 
 546:     {
 547:       return 16;
 548:     }
 549: 
 550:     /**
 551:      * Returns the height of the icon, in pixels.  The height returned is 
 552:      * <code>16</code> plus the value returned by 
 553:      * {@link #getAdditionalHeight()}.
 554:      * 
 555:      * @return The height of the icon.
 556:      */
 557:     public int getIconHeight() 
 558:     {
 559:       return 16 + getAdditionalHeight();
 560:     }
 561:     
 562:     /**
 563:      * Paints the icon at the location (x, y).
 564:      * 
 565:      * @param c  the component.
 566:      * @param g  the graphics context.
 567:      * @param x  the x coordinate.
 568:      * @param y  the y coordinate.
 569:      */
 570:     public void paintIcon(Component c, Graphics g, int x, int y) 
 571:     {
 572:       // TODO: pick up appropriate UI colors
 573:       g.setColor(Color.black);
 574:       g.drawLine(x, y, x + 9, y);            
 575:       g.drawLine(x, y + 1, x, y + 15);            
 576:       g.drawLine(x, y + 15, x + 12, y + 15);            
 577:       g.drawLine(x + 12, y + 15, x + 12, y + 6);            
 578:       g.drawLine(x + 12, y + 6, x + 9, y);           
 579: 
 580:       g.drawLine(x + 7, y + 2, x + 11, y + 6);
 581:       g.drawLine(x + 8, y + 1, x + 9, y + 1);
 582: 
 583:       g.setColor(new Color(204, 204, 255));
 584:       g.drawLine(x + 1, y + 1, x + 7, y + 1);            
 585:       g.drawLine(x + 1, y + 1, x + 1, y + 14);            
 586:       g.drawLine(x + 1, y + 14, x + 11, y + 14);            
 587:       g.drawLine(x + 11, y + 14, x + 11, y + 7);            
 588:       g.drawLine(x + 8, y + 2, x + 10, y + 4);
 589:     }
 590:     
 591:     /**
 592:      * Returns the additional height for the icon.  The 
 593:      * {@link #getIconHeight()} method adds this value to the icon height it
 594:      * returns.  Subclasses can override this method to adjust the icon height.
 595:      * 
 596:      * @return The additional height (<code>0</code> unless overridden).
 597:      */
 598:     public int getAdditionalHeight() 
 599:     {
 600:       return 0;
 601:     }
 602:         
 603:     /**
 604:      * Returns the shift (???).
 605:      * 
 606:      * @return The shift.
 607:      */
 608:     public int getShift() 
 609:     {
 610:       return 0;
 611:     }
 612:         
 613:   }
 614:     
 615:   /**
 616:    * An icon representing a folder.
 617:    */
 618:   public static class FolderIcon16 implements Icon, Serializable 
 619:   {
 620:     /**
 621:      * Returns the width of the icon, in pixels.
 622:      * 
 623:      * @return The width of the icon.
 624:      */
 625:     public int getIconWidth() 
 626:     {
 627:       return 16;
 628:     }
 629:     
 630:     /**
 631:      * Returns the height of the icon, in pixels.  The height returned is 
 632:      * <code>16</code> plus the value returned by 
 633:      * {@link #getAdditionalHeight()}.
 634:      * 
 635:      * @return The height of the icon.
 636:      */
 637:     public int getIconHeight() 
 638:     {
 639:       return 16 + getAdditionalHeight();
 640:     }
 641: 
 642:     /**
 643:      * Paints the icon at the location (x, y).
 644:      * 
 645:      * @param c  the component.
 646:      * @param g  the graphics device.
 647:      * @param x  the x coordinate.
 648:      * @param y  the y coordinate.
 649:      */
 650:     public void paintIcon(Component c, Graphics g, int x, int y) 
 651:     {
 652:       // TODO: pick up appropriate UI colors
 653:       g.setColor(Color.black);
 654:       g.drawLine(x, y + 3, x, y + 12);
 655:       g.drawLine(x, y + 12, x + 15, y + 12);
 656:       g.drawLine(x + 15, y + 12, x + 15, y + 2);
 657:       g.drawLine(x + 14, y + 3, x + 9, y + 3);
 658:       g.drawLine(x + 8, y + 2, x + 1, y + 2);
 659:       g.setColor(new Color(204, 204, 255));
 660:       g.fillRect(x + 2, y + 4, 7, 8);
 661:       g.fillRect(x + 9, y + 5, 6, 7);
 662:       g.setColor(new Color(102, 102, 153));
 663:       g.drawLine(x + 9, y + 2, x + 14, y + 2);
 664:       g.setColor(new Color(50, 50, 120));
 665:       g.drawLine(x + 9, y + 1, x + 15, y + 1);
 666:       g.drawLine(x + 10, y, x + 15, y);
 667:     }
 668:     
 669:     /**
 670:      * Returns the additional height for the icon.  The 
 671:      * {@link #getIconHeight()} method adds this value to the icon height it
 672:      * returns.  Subclasses can override this method to adjust the icon height.
 673:      * 
 674:      * @return The additional height (<code>0</code> unless overridden).
 675:      */
 676:     public int getAdditionalHeight() 
 677:     {
 678:       return 0;
 679:     }
 680:     
 681:     /**
 682:      * Returns the shift (???).
 683:      * 
 684:      * @return The shift.
 685:      */
 686:     public int getShift() 
 687:     {
 688:       return 0;
 689:     }
 690:         
 691:   }
 692: 
 693:   /**
 694:    * An icon used by the {@link MetalInternalFrameUI} class when the frame
 695:    * is displayed as a palette.
 696:    * 
 697:    * @since 1.3
 698:    */
 699:   public static class PaletteCloseIcon
 700:     implements Icon, Serializable, UIResource
 701:   {
 702:     /**
 703:      * Returns the width of the icon, in pixels.
 704:      * 
 705:      * @return The width of the icon.
 706:      */
 707:     public int getIconWidth() 
 708:     {
 709:       return 7;
 710:     }
 711:     
 712:     /**
 713:      * Returns the height of the icon, in pixels.
 714:      * 
 715:      * @return The height of the icon.
 716:      */
 717:     public int getIconHeight() 
 718:     {
 719:       return 7;
 720:     }
 721:     
 722:     /**
 723:      * Paints the icon using colors from the {@link MetalLookAndFeel}.
 724:      * 
 725:      * @param c  the component (ignored).
 726:      * @param g  the graphics device.
 727:      * @param x  the x-coordinate for the top-left of the icon.
 728:      * @param y  the y-coordinate for the top-left of the icon.
 729:      */
 730:     public void paintIcon(Component c, Graphics g, int x, int y) 
 731:     {
 732:       Color savedColor = g.getColor();
 733:       AbstractButton button = (AbstractButton) c;
 734:       if (button.getModel().isPressed())
 735:         g.setColor(MetalLookAndFeel.getBlack());
 736:       else
 737:         g.setColor(MetalLookAndFeel.getControlDarkShadow());
 738:       g.fillRect(x + 2, y + 2, 3, 3);
 739:       g.drawLine(x + 1, y, x + 1, y + 2);
 740:       g.drawLine(x, y + 1, x + 2, y + 1);
 741:       g.drawLine(x + 5, y, x + 5, y + 2);
 742:       g.drawLine(x + 4, y + 1, x + 6, y + 1);
 743:       g.drawLine(x + 1, y + 4, x + 1, y + 6);
 744:       g.drawLine(x, y + 5, x + 2, y + 5);
 745:       g.drawLine(x + 5, y + 4, x + 5, y + 6);
 746:       g.drawLine(x + 4, y + 5, x + 6, y + 5);
 747:       g.setColor(MetalLookAndFeel.getControlHighlight());
 748:       g.drawLine(x + 2, y + 6, x + 3, y + 5);
 749:       g.drawLine(x + 5, y + 3, x + 6, y + 2);
 750:       g.drawLine(x + 6, y + 6, x + 6, y + 6);
 751:       g.setColor(savedColor);
 752:     }        
 753:   }
 754:   
 755:   /**
 756:    * An {@link Icon} implementation for {@link JCheckBox}es in the
 757:    * Metal Look &amp; Feel.
 758:    *
 759:    * @author Roman Kennke (roman@kennke.org)
 760:    */
 761:   static class RadioButtonIcon implements Icon, UIResource, Serializable
 762:   {
 763: 
 764:     /**
 765:      * This is used as a mask when painting the gradient. See
 766:      * {@link MetalUtils#paintGradient(java.awt.Graphics, int, int, int, int,
 767:      *  float, float, java.awt.Color, java.awt.Color, java.awt.Color, int,
 768:      *  int[][])} for details.
 769:      */
 770:     private static int[][] gradientMask = new int[][] {{3, 7}, {1, 9}, {1, 9},
 771:                                                        {0, 10}, {0, 10}, {0, 10},
 772:                                                        {0, 10}, {1, 9}, {1, 9},
 773:                                                        {3, 7}};
 774: 
 775:     /**
 776:      * Returns the width of the icon in pixels.
 777:      *
 778:      * @return the width of the icon in pixels
 779:      */
 780:     public int getIconWidth()
 781:     {
 782:       return 13;
 783:     }
 784: 
 785:     /**
 786:      * Returns the height of the icon in pixels.
 787:      *
 788:      * @return the height of the icon in pixels
 789:      */
 790:     public int getIconHeight()
 791:     {
 792:       return 13;
 793:     }
 794: 
 795:     /**
 796:      * Paints the icon, taking into account whether or not the component is
 797:      * enabled, selected and/or armed.
 798:      *
 799:      * @param c the Component to draw on (must be an instance of 
 800:      *          {@link JRadioButton})
 801:      * @param g the Graphics context to draw with
 802:      * @param x the X position
 803:      * @param y the Y position
 804:      */
 805:     public void paintIcon(Component c, Graphics g, int x, int y) 
 806:     {
 807:       if (UIManager.get("RadioButton.gradient") != null)
 808:         MetalUtils.paintGradient(g, x + 2, y + 2, 8, 8,
 809:                               SwingConstants.VERTICAL, "RadioButton.gradient",
 810:                               gradientMask);
 811: 
 812:       Color savedColor = g.getColor();
 813:       JRadioButton b = (JRadioButton) c;
 814: 
 815:       // draw outer circle
 816:       if (b.isEnabled())
 817:         g.setColor(MetalLookAndFeel.getControlDarkShadow());
 818:       else
 819:         g.setColor(MetalLookAndFeel.getControlDisabled());
 820:       g.drawLine(x + 2, y + 1, x + 3, y + 1);
 821:       g.drawLine(x + 4, y, x + 7, y);
 822:       g.drawLine(x + 8, y + 1, x + 9, y + 1);
 823:       g.drawLine(x + 10, y + 2, x + 10, y + 3);
 824:       g.drawLine(x + 11, y + 4, x + 11, y + 7);
 825:       g.drawLine(x + 10, y + 8, x + 10, y + 9);
 826:       g.drawLine(x + 8, y + 10, x + 9, y + 10);
 827:       g.drawLine(x + 4, y + 11, x + 7, y + 11);
 828:       g.drawLine(x + 2, y + 10, x + 3, y + 10);
 829:       g.drawLine(x + 1, y + 9, x + 1, y + 8);
 830:       g.drawLine(x, y + 7, x, y + 4);
 831:       g.drawLine(x + 1, y + 2, x + 1, y + 3);
 832: 
 833:       if (b.getModel().isArmed())
 834:         {
 835:           g.setColor(MetalLookAndFeel.getControlShadow());
 836:           g.drawLine(x + 4, y + 1, x + 7, y + 1);
 837:           g.drawLine(x + 4, y + 10, x + 7, y + 10);
 838:           g.drawLine(x + 1, y + 4, x + 1, y + 7);
 839:           g.drawLine(x + 10, y + 4, x + 10, y + 7);
 840:           g.fillRect(x + 2, y + 2, 8, 8);
 841:         }
 842:       else 
 843:         {
 844:           // only draw inner highlight if not filled
 845:           if (b.isEnabled())
 846:             {
 847:               g.setColor(MetalLookAndFeel.getWhite());
 848:           
 849:               g.drawLine(x + 2, y + 8, x + 2, y + 9);
 850:               g.drawLine(x + 1, y + 4, x + 1, y + 7);
 851:               g.drawLine(x + 2, y + 2, x + 2, y + 3);
 852:               g.drawLine(x + 3, y + 2, x + 3, y + 2);
 853:               g.drawLine(x + 4, y + 1, x + 7, y + 1);
 854:               g.drawLine(x + 8, y + 2, x + 9, y + 2);
 855:             }
 856:         }
 857: 
 858:       // draw outer highlight
 859:       if (b.isEnabled())
 860:         {
 861:           g.setColor(MetalLookAndFeel.getWhite());
 862:           
 863:           // outer
 864:           g.drawLine(x + 10, y + 1, x + 10, y + 1);
 865:           g.drawLine(x + 11, y + 2, x + 11, y + 3);
 866:           g.drawLine(x + 12, y + 4, x + 12, y + 7);
 867:           g.drawLine(x + 11, y + 8, x + 11, y + 9);
 868:           g.drawLine(x + 10, y + 10, x + 10, y + 10);
 869:           g.drawLine(x + 8, y + 11, x + 9, y + 11);
 870:           g.drawLine(x + 4, y + 12, x + 7, y + 12);
 871:           g.drawLine(x + 2, y + 11, x + 3, y + 11);
 872:         }
 873:       
 874:       if (b.isSelected())
 875:         {
 876:           if (b.isEnabled())
 877:             g.setColor(MetalLookAndFeel.getBlack());
 878:           else
 879:             g.setColor(MetalLookAndFeel.getControlDisabled());
 880:           g.drawLine(x + 4, y + 3, x + 7, y + 3);
 881:           g.fillRect(x + 3, y + 4, 6, 4);
 882:           g.drawLine(x + 4, y + 8, x + 7, y + 8);
 883:         }
 884:       g.setColor(savedColor);
 885:     }        
 886:   }
 887: 
 888:   /**
 889:    * An icon displayed for {@link JRadioButtonMenuItem} components.
 890:    */
 891:   private static class RadioButtonMenuItemIcon 
 892:     implements Icon, UIResource, Serializable 
 893:   {
 894:     /**
 895:      * Creates a new icon instance.
 896:      */
 897:     public RadioButtonMenuItemIcon() 
 898:     {
 899:       // Nothing to do here.
 900:     }
 901: 
 902:     /**
 903:      * Returns the width of the icon, in pixels.
 904:      * 
 905:      * @return The width of the icon.
 906:      */
 907:     public int getIconWidth() 
 908:     {
 909:       return 10;
 910:     }
 911: 
 912:     /**
 913:      * Returns the height of the icon, in pixels.
 914:      * 
 915:      * @return The height of the icon.
 916:      */
 917:     public int getIconHeight()   
 918:     {
 919:       return 10;
 920:     }
 921: 
 922:     /**
 923:      * Paints the icon.
 924:      * 
 925:      * @param c  the component.
 926:      * @param g  the graphics device.
 927:      * @param x  the x-coordinate.
 928:      * @param y  the y-coordinate.
 929:      */
 930:     public void paintIcon(Component c, Graphics g, int x, int y) 
 931:     {
 932:       Color savedColor = g.getColor();
 933:       JRadioButtonMenuItem item = (JRadioButtonMenuItem) c;
 934:       g.setColor(MetalLookAndFeel.getBlack());
 935:       g.drawLine(x + 2, y, x + 6, y);
 936:       g.drawLine(x + 7, y + 1, x + 7, y + 1);
 937:       g.drawLine(x + 8, y + 2, x + 8, y + 6);
 938:       g.drawLine(x + 7, y + 7, x + 7, y + 7);
 939:       g.drawLine(x + 2, y + 8, x + 6, y + 8);
 940:       g.drawLine(x + 1, y + 7, x + 1, y + 7);
 941:       g.drawLine(x, y + 2, x, y + 6);
 942:       g.drawLine(x + 1, y + 1, x + 1, y + 1);
 943:       
 944:       if (item.isSelected())
 945:         {
 946:           g.drawLine(x + 3, y + 2, x + 5, y + 2);
 947:           g.fillRect(x + 2, y + 3, 5, 3);
 948:           g.drawLine(x + 3, y + 6, x + 5, y + 6);
 949:         }
 950: 
 951:       // highlight
 952:       g.setColor(MetalLookAndFeel.getControlHighlight());
 953:       g.drawLine(x + 3, y + 1, x + 6, y + 1);
 954:       g.drawLine(x + 8, y + 1, x + 8, y + 1);
 955:       g.drawLine(x + 9, y + 2, x + 9, y + 7);
 956:       g.drawLine(x + 8, y + 8, x + 8, y + 8);
 957:       g.drawLine(x + 2, y + 9, x + 7, y + 9);
 958:       g.drawLine(x + 1, y + 8, x + 1, y + 8);
 959:       g.drawLine(x + 1, y + 3, x + 1, y + 6);
 960:       g.drawLine(x + 2, y + 2, x + 2, y + 2);
 961:       g.setColor(savedColor);
 962:     }        
 963:   }
 964: 
 965:   /**
 966:    * The icon used to display the thumb control on a horizontally oriented
 967:    * {@link JSlider} component.
 968:    */
 969:   private static class HorizontalSliderThumbIcon 
 970:     implements Icon, UIResource, Serializable
 971:   {
 972: 
 973:     /**
 974:      * This mask is used to paint the gradient in the shape of the thumb.
 975:      */
 976:     int[][] gradientMask = new int[][] { {0, 12}, {0, 12}, {0, 12}, {0, 12},
 977:                                          {0, 12}, {0, 12}, {0, 12}, {1, 11},
 978:                                          {2, 10}, {3, 9}, {4, 8}, {5, 7},
 979:                                          {6, 6}};
 980: 
 981:     /**
 982:      * Creates a new instance.
 983:      */
 984:     public HorizontalSliderThumbIcon() 
 985:     {
 986:       // Nothing to do here.
 987:     }
 988:     
 989:     /**
 990:      * Returns the width of the icon, in pixels.
 991:      * 
 992:      * @return The width of the icon.
 993:      */
 994:     public int getIconWidth() 
 995:     {
 996:       return 15;
 997:     }
 998:     
 999:     /**
1000:      * Returns the height of the icon, in pixels.
1001:      * 
1002:      * @return The height of the icon.
1003:      */
1004:     public int getIconHeight() 
1005:     {
1006:       return 16;
1007:     }
1008:     
1009:     /**
1010:      * Paints the icon, taking into account whether or not the component has 
1011:      * the focus.
1012:      * 
1013:      * @param c  the component.
1014:      * @param g  the graphics device.
1015:      * @param x  the x-coordinate.
1016:      * @param y  the y-coordinate.
1017:      */
1018:     public void paintIcon(Component c, Graphics g, int x, int y) 
1019:     {
1020:       boolean enabled = false;
1021:       boolean focus = false;
1022:       if (c != null)
1023:         {
1024:           enabled = c.isEnabled();
1025:           focus = c.hasFocus();    
1026:         }
1027:       
1028:       // draw the outline
1029:       if (enabled) 
1030:         g.setColor(MetalLookAndFeel.getBlack());
1031:       else
1032:         g.setColor(MetalLookAndFeel.getControlDarkShadow());
1033:       g.drawLine(x + 1, y, x + 13, y);
1034:       g.drawLine(x + 14, y + 1, x + 14, y + 7);
1035:       g.drawLine(x + 14, y + 8, x + 7, y + 15);
1036:       g.drawLine(x + 6, y + 14, x, y + 8);
1037:       g.drawLine(x, y + 7, x, y + 1);
1038:       
1039:       // Fill the icon.
1040:       if (MetalLookAndFeel.getCurrentTheme() instanceof OceanTheme
1041:           && enabled)
1042:         {
1043:           String gradient;
1044:           if (focus)
1045:             gradient = "Slider.focusGradient";
1046:           else
1047:             gradient = "Slider.gradient";
1048:           MetalUtils.paintGradient(g, x + 1, y + 2, 12, 13,
1049:                                    SwingConstants.VERTICAL, gradient,
1050:                                    gradientMask);
1051:         }
1052:       else
1053:         {
1054:           if (focus)
1055:             g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
1056:           else
1057:             g.setColor(MetalLookAndFeel.getControl());
1058:           g.fillRect(x + 1, y + 2, 13, 7);
1059:           g.drawLine(x + 2, y + 9, x + 12, y + 9);
1060:           g.drawLine(x + 3, y + 10, x + 11, y + 10);
1061:           g.drawLine(x + 4, y + 11, x + 10, y + 11);
1062:           g.drawLine(x + 5, y + 12, x + 9, y + 12);
1063:           g.drawLine(x + 6, y + 13, x + 8, y + 13);
1064:           g.drawLine(x + 7, y + 14, x + 7, y + 14);
1065:         }
1066: 
1067:       // If the slider is enabled, draw dots and highlights.
1068:       if (c.isEnabled()
1069:           && !(MetalLookAndFeel.getCurrentTheme() instanceof OceanTheme))
1070:         {
1071:           if (focus)
1072:             g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
1073:           else
1074:             g.setColor(MetalLookAndFeel.getBlack());
1075:           g.drawLine(x + 3, y + 3, x + 3, y + 3);
1076:           g.drawLine(x + 7, y + 3, x + 7, y + 3);
1077:           g.drawLine(x + 11, y + 3, x + 11, y + 3);
1078: 
1079:           g.drawLine(x + 5, y + 5, x + 5, y + 5);
1080:           g.drawLine(x + 9, y + 5, x + 9, y + 5);
1081: 
1082:           g.drawLine(x + 3, y + 7, x + 3, y + 7);
1083:           g.drawLine(x + 7, y + 7, x + 7, y + 7);
1084:           g.drawLine(x + 11, y + 7, x + 11, y + 7);
1085: 
1086:           // Draw highlights
1087:           if (focus)
1088:             g.setColor(MetalLookAndFeel.getPrimaryControl());
1089:           else
1090:             g.setColor(MetalLookAndFeel.getWhite());
1091:           g.drawLine(x + 1, y + 1, x + 13, y + 1);
1092:           g.drawLine(x + 1, y + 2, x + 1, y + 8);
1093:           g.drawLine(x + 2, y + 2, x + 2, y + 2);
1094:           g.drawLine(x + 6, y + 2, x + 6, y + 2);
1095:           g.drawLine(x + 10, y + 2, x + 10, y + 2);
1096:           
1097:           g.drawLine(x + 4, y + 4, x + 4, y + 4);
1098:           g.drawLine(x + 8, y + 4, x + 8, y + 4);
1099: 
1100:           g.drawLine(x + 2, y + 6, x + 2, y + 6);
1101:           g.drawLine(x + 6, y + 6, x + 6, y + 6);
1102:           g.drawLine(x + 10, y + 6, x + 10, y + 6);
1103:         }
1104: 
1105:     }        
1106:   }
1107:   
1108:   /**
1109:    * An icon used for the 'close' button in the title frame of a 
1110:    * {@link JInternalFrame}.
1111:    */
1112:   private static class InternalFrameCloseIcon 
1113:     implements Icon, UIResource, Serializable
1114:   {
1115:     /** The icon size in pixels. */
1116:     private int size;
1117:     
1118:     /**
1119:      * Creates a new icon.
1120:      * 
1121:      * @param size  the icon size (width and height) in pixels.
1122:      */
1123:     public InternalFrameCloseIcon(int size) 
1124:     {
1125:       this.size = size;
1126:     }
1127:     
1128:     /**
1129:      * Returns the width of the icon, in pixels.
1130:      * 
1131:      * @return The width of the icon.
1132:      */
1133:     public int getIconWidth() 
1134:     {
1135:       return size;
1136:     }
1137:     
1138:     /**
1139:      * Returns the height of the icon, in pixels.
1140:      * 
1141:      * @return The height of the icon.
1142:      */
1143:     public int getIconHeight() 
1144:     {
1145:       return size;
1146:     }
1147:     
1148:     /**
1149:      * Paints the icon.
1150:      * 
1151:      * @param c  the component (an {@link JInternalFrame} is expected).
1152:      * @param g  the graphics device.
1153:      * @param x  the x-coordinate.
1154:      * @param y  the y-coordinate.
1155:      */
1156:     public void paintIcon(Component c, Graphics g, int x, int y) 
1157:     {
1158:       Color savedColor = g.getColor();
1159:       AbstractButton b = (AbstractButton) c;
1160:       
1161:       // fill the interior
1162:       if (b.getModel().isPressed())
1163:         // FIXME: also need to take into account whether the internal frame is
1164:         // selected
1165:         g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
1166:       else
1167:         g.setColor(MetalLookAndFeel.getPrimaryControl());
1168:       g.fillRect(x + 2, y + 2, 10, 10);
1169:       
1170:       // draw the outline box and the cross
1171:       if (b.getModel().isPressed())
1172:         g.setColor(MetalLookAndFeel.getBlack());
1173:       else
1174:         {
1175:           // FIXME: also need to take into account whether the internal frame is
1176:           // selected
1177:           boolean selected = true;
1178:           if (selected)
1179:             g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
1180:           else
1181:             g.setColor(MetalLookAndFeel.getControlDarkShadow());
1182:         }
1183:       g.drawLine(x + 1, y + 1, x + 13, y + 1);
1184:       g.drawLine(x + 1, y + 2, x + 1, y + 12);
1185:       g.drawLine(x + 1, y + 13, x + 13, y + 13);
1186:       g.drawLine(x + 13, y + 2, x + 13, y + 12);
1187:       g.drawLine(x + 2, y + 12, x + 2, y + 12);
1188:       g.drawLine(x + 12, y + 2, x + 12, y + 2);
1189:       
1190:       g.fillRect(x + 4, y + 4, 2, 2);
1191:       g.fillRect(x + 5, y + 5, 4, 4);
1192:       g.drawLine(x + 9, y + 4, x + 10, y + 4);
1193:       g.drawLine(x + 9, y + 4, x + 9, y + 5);
1194:       g.drawLine(x + 4, y + 9, x + 4, y + 10);
1195:       g.drawLine(x + 4, y + 9, x + 5, y + 9);
1196:       g.drawLine(x + 9, y + 8, x + 9, y + 10);
1197:       g.drawLine(x + 8, y + 9, x + 10, y + 9);
1198:       
1199:       g.setColor(MetalLookAndFeel.getBlack());
1200:       g.drawLine(x, y, x + 13, y);
1201:       g.drawLine(x, y + 1, x, y + 13);
1202:       g.drawLine(x + 3, y + 4, x + 4, y + 3);
1203:       g.drawLine(x + 3, y + 9, x + 5, y + 7);
1204:       g.drawLine(x + 7, y + 5, x + 9, y + 3);
1205:       
1206:       g.drawLine(x + 12, y + 3, x + 12, y + 11);
1207:       g.drawLine(x + 3, y + 12, x + 12, y + 12);
1208:       
1209:       g.setColor(MetalLookAndFeel.getWhite());
1210:       g.drawLine(x + 1, y + 14, x + 14, y + 14);
1211:       g.drawLine(x + 14, y + 1, x + 14, y + 14);
1212:       
1213:       if (!b.getModel().isPressed())
1214:         {
1215:           g.drawLine(x + 5, y + 10, x + 5, y + 10);
1216:           g.drawLine(x + 6, y + 9, x + 7, y + 9);
1217:           g.drawLine(x + 10, y + 5, x + 10, y + 5);
1218:           g.drawLine(x + 9, y + 6, x + 9, y + 7);
1219:           g.drawLine(x + 10, y + 10, x + 11, y + 10);
1220:           g.drawLine(x + 10, y + 11, x + 10, y + 11);
1221:         }
1222:       g.setColor(savedColor);
1223:     }        
1224:   }
1225: 
1226:   /**
1227:    * The icon displayed at the top-left corner of a {@link JInternalFrame}.
1228:    */
1229:   private static class InternalFrameDefaultMenuIcon
1230:     implements Icon, UIResource, Serializable 
1231:   {
1232:        
1233:     /**
1234:      * Creates a new instance.
1235:      */
1236:     public InternalFrameDefaultMenuIcon() 
1237:     {
1238:       // Nothing to do here.
1239:     }
1240:     
1241:     /**
1242:      * Returns the width of the icon, in pixels.
1243:      * 
1244:      * @return The width of the icon.
1245:      */
1246:     public int getIconWidth() 
1247:     {
1248:       return 16;
1249:     }
1250:     
1251:     /**
1252:      * Returns the height of the icon, in pixels.
1253:      * 
1254:      * @return The height of the icon.
1255:      */
1256:     public int getIconHeight() 
1257:     {
1258:       return 16;
1259:     }
1260:     
1261:     /**
1262:      * Paints the icon at the specified location.
1263:      * 
1264:      * @param c  the component.
1265:      * @param g  the graphics device.
1266:      * @param x  the x coordinate.
1267:      * @param y  the y coordinate.
1268:      */
1269:     public void paintIcon(Component c, Graphics g, int x, int y) 
1270:     {
1271:       g.setColor(new Color(102, 102, 153));
1272:       g.fillRect(x + 1, y, 14, 2);
1273:       g.fillRect(x, y + 1, 2, 14);
1274:       g.fillRect(x + 1, y + 14, 14, 2);
1275:       g.fillRect(x + 14, y + 1, 2, 14);
1276:       g.drawLine(x + 2, y + 5, x + 14, y + 5);
1277:       
1278:       g.setColor(new Color(204, 204, 255));
1279:       g.fillRect(x + 2, y + 2, 12, 3);
1280:       
1281:       g.setColor(new Color(102, 102, 153));
1282:       g.drawLine(x + 3, y + 3, x + 3, y + 3);
1283:       g.drawLine(x + 6, y + 3, x + 6, y + 3);
1284:       g.drawLine(x + 9, y + 3, x + 9, y + 3);
1285:       g.drawLine(x + 12, y + 3, x + 12, y + 3);
1286: 
1287:       g.setColor(Color.white);
1288:       g.fillRect(x + 2, y + 6, 12, 8);
1289:       g.drawLine(x + 2, y + 2, x + 2, y + 2);
1290:       g.drawLine(x + 5, y + 2, x + 5, y + 2);
1291:       g.drawLine(x + 8, y + 2, x + 8, y + 2);
1292:       g.drawLine(x + 11, y + 2, x + 11, y + 2);
1293:     }        
1294:   }
1295: 
1296:   /**
1297:    * An icon used in the title frame of a {@link JInternalFrame}.  When you 
1298:    * maximise an internal frame, this icon will replace the 'maximise' icon to
1299:    * provide a 'restore' option.
1300:    */
1301:   private static class InternalFrameAltMaximizeIcon
1302:     implements Icon, UIResource, Serializable 
1303:   {
1304:     /** The icon size in pixels. */
1305:     private int size;
1306:     
1307:     /**
1308:      * Creates a new icon.
1309:      * 
1310:      * @param size  the icon size in pixels.
1311:      */
1312:     public InternalFrameAltMaximizeIcon(int size) 
1313:     {
1314:       this.size = size;
1315:     }
1316:     
1317:     /**
1318:      * Returns the width of the icon, in pixels.
1319:      * 
1320:      * @return The width of the icon.
1321:      */
1322:     public int getIconWidth() 
1323:     {
1324:       return size;
1325:     }
1326:     
1327:     /**
1328:      * Returns the height of the icon, in pixels.
1329:      * 
1330:      * @return The height of the icon.
1331:      */
1332:     public int getIconHeight() 
1333:     {
1334:       return size;
1335:     }
1336:     
1337:     /**
1338:      * Paints the icon at the specified location.
1339:      * 
1340:      * @param c  the component.
1341:      * @param g  the graphics device.
1342:      * @param x  the x coordinate.
1343:      * @param y  the y coordinate.
1344:      */
1345:     public void paintIcon(Component c, Graphics g, int x, int y) 
1346:     {
1347:       Color savedColor = g.getColor();
1348: 
1349:       AbstractButton b = (AbstractButton) c;
1350: 
1351:       // fill the small box interior
1352:       if (b.getModel().isPressed())
1353:         g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
1354:       else
1355:         g.setColor(MetalLookAndFeel.getPrimaryControl());
1356:       g.fillRect(x + 2, y + 6, 7, 7);
1357:       
1358:       
1359:       if (b.getModel().isPressed())
1360:         g.setColor(MetalLookAndFeel.getBlack());
1361:       else
1362:         g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
1363:         
1364:       g.drawLine(x + 12, y + 1, x + 13, y + 1);
1365:       g.drawLine(x + 11, y + 2, x + 12, y + 2);
1366:       g.drawLine(x + 10, y + 3, x + 11, y + 3);
1367:       g.drawLine(x + 8, y + 2, x + 8, y + 3);
1368:       g.fillRect(x + 8, y + 4, 3, 3);
1369:       g.drawLine(x + 11, y + 6, x + 12, y + 6);
1370:       
1371:       g.drawLine(x + 1, y + 5, x + 5, y + 5);
1372:       g.drawLine(x + 1, y + 6, x + 1, y + 12);
1373:       g.drawLine(x + 9, y + 9, x + 9, y + 12);
1374:       g.drawLine(x + 1, y + 13, x + 9, y + 13);
1375:       
1376:       g.drawLine(x + 2, y + 12, x + 2, y + 12);
1377:       
1378:       g.setColor(MetalLookAndFeel.getBlack());
1379:       g.drawLine(x + 12, y, x + 9, y + 3);
1380:       g.drawLine(x + 7, y + 1, x + 8, y + 1);
1381:       g.drawLine(x + 7, y + 2, x + 7, y + 6);
1382:       g.drawLine(x + 11, y + 5, x + 12, y + 5);
1383:       g.drawLine(x, y + 4, x + 5, y + 4);
1384:       g.drawLine(x, y + 5, x, y + 13);
1385:       g.drawLine(x + 3, y + 12, x + 8, y + 12);
1386:       g.drawLine(x + 8, y + 8, x + 8, y + 11);
1387:       g.drawLine(x + 9, y + 8, x + 9, y + 8);
1388:       
1389:       g.setColor(MetalLookAndFeel.getWhite());
1390:       g.drawLine(x + 9, y + 2, x + 9, y + 2);
1391:       g.drawLine(x + 11, y + 4, x + 13, y + 2);
1392:       g.drawLine(x + 13, y + 6, x + 13, y + 6);
1393:       g.drawLine(x + 8, y + 7, x + 13, y + 7);
1394:       g.drawLine(x + 6, y + 5, x + 6, y + 5);
1395:       g.drawLine(x + 10, y + 8, x + 10, y + 13);
1396:       g.drawLine(x + 1, y + 14, x + 10, y + 14);
1397:       
1398:       if (!b.getModel().isPressed())
1399:         {
1400:           g.drawLine(x + 2, y + 6, x + 6, y + 6);
1401:           g.drawLine(x + 2, y + 6, x + 2, y + 11);
1402:         }
1403:       
1404:       g.setColor(savedColor);
1405:     }        
1406:   }
1407:   
1408:   /**
1409:    * An icon used for the 'maximize' button in the title frame of a 
1410:    * {@link JInternalFrame}.
1411:    */
1412:   private static class InternalFrameMaximizeIcon 
1413:     implements Icon, UIResource, Serializable
1414:   {
1415:     
1416:     /**
1417:      * Creates a new instance.
1418:      */
1419:     public InternalFrameMaximizeIcon() 
1420:     {
1421:       // Nothing to do here.
1422:     }
1423:     
1424:     /**
1425:      * Returns the width of the icon, in pixels.
1426:      * 
1427:      * @return The width of the icon.
1428:      */
1429:     public int getIconWidth() 
1430:     {
1431:       return 16;
1432:     }
1433:     
1434:     /**
1435:      * Returns the height of the icon, in pixels.
1436:      * 
1437:      * @return The height of the icon.
1438:      */
1439:     public int getIconHeight() 
1440:     {
1441:       return 16;
1442:     }
1443:     
1444:     /**
1445:      * Paints the icon at the specified location.
1446:      * 
1447:      * @param c  the component.
1448:      * @param g  the graphics device.
1449:      * @param x  the x coordinate.
1450:      * @param y  the y coordinate.
1451:      */
1452:     public void paintIcon(Component c, Graphics g, int x, int y) 
1453:     {
1454:       Color savedColor = g.getColor();
1455:       
1456:       AbstractButton b = (AbstractButton) c;
1457:       
1458:       // fill the interior
1459:       if (b.getModel().isPressed())
1460:         g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
1461:       else
1462:         g.setColor(MetalLookAndFeel.getPrimaryControl());
1463:       g.fillRect(x + 2, y + 6, 7, 7);
1464: 
1465:       if (b.getModel().isPressed())
1466:         g.setColor(MetalLookAndFeel.getBlack());
1467:       else
1468:         g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
1469:           
1470:       g.drawLine(x + 9, y + 1, x + 10, y + 1);
1471:       g.fillRect(x + 11, y + 1, 3, 3);
1472:       g.fillRect(x + 12, y + 4, 2, 2);
1473:       g.drawLine(x + 10, y + 3, x + 10, y + 3);
1474:       g.drawLine(x + 9, y + 4, x + 10, y + 4);
1475:       g.drawLine(x + 1, y + 5, x + 9, y + 5);
1476:       g.drawLine(x + 1, y + 6, x + 1, y + 12);
1477:       g.drawLine(x + 9, y + 6, x + 9, y + 12);
1478:       g.drawLine(x + 1, y + 13, x + 9, y + 13);
1479:       
1480:       // fill
1481:       g.drawLine(x + 7, y + 6, x + 8, y + 6);
1482:       g.drawLine(x + 6, y + 7, x + 8, y + 7);
1483:       g.drawLine(x + 5, y + 8, x + 6, y + 8);
1484:       g.drawLine(x + 4, y + 9, x + 5, y + 9);
1485:       g.drawLine(x + 3, y + 10, x + 4, y + 10);
1486:       g.drawLine(x + 2, y + 11, x + 3, y + 11);
1487:       g.drawLine(x + 2, y + 12, x + 4, y + 12);
1488:       g.drawLine(x + 8, y + 8, x + 8, y + 8);
1489:       
1490:       // draw black
1491:       g.setColor(MetalLookAndFeel.getBlack());
1492:       g.drawLine(x + 8, y, x + 13, y);
1493:       g.drawLine(x + 8, y + 1, x + 8, y + 1);
1494:       g.drawLine(x + 10, y + 2, x + 9, y + 3);
1495:       g.drawLine(x, y + 4, x + 8, y + 4);
1496:       g.drawLine(x, y + 5, x, y + 13);
1497:       
1498:       g.drawLine(x + 2, y + 10, x + 6, y + 6);
1499:       g.drawLine(x + 8, y + 9, x + 8, y + 11);
1500:       g.drawLine(x + 5, y + 12, x + 8, y + 12);
1501:       
1502:       // draw white
1503:       g.setColor(MetalLookAndFeel.getWhite());
1504:       if (!b.getModel().isPressed())
1505:         {
1506:           g.drawLine(x + 2, y + 6, x + 5, y + 6);
1507:           g.drawLine(x + 2, y + 7, x + 2, y + 9);
1508:           g.drawLine(x + 4, y + 11, x + 7, y + 8);
1509:         }
1510:       
1511:       g.drawLine(x + 1, y + 14, x + 10, y + 14);
1512:       g.drawLine(x + 10, y + 5, x + 10, y + 13);
1513:       
1514:       g.drawLine(x + 9, y + 2, x + 9, y + 2);
1515:       g.drawLine(x + 11, y + 4, x + 11, y + 5);
1516:       g.drawLine(x + 13, y + 6, x + 14, y + 6);
1517:       g.drawLine(x + 14, y + 1, x + 14, y + 5);
1518:       g.setColor(savedColor);
1519:     }        
1520:   }
1521: 
1522:   /**
1523:    * An icon used in the title frame of a {@link JInternalFrame}.
1524:    */
1525:   private static class InternalFrameMinimizeIcon 
1526:     implements Icon, UIResource, Serializable
1527:   {
1528:   
1529:     /**
1530:      * Creates a new instance.
1531:      */
1532:     public InternalFrameMinimizeIcon() 
1533:     {
1534:       // Nothing to do here.
1535:     }
1536:     
1537:     /**
1538:      * Returns the width of the icon, in pixels.
1539:      * 
1540:      * @return The width of the icon.
1541:      */
1542:     public int getIconWidth() 
1543:     {
1544:       return 16;
1545:     }
1546:     
1547:     /**
1548:      * Returns the height of the icon, in pixels.
1549:      * 
1550:      * @return The height of the icon.
1551:      */
1552:     public int getIconHeight() 
1553:     {
1554:       return 16;
1555:     }
1556:     
1557:     /**
1558:      * Paints the icon at the specified location.
1559:      * 
1560:      * @param c  the component.
1561:      * @param g  the graphics device.
1562:      * @param x  the x coordinate.
1563:      * @param y  the y coordinate.
1564:      */
1565:     public void paintIcon(Component c, Graphics g, int x, int y) 
1566:     {
1567:       Color savedColor = g.getColor();
1568:       
1569:       AbstractButton b = (AbstractButton) c;
1570:       
1571:       if (b.getModel().isPressed())
1572:         g.setColor(MetalLookAndFeel.getBlack());
1573:       else
1574:         // FIXME: here the color depends on whether or not the internal frame 
1575:         // is selected 
1576:         g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
1577:       
1578:       g.drawLine(x + 12, y + 1, x + 13, y + 1);
1579:       g.drawLine(x + 11, y + 2, x + 12, y + 2);
1580:       g.drawLine(x + 10, y + 3, x + 11, y + 3);
1581:       g.drawLine(x + 8, y + 2, x + 8, y + 3);
1582:       g.fillRect(x + 8, y + 4, 3, 3);
1583:       g.drawLine(x + 11, y + 6, x + 12, y + 6);
1584:       
1585:       g.drawLine(x + 1, y + 8, x + 6, y + 8);
1586:       g.drawLine(x + 1, y + 9, x + 1, y + 12);
1587:       g.drawLine(x + 6, y + 9, x + 6, y + 12);
1588:       g.drawLine(x + 1, y + 13, x + 6, y + 13);
1589:       
1590:       g.drawLine(x + 5, y + 9, x + 5, y + 9);
1591:       g.drawLine(x + 2, y + 12, x + 2, y + 12);
1592:       
1593:       g.setColor(MetalLookAndFeel.getBlack());
1594:       g.drawLine(x + 12, y, x + 9, y + 3);
1595:       g.drawLine(x + 7, y + 1, x + 8, y + 1);
1596:       g.drawLine(x + 7, y + 2, x + 7, y + 6);
1597:       g.drawLine(x, y + 7, x + 6, y + 7);
1598:       g.drawLine(x, y + 8, x, y + 13);
1599:       g.drawLine(x + 3, y + 12, x + 5, y + 12);
1600:       g.drawLine(x + 5, y + 10, x + 5, y + 11);
1601:       g.drawLine(x + 11, y + 5, x + 12, y + 5);
1602:       
1603:       g.setColor(MetalLookAndFeel.getWhite());
1604:       g.drawLine(x + 9, y + 2, x + 9, y + 2);
1605:       g.drawLine(x + 11, y + 4, x + 13, y + 2);
1606:       g.drawLine(x + 13, y + 6, x + 13, y + 6);
1607:       g.drawLine(x + 8, y + 7, x + 13, y + 7);
1608:       g.drawLine(x + 7, y + 9, x + 7, y + 13);
1609:       g.drawLine(x + 1, y + 14, x + 7, y + 14);
1610: 
1611:       if (b.getModel().isPressed())
1612:         {
1613:           g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
1614:           g.fillRect(x + 2, y + 9, 3, 3);
1615:         }
1616:       else
1617:         {
1618:           g.drawLine(x + 2, y + 9, x + 4, y + 9);
1619:           g.drawLine(x + 2, y + 10, x + 2, y + 11);
1620:         }
1621: 
1622:       g.setColor(savedColor);
1623:     }        
1624:   }
1625: 
1626:   /**
1627:    * The icon used to display the thumb control on a horizontally oriented
1628:    * {@link JSlider} component.
1629:    */
1630:   private static class VerticalSliderThumbIcon 
1631:     implements Icon, UIResource, Serializable
1632:   {
1633:     /**
1634:      * This mask is used to paint the gradient in the shape of the thumb.
1635:      */
1636:     int[][] gradientMask = new int[][] { {0, 12}, {0, 12}, {0, 12}, {0, 12},
1637:                                          {0, 12}, {0, 12}, {0, 12}, {1, 11},
1638:                                          {2, 10}, {3, 9}, {4, 8}, {5, 7},
1639:                                          {6, 6}};
1640: 
1641:     /**
1642:      * Creates a new instance.
1643:      */
1644:     public VerticalSliderThumbIcon() 
1645:     {
1646:       // Nothing to do here.
1647:     }
1648:     
1649:     /**
1650:      * Returns the width of the icon, in pixels.
1651:      * 
1652:      * @return The width of the icon.
1653:      */
1654:     public int getIconWidth() 
1655:     {
1656:       return 16;
1657:     }
1658:     
1659:     /**
1660:      * Returns the height of the icon, in pixels.
1661:      * 
1662:      * @return The height of the icon.
1663:      */
1664:     public int getIconHeight() 
1665:     {
1666:       return 15;
1667:     }
1668:     
1669:     /**
1670:      * Paints the icon taking into account whether the slider control has the
1671:      * focus or not.
1672:      * 
1673:      * @param c  the slider (must be a non-<code>null</code> instance of
1674:      *           {@link JSlider}.
1675:      * @param g  the graphics device.
1676:      * @param x  the x-coordinate.
1677:      * @param y  the y-coordinate.
1678:      */
1679:     public void paintIcon(Component c, Graphics g, int x, int y) 
1680:     {
1681:       boolean enabled = false;
1682:       boolean focus = false;
1683:       if (c != null)
1684:         {
1685:           enabled = c.isEnabled();
1686:           focus = c.hasFocus();    
1687:         }
1688:       
1689:       // draw the outline
1690:       if (enabled) 
1691:         g.setColor(MetalLookAndFeel.getBlack());
1692:       else
1693:         g.setColor(MetalLookAndFeel.getControlDarkShadow());
1694:       g.drawLine(x + 1, y, x + 7, y);
1695:       g.drawLine(x + 8, y, x + 15, y + 7);
1696:       g.drawLine(x + 14, y + 8, x + 8, y + 14);
1697:       g.drawLine(x + 8, y + 14, x + 1, y + 14);
1698:       g.drawLine(x, y + 13, x, y + 1);
1699:       
1700:       // Fill the icon.
1701:       if (MetalLookAndFeel.getCurrentTheme() instanceof OceanTheme
1702:           && enabled)
1703:         {
1704:           String gradient;
1705:           if (focus)
1706:             gradient = "Slider.focusGradient";
1707:           else
1708:             gradient = "Slider.gradient";
1709:           MetalUtils.paintGradient(g, x + 2, y + 1, 13, 12,
1710:                                    SwingConstants.HORIZONTAL, gradient,
1711:                                    gradientMask);
1712:         }
1713:       else
1714:         {
1715:           if (focus)
1716:             g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
1717:           else
1718:             g.setColor(MetalLookAndFeel.getControl());
1719:           g.fillRect(x + 2, y + 1, 7, 13);
1720:           g.drawLine(x + 9, y + 2, x + 9, y + 12);
1721:           g.drawLine(x + 10, y + 3, x + 10, y + 11);
1722:           g.drawLine(x + 11, y + 4, x + 11, y + 10);
1723:           g.drawLine(x + 12, y + 5, x + 12, y + 9);
1724:           g.drawLine(x + 13, y + 6, x + 13, y + 8);
1725:           g.drawLine(x + 14, y + 7, x + 14, y + 7);
1726:         }
1727: 
1728:       // if the slider is enabled, draw dots and highlights
1729:       if (enabled
1730:           && ! (MetalLookAndFeel.getCurrentTheme() instanceof OceanTheme))
1731:         {
1732:           if (focus)
1733:             g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
1734:           else
1735:             g.setColor(MetalLookAndFeel.getBlack());
1736:           g.drawLine(x + 3, y + 3, x + 3, y + 3);
1737:           g.drawLine(x + 3, y + 7, x + 3, y + 7);
1738:           g.drawLine(x + 3, y + 11, x + 3, y + 11);
1739: 
1740:           g.drawLine(x + 5, y + 5, x + 5, y + 5);
1741:           g.drawLine(x + 5, y + 9, x + 5, y + 9);
1742: 
1743:           g.drawLine(x + 7, y + 3, x + 7, y + 3);
1744:           g.drawLine(x + 7, y + 7, x + 7, y + 7);
1745:           g.drawLine(x + 7, y + 11, x + 7, y + 11);
1746: 
1747:           // draw highlights
1748:           if (focus)
1749:             g.setColor(MetalLookAndFeel.getPrimaryControl());
1750:           else
1751:             g.setColor(MetalLookAndFeel.getWhite());
1752:           g.drawLine(x + 1, y + 1, x + 8, y + 1);
1753:           g.drawLine(x + 1, y + 2, x + 1, y + 13);
1754:           g.drawLine(x + 2, y + 2, x + 2, y + 2);
1755:           g.drawLine(x + 2, y + 6, x + 2, y + 6);
1756:           g.drawLine(x + 2, y + 10, x + 2, y + 10);
1757: 
1758:           g.drawLine(x + 4, y + 4, x + 4, y + 4);
1759:           g.drawLine(x + 4, y + 8, x + 4, y + 8);
1760: 
1761:           g.drawLine(x + 6, y + 2, x + 6, y + 2);
1762:           g.drawLine(x + 6, y + 6, x + 6, y + 6);
1763:           g.drawLine(x + 6, y + 10, x + 6, y + 10);
1764:         
1765:         }
1766:     }        
1767:   }
1768:     
1769:   /**
1770:    * A tree control icon.  This icon can be in one of two states: expanded and
1771:    * collapsed.
1772:    */
1773:   public static class TreeControlIcon implements Icon, Serializable
1774:   {
1775:     
1776:     /** ???. */
1777:     protected boolean isLight;
1778:     
1779:     /** A flag that controls whether or not the icon is collapsed. */
1780:     private boolean collapsed;
1781:     
1782:     /**
1783:      * Creates a new icon.
1784:      * 
1785:      * @param isCollapsed  a flag that controls whether the icon is in the
1786:      *                     collapsed state or the expanded state.
1787:      */
1788:     public TreeControlIcon(boolean isCollapsed) 
1789:     {
1790:       collapsed = isCollapsed;
1791:     }
1792:     
1793:     /**
1794:      * Returns the width of the icon, in pixels.
1795:      * 
1796:      * @return The width of the icon.
1797:      */
1798:     public int getIconWidth() 
1799:     {
1800:       return 18;
1801:     }
1802:     /**
1803:      * Returns the height of the icon, in pixels.
1804:      * 
1805:      * @return The height of the icon.
1806:      */
1807:     public int getIconHeight() 
1808:     {
1809:       return 18;
1810:     }
1811:     
1812:     /**
1813:      * Paints the icon at the location (x, y).
1814:      * 
1815:      * @param c the component.
1816:      * @param g the graphics device.
1817:      * @param x the x coordinate.
1818:      * @param y the y coordinate.
1819:      */
1820:     public void paintIcon(Component c, Graphics g, int x, int y)
1821:     {
1822:       // TODO: pick up appropriate UI colors
1823:       Color dark = new Color(99, 130, 191);
1824:       Color light = new Color(163, 184, 204);
1825:       Color white = Color.white;
1826: 
1827:       x += 8;
1828:       y += 6;
1829: 
1830:       final int w = 6;
1831:       final int wHalf = (w >> 2);
1832:       g.setColor(light);
1833:       g.drawOval(x, y, w, w);
1834:       g.setColor(dark);
1835:       g.fillOval(x + 1, y + 1, w - 1, w - 1);
1836:       
1837:       if (collapsed)
1838:         g.fillRect(x + w, y + wHalf + 1, w, 2);
1839:       else
1840:         g.fillRect(x + wHalf + 1, y + w, 2, w);
1841:       
1842:       g.setColor(white);
1843:       g.fillRect(x + wHalf + 1, y + wHalf + 1, 2, 2);
1844: 
1845:     } 
1846:     
1847:     /**
1848:      * Simply calls {@link #paintIcon(Component, Graphics, int, int)}.
1849:      * 
1850:      * @param c  the component.
1851:      * @param g  the graphics device.
1852:      * @param x  the x coordinate.
1853:      * @param y  the y coordinate.
1854:      */
1855:     public void paintMe(Component c, Graphics g, int x, int y) 
1856:     {
1857:       paintIcon(c, g, x, y);  
1858:     }
1859:   }
1860:     
1861:   /**
1862:    * A tree folder icon.
1863:    */
1864:   public static class TreeFolderIcon extends FolderIcon16
1865:   {
1866:     /**
1867:      * Creates a new instance.
1868:      */
1869:     public TreeFolderIcon() 
1870:     {
1871:       // Nothing to do here.
1872:     }
1873:     
1874:     /**
1875:      * Returns the additional height for this icon, in this case <code>2</code>
1876:      * pixels.
1877:      * 
1878:      * @return <code>2</code>.
1879:      */
1880:     public int getAdditionalHeight() 
1881:     {
1882:       return 2;
1883:     }
1884:     
1885:     /**
1886:      * Returns the shift (???).
1887:      * 
1888:      * @return The shift.
1889:      */
1890:     public int getShift() 
1891:     {
1892:       return -1;
1893:     }
1894:   }
1895:     
1896:   /**
1897:    * A tree leaf icon.
1898:    */
1899:   public static class TreeLeafIcon extends FileIcon16
1900:   {
1901:     /**
1902:      * Creates a new instance.
1903:      */
1904:     public TreeLeafIcon() 
1905:     {
1906:       // Nothing to do here.
1907:     }
1908:     
1909:     /**
1910:      * Returns the additional height for this icon, in this case <code>4</code>
1911:      * pixels.
1912:      * 
1913:      * @return <code>4</code>.
1914:      */
1915:     public int getAdditionalHeight() 
1916:     {
1917:       return 4;
1918:     }
1919:     
1920:     /**
1921:      * Returns the shift (???).
1922:      * 
1923:      * @return The shift.
1924:      */
1925:     public int getShift() 
1926:     {
1927:       return 2;
1928:     }
1929:   }
1930: 
1931:   /**
1932:    * An icon representing a hard disk.
1933:    * 
1934:    * @see MetalIconFactory#getTreeHardDriveIcon()
1935:    */
1936:   private static class TreeHardDriveIcon 
1937:     implements Icon, UIResource, Serializable
1938:   {
1939: 
1940:     /**
1941:      * Creates a new icon instance.
1942:      */
1943:     public TreeHardDriveIcon() 
1944:     {
1945:       // Nothing to do here.
1946:     }
1947: 
1948:     /**
1949:      * Returns the width of the icon, in pixels.
1950:      * 
1951:      * @return <code>16</code>.
1952:      */
1953:     public int getIconWidth() 
1954:     { 
1955:       return 16;
1956:     }
1957: 
1958:     /**
1959:      * Returns the height of the icon, in pixels.
1960:      * 
1961:      * @return <code>16</code>.
1962:      */
1963:     public int getIconHeight()   
1964:     {
1965:       return 16;
1966:     }
1967: 
1968:     /**
1969:      * Paints the icon at the specified location, using colors from the 
1970:      * current theme.
1971:      * 
1972:      * @param c  the component (ignored).
1973:      * @param g  the graphics device.
1974:      * @param x  the x-coordinate for the top-left of the icon.
1975:      * @param y  the y-coordinate for the top-left of the icon.
1976:      */
1977:     public void paintIcon(Component c, Graphics g, int x, int y) 
1978:     {
1979:       Color saved = g.getColor();
1980:       g.setColor(MetalLookAndFeel.getBlack());
1981:       g.drawLine(x + 1, y + 4, x + 1, y + 5);
1982:       g.drawLine(x + 14, y + 4, x + 14, y + 5);
1983:       g.drawLine(x + 1, y + 7, x + 1, y + 8);
1984:       g.drawLine(x + 14, y + 7, x + 14, y + 8);
1985:       g.drawLine(x + 1, y + 10, x + 1, y + 11);
1986:       g.drawLine(x + 14, y + 10, x + 14, y + 11);
1987:       
1988:       g.drawLine(x + 2, y + 3, x + 3, y + 3);
1989:       g.drawLine(x + 12, y + 3, x + 13, y + 3);
1990:       g.drawLine(x + 2, y + 6, x + 3, y + 6);
1991:       g.drawLine(x + 12, y + 6, x + 13, y + 6);
1992:       g.drawLine(x + 2, y + 9, x + 3, y + 9);
1993:       g.drawLine(x + 12, y + 9, x + 13, y + 9);
1994:       g.drawLine(x + 2, y + 12, x + 3, y + 12);
1995:       g.drawLine(x + 12, y + 12, x + 13, y + 12);
1996:       
1997:       g.drawLine(x + 4, y + 2, x + 11, y + 2);
1998:       g.drawLine(x + 4, y + 7, x + 11, y + 7);
1999:       g.drawLine(x + 4, y + 10, x + 11, y + 10);
2000:       g.drawLine(x + 4, y + 13, x + 11, y + 13);
2001:       
2002:       g.setColor(MetalLookAndFeel.getWhite());
2003:       g.fillRect(x + 4, y + 3, 2, 2);
2004:       g.drawLine(x + 6, y + 4, x + 6, y + 4);
2005:       g.drawLine(x + 7, y + 3, x + 9, y + 3);
2006:       g.drawLine(x + 8, y + 4, x + 8, y + 4);
2007:       g.drawLine(x + 11, y + 3, x + 11, y + 3);
2008:       g.fillRect(x + 2, y + 4, 2, 2); 
2009:       g.fillRect(x + 2, y + 7, 2, 2); 
2010:       g.fillRect(x + 2, y + 10, 2, 2); 
2011:       g.drawLine(x + 4, y + 6, x + 4, y + 6);
2012:       g.drawLine(x + 4, y + 9, x + 4, y + 9);
2013:       g.drawLine(x + 4, y + 12, x + 4, y + 12);
2014:       
2015:       g.setColor(MetalLookAndFeel.getControlShadow());
2016:       g.drawLine(x + 13, y + 4, x + 13, y + 4);
2017:       g.drawLine(x + 12, y + 5, x + 13, y + 5);
2018:       g.drawLine(x + 13, y + 7, x + 13, y + 7);
2019:       g.drawLine(x + 12, y + 8, x + 13, y + 8);
2020:       g.drawLine(x + 13, y + 10, x + 13, y + 10);
2021:       g.drawLine(x + 12, y + 11, x + 13, y + 11);
2022:       
2023:       g.drawLine(x + 10, y + 5, x + 10, y + 5);
2024:       g.drawLine(x + 7, y + 6, x + 7, y + 6);
2025:       g.drawLine(x + 9, y + 6, x + 9, y + 6);
2026:       g.drawLine(x + 11, y + 6, x + 11, y + 6);
2027: 
2028:       g.drawLine(x + 10, y + 8, x + 10, y + 8);
2029:       g.drawLine(x + 7, y + 9, x + 7, y + 9);
2030:       g.drawLine(x + 9, y + 9, x + 9, y + 9);
2031:       g.drawLine(x + 11, y + 9, x + 11, y + 9);
2032: 
2033:       g.drawLine(x + 10, y + 11, x + 10, y + 11);
2034:       g.drawLine(x + 7, y + 12, x + 7, y + 12);
2035:       g.drawLine(x + 9, y + 12, x + 9, y + 12);
2036:       g.drawLine(x + 11, y + 12, x + 11, y + 12);
2037: 
2038:       g.setColor(saved);
2039:     }        
2040:   }  
2041:   
2042:   /**
2043:    * An icon representing a floppy disk.
2044:    * 
2045:    * @see MetalIconFactory#getTreeFloppyDriveIcon()
2046:    */
2047:   private static class TreeFloppyDriveIcon 
2048:     implements Icon, UIResource, Serializable
2049:   {
2050: 
2051:     /**
2052:      * Creates a new icon instance.
2053:      */
2054:     public TreeFloppyDriveIcon() 
2055:     {
2056:       // Nothing to do here.
2057:     }
2058: 
2059:     /**
2060:      * Returns the width of the icon, in pixels.
2061:      * 
2062:      * @return <code>16</code>.
2063:      */
2064:     public int getIconWidth() 
2065:     { 
2066:       return 16;
2067:     }
2068: 
2069:     /**
2070:      * Returns the height of the icon, in pixels.
2071:      * 
2072:      * @return <code>16</code>.
2073:      */
2074:     public int getIconHeight()   
2075:     {
2076:       return 16;
2077:     }
2078: 
2079:     /**
2080:      * Paints the icon at the specified location, using colors from the 
2081:      * current theme.
2082:      * 
2083:      * @param c  the component (ignored).
2084:      * @param g  the graphics device.
2085:      * @param x  the x-coordinate for the top-left of the icon.
2086:      * @param y  the y-coordinate for the top-left of the icon.
2087:      */
2088:     public void paintIcon(Component c, Graphics g, int x, int y) 
2089:     {
2090:       Color saved = g.getColor();
2091:       
2092:       g.setColor(MetalLookAndFeel.getBlack());
2093:       g.drawLine(x + 1, y + 1, x + 13, y + 1);
2094:       g.drawLine(x + 1, y + 1, x + 1, y + 14);
2095:       g.drawLine(x + 1, y + 14, x + 14, y + 14);
2096:       g.drawLine(x + 14, y + 2, x + 14, y + 14);
2097:       
2098:       g.setColor(MetalLookAndFeel.getPrimaryControl());
2099:       g.fillRect(x + 2, y + 2, 12, 12);
2100:       
2101:       g.setColor(MetalLookAndFeel.getControlShadow());
2102:       g.fillRect(x + 5, y + 2, 6, 5);
2103:       g.drawLine(x + 4, y + 8, x + 11, y + 8);
2104:       g.drawLine(x + 3, y + 9, x + 3, y + 13);
2105:       g.drawLine(x + 12, y + 9, x + 12, y + 13);
2106:       
2107:       g.setColor(MetalLookAndFeel.getWhite());
2108:       g.fillRect(x + 8, y + 3, 2, 3);
2109:       g.fillRect(x + 4, y + 9, 8, 5);
2110:       
2111:       g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
2112:       g.drawLine(x + 5, y + 10, x + 9, y + 10);
2113:       g.drawLine(x + 5, y + 12, x + 8, y + 12);
2114: 
2115:       g.setColor(saved);
2116:     }        
2117:   }  
2118: 
2119:   /**
2120:    * An icon representing a computer.
2121:    * 
2122:    * @see MetalIconFactory#getTreeComputerIcon()
2123:    */
2124:   private static class TreeComputerIcon 
2125:     implements Icon, UIResource, Serializable
2126:   {
2127: 
2128:     /**
2129:      * Creates a new icon instance.
2130:      */
2131:     public TreeComputerIcon() 
2132:     {
2133:       // Nothing to do here.
2134:     }
2135: 
2136:     /**
2137:      * Returns the width of the icon, in pixels.
2138:      * 
2139:      * @return <code>16</code>.
2140:      */
2141:     public int getIconWidth() 
2142:     { 
2143:       return 16;
2144:     }
2145: 
2146:     /**
2147:      * Returns the height of the icon, in pixels.
2148:      * 
2149:      * @return <code>16</code>.
2150:      */
2151:     public int getIconHeight()   
2152:     {
2153:       return 16;
2154:     }
2155: 
2156:     /**
2157:      * Paints the icon at the specified location, using colors from the 
2158:      * current theme.
2159:      * 
2160:      * @param c  the component (ignored).
2161:      * @param g  the graphics device.
2162:      * @param x  the x-coordinate for the top-left of the icon.
2163:      * @param y  the y-coordinate for the top-left of the icon.
2164:      */
2165:     public void paintIcon(Component c, Graphics g, int x, int y) 
2166:     {
2167:       Color saved = g.getColor();
2168:       
2169:       g.setColor(MetalLookAndFeel.getBlack());
2170:       g.drawLine(x + 3, y + 1, x + 12, y + 1);
2171:       g.drawLine(x + 2, y + 2, x + 2, y + 8);
2172:       g.drawLine(x + 13, y + 2, x + 13, y + 8);
2173:       g.drawLine(x + 3, y + 9, x + 3, y + 9);
2174:       g.drawLine(x + 12, y + 9, x + 12, y + 9);
2175:       g.drawRect(x + 1, y + 10, 13, 4);
2176:       g.drawLine(x + 5, y + 3, x + 10, y + 3);
2177:       g.drawLine(x + 5, y + 8, x + 10, y + 8);
2178:       g.drawLine(x + 4, y + 4, x + 4, y + 7);
2179:       g.drawLine(x + 11, y + 4, x + 11, y + 7);
2180: 
2181:       g.setColor(MetalLookAndFeel.getPrimaryControl());
2182:       g.fillRect(x + 5, y + 4, 6, 4);
2183:       
2184:       g.setColor(MetalLookAndFeel.getControlShadow());
2185:       g.drawLine(x + 6, y + 12, x + 8, y + 12);
2186:       g.drawLine(x + 10, y + 12, x + 12, y + 12);
2187:       g.setColor(saved);
2188:     }        
2189:   }  
2190:     
2191:   /** The icon returned by {@link #getCheckBoxIcon()}. */
2192:   private static Icon checkBoxIcon;
2193:   
2194:   /** The icon returned by {@link #getCheckBoxMenuItemIcon()}. */
2195:   private static Icon checkBoxMenuItemIcon;
2196:   
2197:   /** The icon returned by {@link #getFileChooserDetailViewIcon()}. */
2198:   private static Icon fileChooserDetailViewIcon;
2199: 
2200:   /** The icon returned by {@link #getFileChooserHomeFolderIcon()}. */
2201:   private static Icon fileChooserHomeFolderIcon;
2202: 
2203:   /** The icon returned by {@link #getFileChooserListViewIcon()}. */
2204:   private static Icon fileChooserListViewIcon;
2205: 
2206:   /** The icon returned by {@link #getFileChooserNewFolderIcon()}. */
2207:   private static Icon fileChooserNewFolderIcon;
2208: 
2209:   /** The icon returned by {@link #getFileChooserUpFolderIcon()}. */
2210:   private static Icon fileChooserUpFolderIcon;
2211: 
2212:   /** The cached RadioButtonIcon instance. */
2213:   private static RadioButtonIcon radioButtonIcon;
2214: 
2215:   /** The icon returned by {@link #getRadioButtonMenuItemIcon()}. */
2216:   private static Icon radioButtonMenuItemIcon;
2217: 
2218:   /** The icon returned by {@link #getInternalFrameDefaultMenuIcon()}. */
2219:   private static Icon internalFrameDefaultMenuIcon;
2220: 
2221:   /** The icon returned by {@link #getTreeComputerIcon()}. */
2222:   private static Icon treeComputerIcon;
2223:   
2224:   /** The icon instance returned by {@link #getTreeFloppyDriveIcon()}. */
2225:   private static Icon treeFloppyDriveIcon;
2226:   
2227:   /** The icon instance returned by {@link #getTreeHardDriveIcon()}. */
2228:   private static Icon treeHardDriveIcon;
2229:   
2230:   /** The icon instance returned by {@link #getHorizontalSliderThumbIcon()}. */
2231:   private static Icon horizontalSliderThumbIcon;
2232: 
2233:   /** The icon instance returned by {@link #getVerticalSliderThumbIcon()}. */
2234:   private static Icon verticalSliderThumbIcon;
2235:   
2236:   /**
2237:    * Creates a new instance.  All the methods are static, so creating an 
2238:    * instance isn't necessary.
2239:    */
2240:   public MetalIconFactory() 
2241:   {
2242:     // Nothing to do here.
2243:   }
2244: 
2245:   /**
2246:    * Returns an icon for use when rendering the {@link JCheckBox} component.
2247:    * 
2248:    * @return A check box icon.
2249:    * 
2250:    * @since 1.3
2251:    */
2252:   public static Icon getCheckBoxIcon() 
2253:   {
2254:     if (checkBoxIcon == null)
2255:       checkBoxIcon = new MetalCheckBoxIcon();
2256:     return checkBoxIcon;
2257:   }
2258:   
2259:   /**
2260:    * Returns an icon for use when rendering the {@link JCheckBoxMenuItem} 
2261:    * component.
2262:    * 
2263:    * @return An icon.
2264:    */
2265:   public static Icon getCheckBoxMenuItemIcon() 
2266:   {
2267:     if (checkBoxMenuItemIcon == null)
2268:       checkBoxMenuItemIcon = new CheckBoxMenuItemIcon();
2269:     return checkBoxMenuItemIcon;
2270:   }
2271: 
2272:   /**
2273:    * Returns an icon for use by the {@link JFileChooser} component.
2274:    * 
2275:    * @return An icon.
2276:    */
2277:   public static Icon getFileChooserDetailViewIcon() 
2278:   {
2279:     if (fileChooserDetailViewIcon == null)
2280:       fileChooserDetailViewIcon = new FileChooserDetailViewIcon();
2281:     return fileChooserDetailViewIcon;
2282:   }
2283:     
2284:   /**
2285:    * Returns an icon for use by the {@link JFileChooser} component.
2286:    * 
2287:    * @return An icon.
2288:    */
2289:   public static Icon getFileChooserHomeFolderIcon() 
2290:   {
2291:     if (fileChooserHomeFolderIcon == null)
2292:       fileChooserHomeFolderIcon = new FileChooserHomeFolderIcon();
2293:     return fileChooserHomeFolderIcon;        
2294:   }
2295:     
2296:   /**
2297:    * Returns an icon for use by the {@link JFileChooser} component.
2298:    * 
2299:    * @return An icon.
2300:    */
2301:   public static Icon getFileChooserListViewIcon() 
2302:   {
2303:     if (fileChooserListViewIcon == null)
2304:       fileChooserListViewIcon = new FileChooserListViewIcon();
2305:     return fileChooserListViewIcon;
2306:   }
2307:     
2308:   /**
2309:    * Returns an icon for use by the {@link JFileChooser} component.
2310:    * 
2311:    * @return An icon.
2312:    */
2313:   public static Icon getFileChooserNewFolderIcon() 
2314:   {
2315:     if (fileChooserNewFolderIcon == null)
2316:       fileChooserNewFolderIcon = new FileChooserNewFolderIcon();
2317:     return fileChooserNewFolderIcon;
2318:   }
2319:     
2320:   /**
2321:    * Returns an icon for use by the {@link JFileChooser} component.
2322:    * 
2323:    * @return An icon.
2324:    */
2325:   public static Icon getFileChooserUpFolderIcon() 
2326:   {
2327:     if (fileChooserUpFolderIcon == null)
2328:       fileChooserUpFolderIcon = new FileChooserUpFolderIcon();
2329:     return fileChooserUpFolderIcon;
2330:   }
2331: 
2332:   /**
2333:    * Returns an icon for RadioButtons in the Metal L&amp;F.
2334:    *
2335:    * @return an icon for RadioButtons in the Metal L&amp;F
2336:    */
2337:   public static Icon getRadioButtonIcon()
2338:   {
2339:     if (radioButtonIcon == null)
2340:       radioButtonIcon = new RadioButtonIcon();
2341:     return radioButtonIcon;
2342:   }
2343: 
2344:   /**
2345:    * Creates a new instance of the icon used in a {@link JRadioButtonMenuItem}.
2346:    * 
2347:    * @return A new icon instance.
2348:    */
2349:   public static Icon getRadioButtonMenuItemIcon() 
2350:   {
2351:     if (radioButtonMenuItemIcon == null)
2352:       radioButtonMenuItemIcon = new RadioButtonMenuItemIcon();
2353:     return radioButtonMenuItemIcon;
2354:   }
2355: 
2356:   /**
2357:    * Returns the icon used to display the thumb for a horizontally oriented
2358:    * {@link JSlider}.
2359:    * 
2360:    * @return The icon.
2361:    */
2362:   public static Icon getHorizontalSliderThumbIcon() 
2363:   {
2364:     if (horizontalSliderThumbIcon == null)
2365:       horizontalSliderThumbIcon = new HorizontalSliderThumbIcon();
2366:     return horizontalSliderThumbIcon;
2367:   }
2368:     
2369:   /**
2370:    * Creates a new icon used to represent the 'close' button in the title
2371:    * pane of a {@link JInternalFrame}.
2372:    * 
2373:    * @param size  the icon size.
2374:    * 
2375:    * @return A close icon.
2376:    */
2377:   public static Icon getInternalFrameCloseIcon(int size) 
2378:   {
2379:     return new InternalFrameCloseIcon(size);
2380:   }
2381: 
2382:   /**
2383:    * Creates a new icon for the menu in a {@link JInternalFrame}.  This is the
2384:    * icon displayed at the top left of the frame.
2385:    * 
2386:    * @return A menu icon.
2387:    */
2388:   public static Icon getInternalFrameDefaultMenuIcon() 
2389:   {
2390:     if (internalFrameDefaultMenuIcon == null)
2391:       internalFrameDefaultMenuIcon = new InternalFrameDefaultMenuIcon();
2392:     return internalFrameDefaultMenuIcon;
2393:   }
2394:   
2395:   /**
2396:    * Creates a new icon for the 'maximize' button in a {@link JInternalFrame}.
2397:    * 
2398:    * @param size  the icon size in pixels.
2399:    * 
2400:    * @return The icon.
2401:    * 
2402:    * @see #getInternalFrameAltMaximizeIcon(int)
2403:    */
2404:   public static Icon getInternalFrameMaximizeIcon(int size) 
2405:   {
2406:     return new InternalFrameMaximizeIcon();
2407:   }
2408:     
2409:   /**
2410:    * Returns the icon used for the minimize button in the frame title for a
2411:    * {@link JInternalFrame}.
2412:    * 
2413:    * @param size  the icon size in pixels (ignored by this implementation).
2414:    * 
2415:    * @return The icon.
2416:    */
2417:   public static Icon getInternalFrameMinimizeIcon(int size) 
2418:   {
2419:     return new InternalFrameMinimizeIcon();
2420:   }
2421: 
2422:   /**
2423:    * Creates a new icon for the 'restore' button in a {@link JInternalFrame}
2424:    * that has been maximised.
2425:    * 
2426:    * @param size  the icon size in pixels.
2427:    * 
2428:    * @return The icon.
2429:    * 
2430:    * @see #getInternalFrameMaximizeIcon(int)
2431:    */
2432:   public static Icon getInternalFrameAltMaximizeIcon(int size) 
2433:   {
2434:     return new InternalFrameAltMaximizeIcon(size);
2435:   }
2436:   
2437:   /**
2438:    * Returns the icon used to display the thumb for a vertically oriented
2439:    * {@link JSlider}.
2440:    * 
2441:    * @return The icon.
2442:    */
2443:   public static Icon getVerticalSliderThumbIcon() 
2444:   {
2445:     if (verticalSliderThumbIcon == null)
2446:       verticalSliderThumbIcon = new VerticalSliderThumbIcon();
2447:     return verticalSliderThumbIcon;
2448:   }
2449:     
2450:   /**
2451:    * Creates and returns a new tree folder icon.
2452:    * 
2453:    * @return A new tree folder icon.
2454:    */  
2455:   public static Icon getTreeFolderIcon() 
2456:   {
2457:     return new TreeFolderIcon();
2458:   }
2459:     
2460:   /**
2461:    * Creates and returns a new tree leaf icon.
2462:    * 
2463:    * @return A new tree leaf icon.
2464:    */
2465:   public static Icon getTreeLeafIcon() 
2466:   {
2467:     return new TreeLeafIcon();
2468:   }
2469:   
2470:   /**
2471:    * Creates and returns a tree control icon.
2472:    * 
2473:    * @param isCollapsed  a flag that controls whether the icon is in the 
2474:    *                     collapsed or expanded state.
2475:    * 
2476:    * @return A tree control icon.
2477:    */
2478:   public static Icon getTreeControlIcon(boolean isCollapsed) 
2479:   {
2480:     return new TreeControlIcon(isCollapsed);
2481:   }
2482: 
2483:   /**
2484:    * Returns a <code>16x16</code> icon representing a computer.
2485:    * 
2486:    * @return The icon.
2487:    */
2488:   public static Icon getTreeComputerIcon() 
2489:   {
2490:     if (treeComputerIcon == null)
2491:       treeComputerIcon = new TreeComputerIcon();
2492:     return treeComputerIcon;        
2493:   }
2494:     
2495:   /**
2496:    * Returns a <code>16x16</code> icon representing a floppy disk.
2497:    * 
2498:    * @return The icon.
2499:    */
2500:   public static Icon getTreeFloppyDriveIcon() 
2501:   {
2502:     if (treeFloppyDriveIcon == null)
2503:       treeFloppyDriveIcon = new TreeFloppyDriveIcon();
2504:     return treeFloppyDriveIcon;
2505:   }
2506:     
2507:   /**
2508:    * Returns a <code>16x16</code> icon representing a hard disk.
2509:    * 
2510:    * @return The icon.
2511:    */
2512:   public static Icon getTreeHardDriveIcon() 
2513:   {
2514:     if (treeHardDriveIcon == null)
2515:       treeHardDriveIcon = new TreeHardDriveIcon();
2516:     return treeHardDriveIcon;
2517:   }
2518: 
2519:   /**
2520:    * Returns a new instance of a 4 x 8 icon showing a small black triangle that
2521:    * points to the right.  This is displayed in menu items that have a 
2522:    * sub menu.
2523:    * 
2524:    * @return The icon.
2525:    */
2526:   public static Icon getMenuArrowIcon()
2527:   {
2528:     if (menuArrow == null)
2529:       menuArrow = new Icon()
2530:       {
2531:         public int getIconHeight()
2532:         {
2533:           return 8;
2534:         }
2535: 
2536:         public int getIconWidth()
2537:         {
2538:           return 4;
2539:         }
2540: 
2541:         public void paintIcon(Component c, Graphics g, int x, int y)
2542:         {
2543:           Color saved = g.getColor();
2544:           g.setColor(Color.BLACK);
2545:           for (int i = 0; i < 4; i++)
2546:             g.drawLine(x + i, y + i, x + i, y + 7 - i);
2547:           g.setColor(saved);
2548:         }
2549:       };
2550:     return menuArrow;
2551:   }
2552:   
2553:   /**
2554:    * Returns a new instance of a 4 x 8 icon showing a small black triangle that
2555:    * points to the right. This is displayed in menu items that have a sub menu.
2556:    * 
2557:    * @return The icon.
2558:    */
2559:   public static Icon getMenuItemArrowIcon()
2560:   {
2561:     if (menuItemArrow == null)
2562:       menuItemArrow = new Icon()
2563:       {
2564:         public int getIconHeight()
2565:         {
2566:           return 8;
2567:         }
2568: 
2569:         public int getIconWidth()
2570:         {
2571:           return 4;
2572:         }
2573: 
2574:         public void paintIcon(Component c, Graphics g, int x, int y)
2575:         {
2576:           Color saved = g.getColor();
2577:           g.setColor(Color.BLACK);
2578:           for (int i = 0; i < 4; i++)
2579:             g.drawLine(x + i, y + i, x + i, y + 7 - i);
2580:           g.setColor(saved);
2581:         }
2582:       };
2583:     return menuItemArrow;
2584:   }
2585:   
2586:   /**
2587:    * Returns a new instance of a 13 x 13 icon showing a small black check mark.
2588:    * 
2589:    * @return The icon.
2590:    */
2591:   public static Icon getMenuItemCheckIcon()
2592:   {
2593:     return new Icon()
2594:     {
2595:       public int getIconHeight()
2596:       {
2597:         return 13;
2598:       }
2599: 
2600:       public int getIconWidth()
2601:       {
2602:         return 13;
2603:       }
2604: 
2605:       public void paintIcon(Component c, Graphics g, int x, int y)
2606:       {
2607:         Color saved = g.getColor();
2608:         g.setColor(Color.BLACK);
2609:         g.drawLine(3 + x, 5 + y, 3 + x, 9 + y);
2610:         g.drawLine(4 + x, 5 + y, 4 + x, 9 + y);
2611:         g.drawLine(5 + x, 7 + y, 9 + x, 3 + y);
2612:         g.drawLine(5 + x, 8 + y, 9 + x, 4 + y);
2613:         g.setColor(saved);
2614:       }
2615:     };
2616:   }
2617: }