1 /*
   2  * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.swing.plaf.metal;
  27 
  28 import javax.swing.*;
  29 import javax.swing.plaf.UIResource;
  30 import java.awt.*;
  31 import java.awt.image.BufferedImage;
  32 import java.io.Serializable;
  33 import java.util.Enumeration;
  34 import java.util.Vector;
  35 import sun.swing.CachedPainter;
  36 
  37 /**
  38  * Factory object that vends <code>Icon</code>s for
  39  * the Java&trade; look and feel (Metal).
  40  * These icons are used extensively in Metal via the defaults mechanism.
  41  * While other look and feels often use GIFs for icons, creating icons
  42  * in code facilitates switching to other themes.
  43  *
  44  * <p>
  45  * Each method in this class returns
  46  * either an <code>Icon</code> or <code>null</code>,
  47  * where <code>null</code> implies that there is no default icon.
  48  *
  49  * <p>
  50  * <strong>Warning:</strong>
  51  * Serialized objects of this class will not be compatible with
  52  * future Swing releases. The current serialization support is
  53  * appropriate for short term storage or RMI between applications running
  54  * the same version of Swing.  As of 1.4, support for long term storage
  55  * of all JavaBeans&trade;
  56  * has been added to the <code>java.beans</code> package.
  57  * Please see {@link java.beans.XMLEncoder}.
  58  *
  59  * @author Michael C. Albers
  60  */
  61 @SuppressWarnings("serial") // Same-version serialization only
  62 public class MetalIconFactory implements Serializable {
  63 
  64     // List of code-drawn Icons
  65     private static Icon fileChooserDetailViewIcon;
  66     private static Icon fileChooserHomeFolderIcon;
  67     private static Icon fileChooserListViewIcon;
  68     private static Icon fileChooserNewFolderIcon;
  69     private static Icon fileChooserUpFolderIcon;
  70     private static Icon internalFrameAltMaximizeIcon;
  71     private static Icon internalFrameCloseIcon;
  72     private static Icon internalFrameDefaultMenuIcon;
  73     private static Icon internalFrameMaximizeIcon;
  74     private static Icon internalFrameMinimizeIcon;
  75     private static Icon radioButtonIcon;
  76     private static Icon treeComputerIcon;
  77     private static Icon treeFloppyDriveIcon;
  78     private static Icon treeHardDriveIcon;
  79 
  80 
  81     private static Icon menuArrowIcon;
  82     private static Icon menuItemArrowIcon;
  83     private static Icon checkBoxMenuItemIcon;
  84     private static Icon radioButtonMenuItemIcon;
  85     private static Icon checkBoxIcon;
  86 
  87 
  88     // Ocean icons
  89     private static Icon oceanHorizontalSliderThumb;
  90     private static Icon oceanVerticalSliderThumb;
  91 
  92     // Constants
  93     /**
  94      * {@code DARK} is used for the property {@code Tree.expandedIcon}.
  95      */
  96     public static final boolean DARK = false;
  97 
  98     /**
  99      * {@code LIGHT} is used for the property {@code Tree.collapsedIcon}.
 100      */
 101     public static final boolean LIGHT = true;
 102 
 103     // Accessor functions for Icons. Does the caching work.
 104     /**
 105      * Returns the instance of {@code FileChooserDetailViewIcon}.
 106      *
 107      * @return the instance of {@code FileChooserDetailViewIcon}
 108      */
 109     public static Icon getFileChooserDetailViewIcon() {
 110         if (fileChooserDetailViewIcon == null) {
 111             fileChooserDetailViewIcon = new FileChooserDetailViewIcon();
 112         }
 113         return fileChooserDetailViewIcon;
 114     }
 115 
 116     /**
 117      * Returns the instance of {@code FileChooserHomeFolderIcon}.
 118      *
 119      * @return the instance of {@code FileChooserHomeFolderIcon}
 120      */
 121     public static Icon getFileChooserHomeFolderIcon() {
 122         if (fileChooserHomeFolderIcon == null) {
 123             fileChooserHomeFolderIcon = new FileChooserHomeFolderIcon();
 124         }
 125         return fileChooserHomeFolderIcon;
 126     }
 127 
 128     /**
 129      * Returns the instance of {@code FileChooserListViewIcon}.
 130      *
 131      * @return the instance of {@code FileChooserListViewIcon}
 132      */
 133     public static Icon getFileChooserListViewIcon() {
 134         if (fileChooserListViewIcon == null) {
 135             fileChooserListViewIcon = new FileChooserListViewIcon();
 136         }
 137         return fileChooserListViewIcon;
 138     }
 139 
 140     /**
 141      * Returns the instance of {@code FileChooserNewFolderIcon}.
 142      *
 143      * @return the instance of {@code FileChooserNewFolderIcon}
 144      */
 145     public static Icon getFileChooserNewFolderIcon() {
 146         if (fileChooserNewFolderIcon == null) {
 147             fileChooserNewFolderIcon = new FileChooserNewFolderIcon();
 148         }
 149         return fileChooserNewFolderIcon;
 150     }
 151 
 152     /**
 153      * Returns the instance of {@code FileChooserUpFolderIcon}.
 154      *
 155      * @return the instance of {@code FileChooserUpFolderIcon}
 156      */
 157     public static Icon getFileChooserUpFolderIcon() {
 158         if (fileChooserUpFolderIcon == null) {
 159             fileChooserUpFolderIcon = new FileChooserUpFolderIcon();
 160         }
 161         return fileChooserUpFolderIcon;
 162     }
 163 
 164     /**
 165      * Constructs a new instance of {@code InternalFrameAltMaximizeIcon}.
 166      *
 167      * @param size the size of the icon
 168      * @return a new instance of {@code InternalFrameAltMaximizeIcon}
 169      */
 170     public static Icon getInternalFrameAltMaximizeIcon(int size) {
 171         return new InternalFrameAltMaximizeIcon(size);
 172     }
 173 
 174     /**
 175      * Constructs a new instance of {@code InternalFrameCloseIcon}.
 176      *
 177      * @param size the size of the icon
 178      * @return a new instance of {@code InternalFrameCloseIcon}
 179      */
 180     public static Icon getInternalFrameCloseIcon(int size) {
 181         return new InternalFrameCloseIcon(size);
 182     }
 183 
 184     /**
 185      * Returns the instance of {@code InternalFrameDefaultMenuIcon}.
 186      *
 187      * @return the instance of {@code InternalFrameDefaultMenuIcon}
 188      */
 189     public static Icon getInternalFrameDefaultMenuIcon() {
 190         if (internalFrameDefaultMenuIcon == null) {
 191             internalFrameDefaultMenuIcon = new InternalFrameDefaultMenuIcon();
 192         }
 193         return internalFrameDefaultMenuIcon;
 194     }
 195 
 196     /**
 197      * Constructs a new instance of {@code InternalFrameMaximizeIcon}.
 198      *
 199      * @param size the size of the icon
 200      * @return a new instance of {@code InternalFrameMaximizeIcon}
 201      */
 202     public static Icon getInternalFrameMaximizeIcon(int size) {
 203         return new InternalFrameMaximizeIcon(size);
 204     }
 205 
 206     /**
 207      * Constructs a new instance of {@code InternalFrameMinimizeIcon}.
 208      *
 209      * @param size the size of the icon
 210      * @return a new instance of {@code InternalFrameMinimizeIcon}
 211      */
 212     public static Icon getInternalFrameMinimizeIcon(int size) {
 213         return new InternalFrameMinimizeIcon(size);
 214     }
 215 
 216     /**
 217      * Returns the instance of {@code RadioButtonIcon}.
 218      *
 219      * @return the instance of {@code RadioButtonIcon}
 220      */
 221     public static Icon getRadioButtonIcon() {
 222         if (radioButtonIcon == null) {
 223             radioButtonIcon = new RadioButtonIcon();
 224         }
 225         return radioButtonIcon;
 226     }
 227 
 228     /**
 229      * Returns a checkbox icon.
 230      *
 231      * @return a checkbox icon
 232      * @since 1.3
 233      */
 234     public static Icon getCheckBoxIcon() {
 235         if (checkBoxIcon == null) {
 236             checkBoxIcon = new CheckBoxIcon();
 237         }
 238         return checkBoxIcon;
 239     }
 240 
 241     /**
 242      * Returns the instance of {@code TreeComputerIcon}.
 243      *
 244      * @return the instance of {@code TreeComputerIcon}
 245      */
 246     public static Icon getTreeComputerIcon() {
 247         if ( treeComputerIcon == null ) {
 248             treeComputerIcon = new TreeComputerIcon();
 249         }
 250         return treeComputerIcon;
 251     }
 252 
 253     /**
 254      * Returns the instance of {@code TreeFloppyDriveIcon}.
 255      *
 256      * @return the instance of {@code TreeFloppyDriveIcon}
 257      */
 258     public static Icon getTreeFloppyDriveIcon() {
 259         if ( treeFloppyDriveIcon == null ) {
 260             treeFloppyDriveIcon = new TreeFloppyDriveIcon();
 261         }
 262         return treeFloppyDriveIcon;
 263     }
 264 
 265     /**
 266      * Constructs a new instance of {@code TreeFolderIcon}.
 267      *
 268      * @return a new instance of {@code TreeFolderIcon}
 269      */
 270     public static Icon getTreeFolderIcon() {
 271         return new TreeFolderIcon();
 272     }
 273 
 274     /**
 275      * Returns the instance of {@code TreeHardDriveIcon}.
 276      *
 277      * @return the instance of {@code TreeHardDriveIcon}
 278      */
 279     public static Icon getTreeHardDriveIcon() {
 280         if ( treeHardDriveIcon == null ) {
 281             treeHardDriveIcon = new TreeHardDriveIcon();
 282         }
 283         return treeHardDriveIcon;
 284     }
 285 
 286     /**
 287      * Constructs a new instance of {@code TreeLeafIcon}.
 288      *
 289      * @return a new instance of {@code TreeLeafIcon}
 290      */
 291     public static Icon getTreeLeafIcon() {
 292         return new TreeLeafIcon();
 293     }
 294 
 295     /**
 296      * Constructs a new instance of {@code TreeControlIcon}.
 297      *
 298      * @param isCollapsed if {@code true} the icon is collapsed
 299      * @return a new instance of {@code TreeControlIcon}
 300      */
 301     public static Icon getTreeControlIcon( boolean isCollapsed ) {
 302             return new TreeControlIcon( isCollapsed );
 303     }
 304 
 305     /**
 306      * Returns an icon to be used by {@code JMenu}.
 307      *
 308      * @return an icon to be used by {@code JMenu}
 309      */
 310     public static Icon getMenuArrowIcon() {
 311         if (menuArrowIcon == null) {
 312             menuArrowIcon = new MenuArrowIcon();
 313         }
 314         return menuArrowIcon;
 315     }
 316 
 317     /**
 318      * Returns an icon to be used by <code>JCheckBoxMenuItem</code>.
 319      *
 320      * @return the default icon for check box menu items,
 321      *         or <code>null</code> if no default exists
 322      */
 323     public static Icon getMenuItemCheckIcon() {
 324         return null;
 325     }
 326 
 327     /**
 328      * Returns an icon to be used by {@code JMenuItem}.
 329      *
 330      * @return an icon to be used by {@code JMenuItem}
 331      */
 332     public static Icon getMenuItemArrowIcon() {
 333         if (menuItemArrowIcon == null) {
 334             menuItemArrowIcon = new MenuItemArrowIcon();
 335         }
 336         return menuItemArrowIcon;
 337     }
 338 
 339     /**
 340      * Returns an icon to be used by {@code JCheckBoxMenuItem}.
 341      *
 342      * @return an icon to be used by {@code JCheckBoxMenuItem}
 343      */
 344     public static Icon getCheckBoxMenuItemIcon() {
 345         if (checkBoxMenuItemIcon == null) {
 346             checkBoxMenuItemIcon = new CheckBoxMenuItemIcon();
 347         }
 348         return checkBoxMenuItemIcon;
 349     }
 350 
 351     /**
 352      * Returns an icon to be used by {@code JRadioButtonMenuItem}.
 353      *
 354      * @return an icon to be used by {@code JRadioButtonMenuItem}
 355      */
 356     public static Icon getRadioButtonMenuItemIcon() {
 357         if (radioButtonMenuItemIcon == null) {
 358             radioButtonMenuItemIcon = new RadioButtonMenuItemIcon();
 359         }
 360         return radioButtonMenuItemIcon;
 361     }
 362 
 363     /**
 364      * Returns a thumb icon to be used by horizontal slider.
 365      *
 366      * @return a thumb icon to be used by horizontal slider
 367      */
 368     public static Icon getHorizontalSliderThumbIcon() {
 369         if (MetalLookAndFeel.usingOcean()) {
 370             if (oceanHorizontalSliderThumb == null) {
 371                 oceanHorizontalSliderThumb =
 372                                new OceanHorizontalSliderThumbIcon();
 373             }
 374             return oceanHorizontalSliderThumb;
 375         }
 376       // don't cache these, bumps don't get updated otherwise
 377         return new HorizontalSliderThumbIcon();
 378     }
 379 
 380     /**
 381      * Returns a thumb icon to be used by vertical slider.
 382      *
 383      * @return a thumb icon to be used by vertical slider
 384      */
 385     public static Icon getVerticalSliderThumbIcon() {
 386         if (MetalLookAndFeel.usingOcean()) {
 387             if (oceanVerticalSliderThumb == null) {
 388                 oceanVerticalSliderThumb = new OceanVerticalSliderThumbIcon();
 389             }
 390             return oceanVerticalSliderThumb;
 391         }
 392         // don't cache these, bumps don't get updated otherwise
 393         return new VerticalSliderThumbIcon();
 394     }
 395 
 396     // File Chooser Detail View code
 397     private static class FileChooserDetailViewIcon implements Icon, UIResource, Serializable {
 398         public void paintIcon(Component c, Graphics g, int x, int y) {
 399             g.translate(x, y);
 400 
 401             // Draw outside edge of each of the documents
 402             g.setColor(MetalLookAndFeel.getPrimaryControlInfo());
 403             //     top
 404             g.drawLine(2,2, 5,2); // top
 405             g.drawLine(2,3, 2,7); // left
 406             g.drawLine(3,7, 6,7); // bottom
 407             g.drawLine(6,6, 6,3); // right
 408             //     bottom
 409             g.drawLine(2,10, 5,10); // top
 410             g.drawLine(2,11, 2,15); // left
 411             g.drawLine(3,15, 6,15); // bottom
 412             g.drawLine(6,14, 6,11); // right
 413 
 414             // Draw little dots next to documents
 415             //     Same color as outside edge
 416             g.drawLine(8,5, 15,5);     // top
 417             g.drawLine(8,13, 15,13);   // bottom
 418 
 419             // Draw inner highlight on documents
 420             g.setColor(MetalLookAndFeel.getPrimaryControl());
 421             g.drawRect(3,3, 2,3);   // top
 422             g.drawRect(3,11, 2,3);  // bottom
 423 
 424             // Draw inner inner highlight on documents
 425             g.setColor(MetalLookAndFeel.getPrimaryControlHighlight());
 426             g.drawLine(4,4, 4,5);     // top
 427             g.drawLine(4,12, 4,13);   // bottom
 428 
 429             g.translate(-x, -y);
 430         }
 431 
 432         public int getIconWidth() {
 433             return 18;
 434         }
 435 
 436         public int getIconHeight() {
 437             return 18;
 438         }
 439     }  // End class FileChooserDetailViewIcon
 440 
 441     // File Chooser Home Folder code
 442     private static class FileChooserHomeFolderIcon implements Icon, UIResource, Serializable {
 443         public void paintIcon(Component c, Graphics g, int x, int y) {
 444             g.translate(x, y);
 445 
 446             // Draw outside edge of house
 447             g.setColor(MetalLookAndFeel.getPrimaryControlInfo());
 448             g.drawLine(8,1, 1,8);  // left edge of roof
 449             g.drawLine(8,1, 15,8); // right edge of roof
 450             g.drawLine(11,2, 11,3); // left edge of chimney
 451             g.drawLine(12,2, 12,4); // right edge of chimney
 452             g.drawLine(3,7, 3,15); // left edge of house
 453             g.drawLine(13,7, 13,15); // right edge of house
 454             g.drawLine(4,15, 12,15); // bottom edge of house
 455             // Draw door frame
 456             //     same color as edge of house
 457             g.drawLine( 6,9,  6,14); // left
 458             g.drawLine(10,9, 10,14); // right
 459             g.drawLine( 7,9,  9, 9); // top
 460 
 461             // Draw roof body
 462             g.setColor(MetalLookAndFeel.getControlDarkShadow());
 463             g.fillRect(8,2, 1,1); //top toward bottom
 464             g.fillRect(7,3, 3,1);
 465             g.fillRect(6,4, 5,1);
 466             g.fillRect(5,5, 7,1);
 467             g.fillRect(4,6, 9,2);
 468             // Draw doornob
 469             //     same color as roof body
 470             g.drawLine(9,12, 9,12);
 471 
 472             // Paint the house
 473             g.setColor(MetalLookAndFeel.getPrimaryControl());
 474             g.drawLine(4,8, 12,8); // above door
 475             g.fillRect(4,9, 2,6); // left of door
 476             g.fillRect(11,9, 2,6); // right of door
 477 
 478             g.translate(-x, -y);
 479         }
 480 
 481         public int getIconWidth() {
 482             return 18;
 483         }
 484 
 485         public int getIconHeight() {
 486             return 18;
 487         }
 488     }  // End class FileChooserHomeFolderIcon
 489 
 490     // File Chooser List View code
 491     private static class FileChooserListViewIcon implements Icon, UIResource, Serializable {
 492         public void paintIcon(Component c, Graphics g, int x, int y) {
 493             g.translate(x, y);
 494 
 495             // Draw outside edge of each of the documents
 496             g.setColor(MetalLookAndFeel.getPrimaryControlInfo());
 497             //     top left
 498             g.drawLine(2,2, 5,2); // top
 499             g.drawLine(2,3, 2,7); // left
 500             g.drawLine(3,7, 6,7); // bottom
 501             g.drawLine(6,6, 6,3); // right
 502             //     top right
 503             g.drawLine(10,2, 13,2); // top
 504             g.drawLine(10,3, 10,7); // left
 505             g.drawLine(11,7, 14,7); // bottom
 506             g.drawLine(14,6, 14,3); // right
 507             //     bottom left
 508             g.drawLine(2,10, 5,10); // top
 509             g.drawLine(2,11, 2,15); // left
 510             g.drawLine(3,15, 6,15); // bottom
 511             g.drawLine(6,14, 6,11); // right
 512             //     bottom right
 513             g.drawLine(10,10, 13,10); // top
 514             g.drawLine(10,11, 10,15); // left
 515             g.drawLine(11,15, 14,15); // bottom
 516             g.drawLine(14,14, 14,11); // right
 517 
 518             // Draw little dots next to documents
 519             //     Same color as outside edge
 520             g.drawLine(8,5, 8,5);     // top left
 521             g.drawLine(16,5, 16,5);   // top right
 522             g.drawLine(8,13, 8,13);   // bottom left
 523             g.drawLine(16,13, 16,13); // bottom right
 524 
 525             // Draw inner highlight on documents
 526             g.setColor(MetalLookAndFeel.getPrimaryControl());
 527             g.drawRect(3,3, 2,3);   // top left
 528             g.drawRect(11,3, 2,3);  // top right
 529             g.drawRect(3,11, 2,3);  // bottom left
 530             g.drawRect(11,11, 2,3); // bottom right
 531 
 532             // Draw inner inner highlight on documents
 533             g.setColor(MetalLookAndFeel.getPrimaryControlHighlight());
 534             g.drawLine(4,4, 4,5);     // top left
 535             g.drawLine(12,4, 12,5);   // top right
 536             g.drawLine(4,12, 4,13);   // bottom left
 537             g.drawLine(12,12, 12,13); // bottom right
 538 
 539             g.translate(-x, -y);
 540         }
 541 
 542         public int getIconWidth() {
 543             return 18;
 544         }
 545 
 546         public int getIconHeight() {
 547             return 18;
 548         }
 549     }  // End class FileChooserListViewIcon
 550 
 551     // File Chooser New Folder code
 552     private static class FileChooserNewFolderIcon implements Icon, UIResource, Serializable {
 553         public void paintIcon(Component c, Graphics g, int x, int y) {
 554             g.translate(x, y);
 555 
 556             // Fill background
 557             g.setColor(MetalLookAndFeel.getPrimaryControl());
 558             g.fillRect(3,5, 12,9);
 559 
 560             // Draw outside edge of folder
 561             g.setColor(MetalLookAndFeel.getPrimaryControlInfo());
 562             g.drawLine(1,6,    1,14); // left
 563             g.drawLine(2,14,  15,14); // bottom
 564             g.drawLine(15,13, 15,5);  // right
 565             g.drawLine(2,5,    9,5);  // top left
 566             g.drawLine(10,6,  14,6);  // top right
 567 
 568             // Draw inner folder highlight
 569             g.setColor(MetalLookAndFeel.getPrimaryControlHighlight());
 570             g.drawLine( 2,6,  2,13); // left
 571             g.drawLine( 3,6,  9,6);  // top left
 572             g.drawLine(10,7, 14,7);  // top right
 573 
 574             // Draw tab on folder
 575             g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
 576             g.drawLine(11,3, 15,3); // top
 577             g.drawLine(10,4, 15,4); // bottom
 578 
 579             g.translate(-x, -y);
 580         }
 581 
 582         public int getIconWidth() {
 583             return 18;
 584         }
 585 
 586         public int getIconHeight() {
 587             return 18;
 588         }
 589     }  // End class FileChooserNewFolderIcon
 590 
 591     // File Chooser Up Folder code
 592     private static class FileChooserUpFolderIcon implements Icon, UIResource, Serializable {
 593         public void paintIcon(Component c, Graphics g, int x, int y) {
 594             g.translate(x, y);
 595 
 596             // Fill background
 597             g.setColor(MetalLookAndFeel.getPrimaryControl());
 598             g.fillRect(3,5, 12,9);
 599 
 600             // Draw outside edge of folder
 601             g.setColor(MetalLookAndFeel.getPrimaryControlInfo());
 602             g.drawLine(1,6,    1,14); // left
 603             g.drawLine(2,14,  15,14); // bottom
 604             g.drawLine(15,13, 15,5);  // right
 605             g.drawLine(2,5,    9,5);  // top left
 606             g.drawLine(10,6,  14,6);  // top right
 607             // Draw the UP arrow
 608             //     same color as edge
 609             g.drawLine(8,13,  8,16); // arrow shaft
 610             g.drawLine(8, 9,  8, 9); // arrowhead top
 611             g.drawLine(7,10,  9,10);
 612             g.drawLine(6,11, 10,11);
 613             g.drawLine(5,12, 11,12);
 614 
 615             // Draw inner folder highlight
 616             g.setColor(MetalLookAndFeel.getPrimaryControlHighlight());
 617             g.drawLine( 2,6,  2,13); // left
 618             g.drawLine( 3,6,  9,6);  // top left
 619             g.drawLine(10,7, 14,7);  // top right
 620 
 621             // Draw tab on folder
 622             g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
 623             g.drawLine(11,3, 15,3); // top
 624             g.drawLine(10,4, 15,4); // bottom
 625 
 626             g.translate(-x, -y);
 627         }
 628 
 629         public int getIconWidth() {
 630             return 18;
 631         }
 632 
 633         public int getIconHeight() {
 634             return 18;
 635         }
 636     }  // End class FileChooserUpFolderIcon
 637 
 638 
 639     /**
 640      * Defines an icon for Palette close
 641      * @since 1.3
 642      */
 643     public static class PaletteCloseIcon implements Icon, UIResource, Serializable{
 644         int iconSize = 7;
 645 
 646         public void paintIcon(Component c, Graphics g, int x, int y) {
 647             JButton parentButton = (JButton)c;
 648             ButtonModel buttonModel = parentButton.getModel();
 649 
 650             Color back;
 651             Color highlight = MetalLookAndFeel.getPrimaryControlHighlight();
 652             Color shadow = MetalLookAndFeel.getPrimaryControlInfo();
 653             if (buttonModel.isPressed() && buttonModel.isArmed()) {
 654                 back = shadow;
 655             } else {
 656                 back = MetalLookAndFeel.getPrimaryControlDarkShadow();
 657             }
 658 
 659             g.translate(x, y);
 660             g.setColor(back);
 661             g.drawLine( 0, 1, 5, 6);
 662             g.drawLine( 1, 0, 6, 5);
 663             g.drawLine( 1, 1, 6, 6);
 664             g.drawLine( 6, 1, 1, 6);
 665             g.drawLine( 5,0, 0,5);
 666             g.drawLine(5,1, 1,5);
 667 
 668             g.setColor(highlight);
 669             g.drawLine(6,2, 5,3);
 670             g.drawLine(2,6, 3, 5);
 671             g.drawLine(6,6,6,6);
 672 
 673 
 674             g.translate(-x, -y);
 675         }
 676 
 677         public int getIconWidth() {
 678             return iconSize;
 679         }
 680 
 681         public int getIconHeight() {
 682             return iconSize;
 683         }
 684     }
 685 
 686     // Internal Frame Close code
 687     private static class InternalFrameCloseIcon implements Icon, UIResource, Serializable {
 688         int iconSize = 16;
 689 
 690         public InternalFrameCloseIcon(int size) {
 691             iconSize = size;
 692         }
 693 
 694         public void paintIcon(Component c, Graphics g, int x, int y) {
 695             JButton parentButton = (JButton)c;
 696             ButtonModel buttonModel = parentButton.getModel();
 697 
 698             Color backgroundColor = MetalLookAndFeel.getPrimaryControl();
 699             Color internalBackgroundColor =
 700                 MetalLookAndFeel.getPrimaryControl();
 701             Color mainItemColor =
 702                 MetalLookAndFeel.getPrimaryControlDarkShadow();
 703             Color darkHighlightColor = MetalLookAndFeel.getBlack();
 704             Color xLightHighlightColor = MetalLookAndFeel.getWhite();
 705             Color boxLightHighlightColor = MetalLookAndFeel.getWhite();
 706 
 707             // if the inactive window
 708             if (parentButton.getClientProperty("paintActive") != Boolean.TRUE)
 709             {
 710                 backgroundColor = MetalLookAndFeel.getControl();
 711                 internalBackgroundColor = backgroundColor;
 712                 mainItemColor = MetalLookAndFeel.getControlDarkShadow();
 713                 // if inactive and pressed
 714                 if (buttonModel.isPressed() && buttonModel.isArmed()) {
 715                     internalBackgroundColor =
 716                         MetalLookAndFeel.getControlShadow();
 717                     xLightHighlightColor = internalBackgroundColor;
 718                     mainItemColor = darkHighlightColor;
 719                 }
 720             }
 721             // if pressed
 722             else if (buttonModel.isPressed() && buttonModel.isArmed()) {
 723                 internalBackgroundColor =
 724                     MetalLookAndFeel.getPrimaryControlShadow();
 725                 xLightHighlightColor = internalBackgroundColor;
 726                 mainItemColor = darkHighlightColor;
 727                 // darkHighlightColor is still "getBlack()"
 728             }
 729 
 730             // Some calculations that are needed more than once later on.
 731             int oneHalf = iconSize / 2; // 16 -> 8
 732 
 733             g.translate(x, y);
 734 
 735             // fill background
 736             g.setColor(backgroundColor);
 737             g.fillRect(0,0, iconSize,iconSize);
 738 
 739             // fill inside of box area
 740             g.setColor(internalBackgroundColor);
 741             g.fillRect(3,3, iconSize-6,iconSize-6);
 742 
 743             // THE BOX
 744             // the top/left dark higlight - some of this will get overwritten
 745             g.setColor(darkHighlightColor);
 746             g.drawRect(1,1, iconSize-3,iconSize-3);
 747             // draw the inside bottom/right highlight
 748             g.drawRect(2,2, iconSize-5,iconSize-5);
 749             // draw the light/outside, bottom/right highlight
 750             g.setColor(boxLightHighlightColor);
 751             g.drawRect(2,2, iconSize-3,iconSize-3);
 752             // draw the "normal" box
 753             g.setColor(mainItemColor);
 754             g.drawRect(2,2, iconSize-4,iconSize-4);
 755             g.drawLine(3,iconSize-3, 3,iconSize-3); // lower left
 756             g.drawLine(iconSize-3,3, iconSize-3,3); // up right
 757 
 758             // THE "X"
 759             // Dark highlight
 760             g.setColor(darkHighlightColor);
 761             g.drawLine(4,5, 5,4); // far up left
 762             g.drawLine(4,iconSize-6, iconSize-6,4); // against body of "X"
 763             // Light highlight
 764             g.setColor(xLightHighlightColor);
 765             g.drawLine(6,iconSize-5, iconSize-5,6); // against body of "X"
 766               // one pixel over from the body
 767             g.drawLine(oneHalf,oneHalf+2, oneHalf+2,oneHalf);
 768               // bottom right
 769             g.drawLine(iconSize-5,iconSize-5, iconSize-4,iconSize-5);
 770             g.drawLine(iconSize-5,iconSize-4, iconSize-5,iconSize-4);
 771             // Main color
 772             g.setColor(mainItemColor);
 773               // Upper left to lower right
 774             g.drawLine(5,5, iconSize-6,iconSize-6); // g.drawLine(5,5, 10,10);
 775             g.drawLine(6,5, iconSize-5,iconSize-6); // g.drawLine(6,5, 11,10);
 776             g.drawLine(5,6, iconSize-6,iconSize-5); // g.drawLine(5,6, 10,11);
 777               // Lower left to upper right
 778             g.drawLine(5,iconSize-5, iconSize-5,5); // g.drawLine(5,11, 11,5);
 779             g.drawLine(5,iconSize-6, iconSize-6,5); // g.drawLine(5,10, 10,5);
 780 
 781             g.translate(-x, -y);
 782         }
 783 
 784         public int getIconWidth() {
 785             return iconSize;
 786         }
 787 
 788         public int getIconHeight() {
 789             return iconSize;
 790         }
 791     }  // End class InternalFrameCloseIcon
 792 
 793     // Internal Frame Alternate Maximize code (actually, the un-maximize icon)
 794     private static class InternalFrameAltMaximizeIcon implements Icon, UIResource, Serializable {
 795         int iconSize = 16;
 796 
 797         public InternalFrameAltMaximizeIcon(int size) {
 798             iconSize = size;
 799         }
 800 
 801         public void paintIcon(Component c, Graphics g, int x, int y) {
 802             JButton parentButton = (JButton)c;
 803             ButtonModel buttonModel = parentButton.getModel();
 804 
 805             Color backgroundColor = MetalLookAndFeel.getPrimaryControl();
 806             Color internalBackgroundColor =
 807                 MetalLookAndFeel.getPrimaryControl();
 808             Color mainItemColor =
 809                 MetalLookAndFeel.getPrimaryControlDarkShadow();
 810             Color darkHighlightColor = MetalLookAndFeel.getBlack();
 811             // ul = Upper Left and lr = Lower Right
 812             Color ulLightHighlightColor = MetalLookAndFeel.getWhite();
 813             Color lrLightHighlightColor = MetalLookAndFeel.getWhite();
 814 
 815             // if the internal frame is inactive
 816             if (parentButton.getClientProperty("paintActive") != Boolean.TRUE)
 817             {
 818                 backgroundColor = MetalLookAndFeel.getControl();
 819                 internalBackgroundColor = backgroundColor;
 820                 mainItemColor = MetalLookAndFeel.getControlDarkShadow();
 821                 // if inactive and pressed
 822                 if (buttonModel.isPressed() && buttonModel.isArmed()) {
 823                     internalBackgroundColor =
 824                         MetalLookAndFeel.getControlShadow();
 825                     ulLightHighlightColor = internalBackgroundColor;
 826                     mainItemColor = darkHighlightColor;
 827                 }
 828             }
 829             // if the button is pressed and the mouse is over it
 830             else if (buttonModel.isPressed() && buttonModel.isArmed()) {
 831                 internalBackgroundColor =
 832                     MetalLookAndFeel.getPrimaryControlShadow();
 833                 ulLightHighlightColor = internalBackgroundColor;
 834                 mainItemColor = darkHighlightColor;
 835                 // darkHighlightColor is still "getBlack()"
 836             }
 837 
 838             g.translate(x, y);
 839 
 840             // fill background
 841             g.setColor(backgroundColor);
 842             g.fillRect(0,0, iconSize,iconSize);
 843 
 844             // BOX
 845             // fill inside the box
 846             g.setColor(internalBackgroundColor);
 847             g.fillRect(3,6, iconSize-9,iconSize-9);
 848 
 849             // draw dark highlight color
 850             g.setColor(darkHighlightColor);
 851             g.drawRect(1,5, iconSize-8,iconSize-8);
 852             g.drawLine(1,iconSize-2, 1,iconSize-2); // extra pixel on bottom
 853 
 854             // draw lower right light highlight
 855             g.setColor(lrLightHighlightColor);
 856             g.drawRect(2,6, iconSize-7,iconSize-7);
 857             // draw upper left light highlight
 858             g.setColor(ulLightHighlightColor);
 859             g.drawRect(3,7, iconSize-9,iconSize-9);
 860 
 861             // draw the main box
 862             g.setColor(mainItemColor);
 863             g.drawRect(2,6, iconSize-8,iconSize-8);
 864 
 865             // Six extraneous pixels to deal with
 866             g.setColor(ulLightHighlightColor);
 867             g.drawLine(iconSize-6,8,iconSize-6,8);
 868             g.drawLine(iconSize-9,6, iconSize-7,8);
 869             g.setColor(mainItemColor);
 870             g.drawLine(3,iconSize-3,3,iconSize-3);
 871             g.setColor(darkHighlightColor);
 872             g.drawLine(iconSize-6,9,iconSize-6,9);
 873             g.setColor(backgroundColor);
 874             g.drawLine(iconSize-9,5,iconSize-9,5);
 875 
 876             // ARROW
 877             // do the shaft first
 878             g.setColor(mainItemColor);
 879             g.fillRect(iconSize-7,3, 3,5); // do a big block
 880             g.drawLine(iconSize-6,5, iconSize-3,2); // top shaft
 881             g.drawLine(iconSize-6,6, iconSize-2,2); // bottom shaft
 882             g.drawLine(iconSize-6,7, iconSize-3,7); // bottom arrow head
 883 
 884             // draw the dark highlight
 885             g.setColor(darkHighlightColor);
 886             g.drawLine(iconSize-8,2, iconSize-7,2); // top of arrowhead
 887             g.drawLine(iconSize-8,3, iconSize-8,7); // left of arrowhead
 888             g.drawLine(iconSize-6,4, iconSize-3,1); // top of shaft
 889             g.drawLine(iconSize-4,6, iconSize-3,6); // top,right of arrowhead
 890 
 891             // draw the light highlight
 892             g.setColor(lrLightHighlightColor);
 893             g.drawLine(iconSize-6,3, iconSize-6,3); // top
 894             g.drawLine(iconSize-4,5, iconSize-2,3); // under shaft
 895             g.drawLine(iconSize-4,8, iconSize-3,8); // under arrowhead
 896             g.drawLine(iconSize-2,8, iconSize-2,7); // right of arrowhead
 897 
 898             g.translate(-x, -y);
 899         }
 900 
 901         public int getIconWidth() {
 902             return iconSize;
 903         }
 904 
 905         public int getIconHeight() {
 906             return iconSize;
 907         }
 908     }  // End class InternalFrameAltMaximizeIcon
 909 
 910     // Code for the default icons that goes in the upper left corner
 911     private static class InternalFrameDefaultMenuIcon implements Icon, UIResource, Serializable {
 912         public void paintIcon(Component c, Graphics g, int x, int y) {
 913 
 914             Color windowBodyColor = MetalLookAndFeel.getWindowBackground();
 915             Color titleColor = MetalLookAndFeel.getPrimaryControl();
 916             Color edgeColor = MetalLookAndFeel.getPrimaryControlDarkShadow();
 917 
 918             g.translate(x, y);
 919 
 920             // draw background color for title area
 921             // catch four corners and title area
 922             g.setColor(titleColor);
 923             g.fillRect(0,0, 16,16);
 924 
 925             // fill body of window
 926             g.setColor(windowBodyColor);
 927             g.fillRect(2,6, 13,9);
 928             // draw light parts of two "bumps"
 929             g.drawLine(2,2, 2,2);
 930             g.drawLine(5,2, 5,2);
 931             g.drawLine(8,2, 8,2);
 932             g.drawLine(11,2, 11,2);
 933 
 934             // draw line around edge of title and icon
 935             g.setColor(edgeColor);
 936             g.drawRect(1,1, 13,13); // entire inner edge
 937             g.drawLine(1,0, 14,0); // top outter edge
 938             g.drawLine(15,1, 15,14); // right outter edge
 939             g.drawLine(1,15, 14,15); // bottom outter edge
 940             g.drawLine(0,1, 0,14); // left outter edge
 941             g.drawLine(2,5, 13,5); // bottom of title bar area
 942             // draw dark part of four "bumps" (same color)
 943             g.drawLine(3,3, 3,3);
 944             g.drawLine(6,3, 6,3);
 945             g.drawLine(9,3, 9,3);
 946             g.drawLine(12,3, 12,3);
 947 
 948             g.translate(-x, -y);
 949         }
 950 
 951         public int getIconWidth() {
 952             return 16;
 953         }
 954 
 955         public int getIconHeight() {
 956             return 16;
 957         }
 958     }  // End class InternalFrameDefaultMenuIcon
 959 
 960     // Internal Frame Maximize code
 961     private static class InternalFrameMaximizeIcon implements Icon, UIResource, Serializable {
 962         protected int iconSize = 16;
 963 
 964         public InternalFrameMaximizeIcon(int size) {
 965             iconSize = size;
 966         }
 967 
 968         public void paintIcon(Component c, Graphics g, int x, int y) {
 969             JButton parentButton = (JButton)c;
 970             ButtonModel buttonModel = parentButton.getModel();
 971 
 972             Color backgroundColor = MetalLookAndFeel.getPrimaryControl();
 973             Color internalBackgroundColor =
 974                 MetalLookAndFeel.getPrimaryControl();
 975             Color mainItemColor =
 976                 MetalLookAndFeel.getPrimaryControlDarkShadow();
 977             Color darkHighlightColor = MetalLookAndFeel.getBlack();
 978             // ul = Upper Left and lr = Lower Right
 979             Color ulLightHighlightColor = MetalLookAndFeel.getWhite();
 980             Color lrLightHighlightColor = MetalLookAndFeel.getWhite();
 981 
 982             // if the internal frame is inactive
 983             if (parentButton.getClientProperty("paintActive") != Boolean.TRUE)
 984             {
 985                 backgroundColor = MetalLookAndFeel.getControl();
 986                 internalBackgroundColor = backgroundColor;
 987                 mainItemColor = MetalLookAndFeel.getControlDarkShadow();
 988                 // if inactive and pressed
 989                 if (buttonModel.isPressed() && buttonModel.isArmed()) {
 990                     internalBackgroundColor =
 991                         MetalLookAndFeel.getControlShadow();
 992                     ulLightHighlightColor = internalBackgroundColor;
 993                     mainItemColor = darkHighlightColor;
 994                 }
 995             }
 996             // if the button is pressed and the mouse is over it
 997             else if (buttonModel.isPressed() && buttonModel.isArmed()) {
 998                 internalBackgroundColor =
 999                     MetalLookAndFeel.getPrimaryControlShadow();
1000                 ulLightHighlightColor = internalBackgroundColor;
1001                 mainItemColor = darkHighlightColor;
1002                 // darkHighlightColor is still "getBlack()"
1003             }
1004 
1005             g.translate(x, y);
1006 
1007             // fill background
1008             g.setColor(backgroundColor);
1009             g.fillRect(0,0, iconSize,iconSize);
1010 
1011             // BOX drawing
1012             // fill inside the box
1013             g.setColor(internalBackgroundColor);
1014             g.fillRect(3,7, iconSize-10,iconSize-10);
1015 
1016             // light highlight
1017             g.setColor(ulLightHighlightColor);
1018             g.drawRect(3,7, iconSize-10,iconSize-10); // up,left
1019             g.setColor(lrLightHighlightColor);
1020             g.drawRect(2,6, iconSize-7,iconSize-7); // low,right
1021             // dark highlight
1022             g.setColor(darkHighlightColor);
1023             g.drawRect(1,5, iconSize-7,iconSize-7); // outer
1024             g.drawRect(2,6, iconSize-9,iconSize-9); // inner
1025             // main box
1026             g.setColor(mainItemColor);
1027             g.drawRect(2,6, iconSize-8,iconSize-8); // g.drawRect(2,6, 8,8);
1028 
1029             // ARROW drawing
1030             // dark highlight
1031             g.setColor(darkHighlightColor);
1032               // down,left to up,right - inside box
1033             g.drawLine(3,iconSize-5, iconSize-9,7);
1034               // down,left to up,right - outside box
1035             g.drawLine(iconSize-6,4, iconSize-5,3);
1036               // outside edge of arrow head
1037             g.drawLine(iconSize-7,1, iconSize-7,2);
1038               // outside edge of arrow head
1039             g.drawLine(iconSize-6,1, iconSize-2,1);
1040             // light highlight
1041             g.setColor(ulLightHighlightColor);
1042               // down,left to up,right - inside box
1043             g.drawLine(5,iconSize-4, iconSize-8,9);
1044             g.setColor(lrLightHighlightColor);
1045             g.drawLine(iconSize-6,3, iconSize-4,5); // outside box
1046             g.drawLine(iconSize-4,5, iconSize-4,6); // one down from this
1047             g.drawLine(iconSize-2,7, iconSize-1,7); // outside edge arrow head
1048             g.drawLine(iconSize-1,2, iconSize-1,6); // outside edge arrow head
1049             // main part of arrow
1050             g.setColor(mainItemColor);
1051             g.drawLine(3,iconSize-4, iconSize-3,2); // top edge of staff
1052             g.drawLine(3,iconSize-3, iconSize-2,2); // bottom edge of staff
1053             g.drawLine(4,iconSize-3, 5,iconSize-3); // highlights inside of box
1054             g.drawLine(iconSize-7,8, iconSize-7,9); // highlights inside of box
1055             g.drawLine(iconSize-6,2, iconSize-4,2); // top of arrow head
1056             g.drawRect(iconSize-3,3, 1,3); // right of arrow head
1057 
1058             g.translate(-x, -y);
1059         }
1060 
1061         public int getIconWidth() {
1062             return iconSize;
1063         }
1064 
1065         public int getIconHeight() {
1066             return iconSize;
1067         }
1068     }  // End class InternalFrameMaximizeIcon
1069 
1070     // Internal Frame Minimize code
1071     private static class InternalFrameMinimizeIcon implements Icon, UIResource, Serializable {
1072         int iconSize = 16;
1073 
1074         public InternalFrameMinimizeIcon(int size) {
1075             iconSize = size;
1076         }
1077 
1078         public void paintIcon(Component c, Graphics g, int x, int y) {
1079             JButton parentButton = (JButton)c;
1080             ButtonModel buttonModel = parentButton.getModel();
1081 
1082 
1083             Color backgroundColor = MetalLookAndFeel.getPrimaryControl();
1084             Color internalBackgroundColor =
1085                 MetalLookAndFeel.getPrimaryControl();
1086             Color mainItemColor =
1087                 MetalLookAndFeel.getPrimaryControlDarkShadow();
1088             Color darkHighlightColor = MetalLookAndFeel.getBlack();
1089             // ul = Upper Left and lr = Lower Right
1090             Color ulLightHighlightColor = MetalLookAndFeel.getWhite();
1091             Color lrLightHighlightColor = MetalLookAndFeel.getWhite();
1092 
1093             // if the internal frame is inactive
1094             if (parentButton.getClientProperty("paintActive") != Boolean.TRUE)
1095             {
1096                 backgroundColor = MetalLookAndFeel.getControl();
1097                 internalBackgroundColor = backgroundColor;
1098                 mainItemColor = MetalLookAndFeel.getControlDarkShadow();
1099                 // if inactive and pressed
1100                 if (buttonModel.isPressed() && buttonModel.isArmed()) {
1101                     internalBackgroundColor =
1102                         MetalLookAndFeel.getControlShadow();
1103                     ulLightHighlightColor = internalBackgroundColor;
1104                     mainItemColor = darkHighlightColor;
1105                 }
1106             }
1107             // if the button is pressed and the mouse is over it
1108             else if (buttonModel.isPressed() && buttonModel.isArmed()) {
1109                 internalBackgroundColor =
1110                     MetalLookAndFeel.getPrimaryControlShadow();
1111                 ulLightHighlightColor = internalBackgroundColor;
1112                 mainItemColor = darkHighlightColor;
1113                 // darkHighlightColor is still "getBlack()"
1114             }
1115 
1116             g.translate(x, y);
1117 
1118             // fill background
1119             g.setColor(backgroundColor);
1120             g.fillRect(0,0, iconSize,iconSize);
1121 
1122             // BOX drawing
1123             // fill inside the box
1124             g.setColor(internalBackgroundColor);
1125             g.fillRect(4,11, iconSize-13,iconSize-13);
1126             // light highlight
1127             g.setColor(lrLightHighlightColor);
1128             g.drawRect(2,10, iconSize-10,iconSize-11); // low,right
1129             g.setColor(ulLightHighlightColor);
1130             g.drawRect(3,10, iconSize-12,iconSize-12); // up,left
1131             // dark highlight
1132             g.setColor(darkHighlightColor);
1133             g.drawRect(1,8, iconSize-10,iconSize-10); // outer
1134             g.drawRect(2,9, iconSize-12,iconSize-12); // inner
1135             // main box
1136             g.setColor(mainItemColor);
1137             g.drawRect(2,9, iconSize-11,iconSize-11);
1138             g.drawLine(iconSize-10,10, iconSize-10,10); // up right highlight
1139             g.drawLine(3,iconSize-3, 3,iconSize-3); // low left highlight
1140 
1141             // ARROW
1142             // do the shaft first
1143             g.setColor(mainItemColor);
1144             g.fillRect(iconSize-7,3, 3,5); // do a big block
1145             g.drawLine(iconSize-6,5, iconSize-3,2); // top shaft
1146             g.drawLine(iconSize-6,6, iconSize-2,2); // bottom shaft
1147             g.drawLine(iconSize-6,7, iconSize-3,7); // bottom arrow head
1148 
1149             // draw the dark highlight
1150             g.setColor(darkHighlightColor);
1151             g.drawLine(iconSize-8,2, iconSize-7,2); // top of arrowhead
1152             g.drawLine(iconSize-8,3, iconSize-8,7); // left of arrowhead
1153             g.drawLine(iconSize-6,4, iconSize-3,1); // top of shaft
1154             g.drawLine(iconSize-4,6, iconSize-3,6); // top,right of arrowhead
1155 
1156             // draw the light highlight
1157             g.setColor(lrLightHighlightColor);
1158             g.drawLine(iconSize-6,3, iconSize-6,3); // top
1159             g.drawLine(iconSize-4,5, iconSize-2,3); // under shaft
1160             g.drawLine(iconSize-7,8, iconSize-3,8); // under arrowhead
1161             g.drawLine(iconSize-2,8, iconSize-2,7); // right of arrowhead
1162 
1163             g.translate(-x, -y);
1164         }
1165 
1166         public int getIconWidth() {
1167             return iconSize;
1168         }
1169 
1170         public int getIconHeight() {
1171             return iconSize;
1172         }
1173     }  // End class InternalFrameMinimizeIcon
1174 
1175     private static class CheckBoxIcon implements Icon, UIResource, Serializable {
1176 
1177         protected int getControlSize() { return 13; }
1178 
1179         private void paintOceanIcon(Component c, Graphics g, int x, int y) {
1180             ButtonModel model = ((JCheckBox)c).getModel();
1181 
1182             g.translate(x, y);
1183             int w = getIconWidth();
1184             int h = getIconHeight();
1185             if ( model.isEnabled() ) {
1186                 if (model.isPressed() && model.isArmed()) {
1187                     g.setColor(MetalLookAndFeel.getControlShadow());
1188                     g.fillRect(0, 0, w, h);
1189                     g.setColor(MetalLookAndFeel.getControlDarkShadow());
1190                     g.fillRect(0, 0, w, 2);
1191                     g.fillRect(0, 2, 2, h - 2);
1192                     g.fillRect(w - 1, 1, 1, h - 1);
1193                     g.fillRect(1, h - 1, w - 2, 1);
1194                 } else if (model.isRollover()) {
1195                     MetalUtils.drawGradient(c, g, "CheckBox.gradient", 0, 0,
1196                                             w, h, true);
1197                     g.setColor(MetalLookAndFeel.getControlDarkShadow());
1198                     g.drawRect(0, 0, w - 1, h - 1);
1199                     g.setColor(MetalLookAndFeel.getPrimaryControl());
1200                     g.drawRect(1, 1, w - 3, h - 3);
1201                     g.drawRect(2, 2, w - 5, h - 5);
1202                 }
1203                 else {
1204                     MetalUtils.drawGradient(c, g, "CheckBox.gradient", 0, 0,
1205                                             w, h, true);
1206                     g.setColor(MetalLookAndFeel.getControlDarkShadow());
1207                     g.drawRect(0, 0, w - 1, h - 1);
1208                 }
1209                 g.setColor( MetalLookAndFeel.getControlInfo() );
1210             } else {
1211                 g.setColor(MetalLookAndFeel.getControlDarkShadow());
1212                 g.drawRect(0, 0, w - 1, h - 1);
1213             }
1214             g.translate(-x, -y);
1215             if (model.isSelected()) {
1216                 drawCheck(c,g,x,y);
1217             }
1218         }
1219 
1220         public void paintIcon(Component c, Graphics g, int x, int y) {
1221             if (MetalLookAndFeel.usingOcean()) {
1222                 paintOceanIcon(c, g, x, y);
1223                 return;
1224             }
1225             ButtonModel model = ((JCheckBox)c).getModel();
1226             int controlSize = getControlSize();
1227 
1228             if ( model.isEnabled() ) {
1229                 if (model.isPressed() && model.isArmed()) {
1230                     g.setColor( MetalLookAndFeel.getControlShadow() );
1231                     g.fillRect( x, y, controlSize-1, controlSize-1);
1232                     MetalUtils.drawPressed3DBorder(g, x, y, controlSize, controlSize);
1233                 } else {
1234                     MetalUtils.drawFlush3DBorder(g, x, y, controlSize, controlSize);
1235                 }
1236                 g.setColor(c.getForeground());
1237             } else {
1238                 g.setColor( MetalLookAndFeel.getControlShadow() );
1239                 g.drawRect( x, y, controlSize-2, controlSize-2);
1240             }
1241 
1242             if (model.isSelected()) {
1243                 drawCheck(c,g,x,y);
1244             }
1245 
1246         }
1247 
1248         protected void drawCheck(Component c, Graphics g, int x, int y) {
1249             int controlSize = getControlSize();
1250             g.fillRect( x+3, y+5, 2, controlSize-8 );
1251             g.drawLine( x+(controlSize-4), y+3, x+5, y+(controlSize-6) );
1252             g.drawLine( x+(controlSize-4), y+4, x+5, y+(controlSize-5) );
1253         }
1254 
1255         public int getIconWidth() {
1256             return getControlSize();
1257         }
1258 
1259         public int getIconHeight() {
1260             return getControlSize();
1261         }
1262     } // End class CheckBoxIcon
1263 
1264     // Radio button code
1265     private static class RadioButtonIcon implements Icon, UIResource, Serializable {
1266         public void paintOceanIcon(Component c, Graphics g, int x, int y) {
1267             ButtonModel model = ((JRadioButton)c).getModel();
1268             boolean enabled = model.isEnabled();
1269             boolean pressed = (enabled && model.isPressed() &&
1270                                model.isArmed());
1271             boolean rollover = (enabled && model.isRollover());
1272 
1273             g.translate(x, y);
1274             if (enabled && !pressed) {
1275                 // PENDING: this isn't quite right, when we're sure it won't
1276                 // change it needs to be cleaned.
1277                 MetalUtils.drawGradient(c, g, "RadioButton.gradient",
1278                                         1, 1, 10, 10, true);
1279                 g.setColor(c.getBackground());
1280                 g.fillRect(1, 1, 1, 1);
1281                 g.fillRect(10, 1, 1, 1);
1282                 g.fillRect(1, 10, 1, 1);
1283                 g.fillRect(10, 10, 1, 1);
1284             }
1285             else if (pressed || !enabled) {
1286                 if (pressed) {
1287                     g.setColor(MetalLookAndFeel.getPrimaryControl());
1288                 }
1289                 else {
1290                     g.setColor(MetalLookAndFeel.getControl());
1291                 }
1292                 g.fillRect(2, 2, 8, 8);
1293                 g.fillRect(4, 1, 4, 1);
1294                 g.fillRect(4, 10, 4, 1);
1295                 g.fillRect(1, 4, 1, 4);
1296                 g.fillRect(10, 4, 1, 4);
1297             }
1298 
1299             // draw Dark Circle (start at top, go clockwise)
1300             if (!enabled) {
1301                 g.setColor(MetalLookAndFeel.getInactiveControlTextColor());
1302             }
1303             else {
1304                 g.setColor(MetalLookAndFeel.getControlDarkShadow());
1305             }
1306             g.drawLine( 4, 0,  7, 0);
1307             g.drawLine( 8, 1,  9, 1);
1308             g.drawLine(10, 2, 10, 3);
1309             g.drawLine(11, 4, 11, 7);
1310             g.drawLine(10, 8, 10, 9);
1311             g.drawLine( 9,10,  8,10);
1312             g.drawLine( 7,11,  4,11);
1313             g.drawLine( 3,10,  2,10);
1314             g.drawLine( 1, 9,  1, 8);
1315             g.drawLine( 0, 7,  0, 4);
1316             g.drawLine( 1, 3,  1, 2);
1317             g.drawLine( 2, 1,  3, 1);
1318 
1319             if (pressed) {
1320                 g.fillRect(1, 4, 1, 4);
1321                 g.fillRect(2, 2, 1, 2);
1322                 g.fillRect(3, 2, 1, 1);
1323                 g.fillRect(4, 1, 4, 1);
1324             }
1325             else if (rollover) {
1326                 g.setColor(MetalLookAndFeel.getPrimaryControl());
1327                 g.fillRect(4, 1, 4, 2);
1328                 g.fillRect(8, 2, 2, 2);
1329                 g.fillRect(9, 4, 2, 4);
1330                 g.fillRect(8, 8, 2, 2);
1331                 g.fillRect(4, 9, 4, 2);
1332                 g.fillRect(2, 8, 2, 2);
1333                 g.fillRect(1, 4, 2, 4);
1334                 g.fillRect(2, 2, 2, 2);
1335             }
1336 
1337             // selected dot
1338             if (model.isSelected()) {
1339                 if (enabled) {
1340                     g.setColor(MetalLookAndFeel.getControlInfo());
1341                 } else {
1342                     g.setColor(MetalLookAndFeel.getControlDarkShadow());
1343                 }
1344                 g.fillRect( 4, 4,  4, 4);
1345                 g.drawLine( 4, 3,  7, 3);
1346                 g.drawLine( 8, 4,  8, 7);
1347                 g.drawLine( 7, 8,  4, 8);
1348                 g.drawLine( 3, 7,  3, 4);
1349             }
1350 
1351             g.translate(-x, -y);
1352         }
1353 
1354         public void paintIcon(Component c, Graphics g, int x, int y) {
1355             if (MetalLookAndFeel.usingOcean()) {
1356                 paintOceanIcon(c, g, x, y);
1357                 return;
1358             }
1359             JRadioButton rb = (JRadioButton)c;
1360             ButtonModel model = rb.getModel();
1361             boolean drawDot = model.isSelected();
1362 
1363             Color background = c.getBackground();
1364             Color dotColor = c.getForeground();
1365             Color shadow = MetalLookAndFeel.getControlShadow();
1366             Color darkCircle = MetalLookAndFeel.getControlDarkShadow();
1367             Color whiteInnerLeftArc = MetalLookAndFeel.getControlHighlight();
1368             Color whiteOuterRightArc = MetalLookAndFeel.getControlHighlight();
1369             Color interiorColor = background;
1370 
1371             // Set up colors per RadioButtonModel condition
1372             if ( !model.isEnabled() ) {
1373                 whiteInnerLeftArc = whiteOuterRightArc = background;
1374                 darkCircle = dotColor = shadow;
1375             }
1376             else if (model.isPressed() && model.isArmed() ) {
1377                 whiteInnerLeftArc = interiorColor = shadow;
1378             }
1379 
1380             g.translate(x, y);
1381 
1382             // fill interior
1383             if (c.isOpaque()) {
1384                 g.setColor(interiorColor);
1385                 g.fillRect(2, 2, 9, 9);
1386             }
1387 
1388             // draw Dark Circle (start at top, go clockwise)
1389             g.setColor(darkCircle);
1390             g.drawLine( 4, 0,  7, 0);
1391             g.drawLine( 8, 1,  9, 1);
1392             g.drawLine(10, 2, 10, 3);
1393             g.drawLine(11, 4, 11, 7);
1394             g.drawLine(10, 8, 10, 9);
1395             g.drawLine( 9,10,  8,10);
1396             g.drawLine( 7,11,  4,11);
1397             g.drawLine( 3,10,  2,10);
1398             g.drawLine( 1, 9,  1, 8);
1399             g.drawLine( 0, 7,  0, 4);
1400             g.drawLine( 1, 3,  1, 2);
1401             g.drawLine( 2, 1,  3, 1);
1402 
1403             // draw Inner Left (usually) White Arc
1404             //  start at lower left corner, go clockwise
1405             g.setColor(whiteInnerLeftArc);
1406             g.drawLine( 2, 9,  2, 8);
1407             g.drawLine( 1, 7,  1, 4);
1408             g.drawLine( 2, 2,  2, 3);
1409             g.drawLine( 2, 2,  3, 2);
1410             g.drawLine( 4, 1,  7, 1);
1411             g.drawLine( 8, 2,  9, 2);
1412             // draw Outer Right White Arc
1413             //  start at upper right corner, go clockwise
1414             g.setColor(whiteOuterRightArc);
1415             g.drawLine(10, 1, 10, 1);
1416             g.drawLine(11, 2, 11, 3);
1417             g.drawLine(12, 4, 12, 7);
1418             g.drawLine(11, 8, 11, 9);
1419             g.drawLine(10,10, 10,10);
1420             g.drawLine( 9,11,  8,11);
1421             g.drawLine( 7,12,  4,12);
1422             g.drawLine( 3,11,  2,11);
1423 
1424             // selected dot
1425             if ( drawDot ) {
1426                 g.setColor(dotColor);
1427                 g.fillRect( 4, 4,  4, 4);
1428                 g.drawLine( 4, 3,  7, 3);
1429                 g.drawLine( 8, 4,  8, 7);
1430                 g.drawLine( 7, 8,  4, 8);
1431                 g.drawLine( 3, 7,  3, 4);
1432             }
1433 
1434             g.translate(-x, -y);
1435         }
1436 
1437         public int getIconWidth() {
1438             return 13;
1439         }
1440 
1441         public int getIconHeight() {
1442             return 13;
1443         }
1444     }  // End class RadioButtonIcon
1445 
1446     // Tree Computer Icon code
1447     private static class TreeComputerIcon implements Icon, UIResource, Serializable {
1448         public void paintIcon(Component c, Graphics g, int x, int y) {
1449             g.translate(x, y);
1450 
1451             // Fill glass portion of monitor
1452             g.setColor(MetalLookAndFeel.getPrimaryControl());
1453             g.fillRect(5,4, 6,4);
1454 
1455             // Draw outside edge of monitor
1456             g.setColor(MetalLookAndFeel.getPrimaryControlInfo());
1457             g.drawLine( 2,2,  2,8); // left
1458             g.drawLine(13,2, 13,8); // right
1459             g.drawLine( 3,1, 12,1); // top
1460             g.drawLine(12,9, 12,9); // bottom right base
1461             g.drawLine( 3,9,  3,9); // bottom left base
1462             // Draw the edge of the glass
1463             g.drawLine( 4,4,  4,7); // left
1464             g.drawLine( 5,3, 10,3); // top
1465             g.drawLine(11,4, 11,7); // right
1466             g.drawLine( 5,8, 10,8); // bottom
1467             // Draw the edge of the CPU
1468             g.drawLine( 1,10, 14,10); // top
1469             g.drawLine(14,10, 14,14); // right
1470             g.drawLine( 1,14, 14,14); // bottom
1471             g.drawLine( 1,10,  1,14); // left
1472 
1473             // Draw the disk drives
1474             g.setColor(MetalLookAndFeel.getControlDarkShadow());
1475             g.drawLine( 6,12,  8,12); // left
1476             g.drawLine(10,12, 12,12); // right
1477 
1478             g.translate(-x, -y);
1479         }
1480 
1481         public int getIconWidth() {
1482             return 16;
1483         }
1484 
1485         public int getIconHeight() {
1486             return 16;
1487         }
1488     }  // End class TreeComputerIcon
1489 
1490     // Tree HardDrive Icon code
1491     private static class TreeHardDriveIcon implements Icon, UIResource, Serializable {
1492         public void paintIcon(Component c, Graphics g, int x, int y) {
1493             g.translate(x, y);
1494 
1495             // Draw edges of the disks
1496             g.setColor(MetalLookAndFeel.getPrimaryControlInfo());
1497             //     top disk
1498             g.drawLine(1,4, 1,5); // left
1499             g.drawLine(2,3, 3,3);
1500             g.drawLine(4,2, 11,2); // top
1501             g.drawLine(12,3, 13,3);
1502             g.drawLine(14,4, 14,5); // right
1503             g.drawLine(12,6, 13,6);
1504             g.drawLine(4,7, 11,7); // bottom
1505             g.drawLine(2,6, 3,6);
1506             //     middle disk
1507             g.drawLine(1,7, 1,8); // left
1508             g.drawLine(2,9, 3,9);
1509             g.drawLine(4,10, 11,10); // bottom
1510             g.drawLine(12,9, 13,9);
1511             g.drawLine(14,7, 14, 8); // right
1512             //     bottom disk
1513             g.drawLine(1,10, 1,11); // left
1514             g.drawLine(2,12, 3,12);
1515             g.drawLine(4,13, 11,13); // bottom
1516             g.drawLine(12,12, 13,12);
1517             g.drawLine(14,10, 14,11); // right
1518 
1519             // Draw the down right shadows
1520             g.setColor(MetalLookAndFeel.getControlShadow());
1521             //     top disk
1522             g.drawLine(7,6, 7,6);
1523             g.drawLine(9,6, 9,6);
1524             g.drawLine(10,5, 10,5);
1525             g.drawLine(11,6, 11,6);
1526             g.drawLine(12,5, 13,5);
1527             g.drawLine(13,4, 13,4);
1528             //     middle disk
1529             g.drawLine(7,9, 7,9);
1530             g.drawLine(9,9, 9,9);
1531             g.drawLine(10,8, 10,8);
1532             g.drawLine(11,9, 11,9);
1533             g.drawLine(12,8, 13,8);
1534             g.drawLine(13,7, 13,7);
1535             //     bottom disk
1536             g.drawLine(7,12, 7,12);
1537             g.drawLine(9,12, 9,12);
1538             g.drawLine(10,11, 10,11);
1539             g.drawLine(11,12, 11,12);
1540             g.drawLine(12,11, 13,11);
1541             g.drawLine(13,10, 13,10);
1542 
1543             // Draw the up left highlight
1544             g.setColor(MetalLookAndFeel.getControlHighlight());
1545             //     top disk
1546             g.drawLine(4,3, 5,3);
1547             g.drawLine(7,3, 9,3);
1548             g.drawLine(11,3, 11,3);
1549             g.drawLine(2,4, 6,4);
1550             g.drawLine(8,4, 8,4);
1551             g.drawLine(2,5, 3,5);
1552             g.drawLine(4,6, 4,6);
1553             //     middle disk
1554             g.drawLine(2,7, 3,7);
1555             g.drawLine(2,8, 3,8);
1556             g.drawLine(4,9, 4,9);
1557             //     bottom disk
1558             g.drawLine(2,10, 3,10);
1559             g.drawLine(2,11, 3,11);
1560             g.drawLine(4,12, 4,12);
1561 
1562             g.translate(-x, -y);
1563         }
1564 
1565         public int getIconWidth() {
1566             return 16;
1567         }
1568 
1569         public int getIconHeight() {
1570             return 16;
1571         }
1572     }  // End class TreeHardDriveIcon
1573 
1574     // Tree FloppyDrive Icon code
1575     private static class TreeFloppyDriveIcon implements Icon, UIResource, Serializable {
1576         public void paintIcon(Component c, Graphics g, int x, int y) {
1577             g.translate(x, y);
1578 
1579             // Fill body of floppy
1580             g.setColor(MetalLookAndFeel.getPrimaryControl());
1581             g.fillRect(2,2, 12,12);
1582 
1583             // Draw outside edge of floppy
1584             g.setColor(MetalLookAndFeel.getPrimaryControlInfo());
1585             g.drawLine( 1, 1, 13, 1); // top
1586             g.drawLine(14, 2, 14,14); // right
1587             g.drawLine( 1,14, 14,14); // bottom
1588             g.drawLine( 1, 1,  1,14); // left
1589 
1590             // Draw grey-ish highlights
1591             g.setColor(MetalLookAndFeel.getControlDarkShadow());
1592             g.fillRect(5,2, 6,5); // metal disk protector part
1593             g.drawLine(4,8, 11,8); // top of label
1594             g.drawLine(3,9, 3,13); // left of label
1595             g.drawLine(12,9, 12,13); // right of label
1596 
1597             // Draw label and exposed disk
1598             g.setColor(MetalLookAndFeel.getPrimaryControlHighlight());
1599             g.fillRect(8,3, 2,3); // exposed disk
1600             g.fillRect(4,9, 8,5); // label
1601 
1602             // Draw text on label
1603             g.setColor(MetalLookAndFeel.getPrimaryControlShadow());
1604             g.drawLine(5,10, 9,10);
1605             g.drawLine(5,12, 8,12);
1606 
1607             g.translate(-x, -y);
1608         }
1609 
1610         public int getIconWidth() {
1611             return 16;
1612         }
1613 
1614         public int getIconHeight() {
1615             return 16;
1616         }
1617     }  // End class TreeFloppyDriveIcon
1618 
1619 
1620     static private final Dimension folderIcon16Size = new Dimension( 16, 16 );
1621 
1622     /**
1623      * Utility class for caching icon images.  This is necessary because
1624      * we need a new image whenever we are rendering into a new
1625      * GraphicsConfiguration, but we do not want to keep recreating icon
1626      * images for GC's that we have already seen (for example,
1627      * dragging a window back and forth between monitors on a multimon
1628      * system, or drawing an icon to different Components that have different
1629      * GC's).
1630      * So now whenever we create a new icon image for a given GC, we
1631      * cache that image with the GC for later retrieval.
1632      */
1633     static class ImageCacher {
1634 
1635         // PENDING: Replace this class with CachedPainter.
1636 
1637         Vector<ImageGcPair> images = new Vector<ImageGcPair>(1, 1);
1638         ImageGcPair currentImageGcPair;
1639 
1640         class ImageGcPair {
1641             Image image;
1642             GraphicsConfiguration gc;
1643             ImageGcPair(Image image, GraphicsConfiguration gc) {
1644                 this.image = image;
1645                 this.gc = gc;
1646             }
1647 
1648             boolean hasSameConfiguration(GraphicsConfiguration newGC) {
1649                 return ((newGC != null) && (newGC.equals(gc))) ||
1650                         ((newGC == null) && (gc == null));
1651             }
1652 
1653         }
1654 
1655         Image getImage(GraphicsConfiguration newGC) {
1656             if ((currentImageGcPair == null) ||
1657                 !(currentImageGcPair.hasSameConfiguration(newGC)))
1658             {
1659                 for (ImageGcPair imgGcPair : images) {
1660                     if (imgGcPair.hasSameConfiguration(newGC)) {
1661                         currentImageGcPair = imgGcPair;
1662                         return imgGcPair.image;
1663                     }
1664                 }
1665                 return null;
1666             }
1667             return currentImageGcPair.image;
1668         }
1669 
1670         void cacheImage(Image image, GraphicsConfiguration gc) {
1671             ImageGcPair imgGcPair = new ImageGcPair(image, gc);
1672             images.addElement(imgGcPair);
1673             currentImageGcPair = imgGcPair;
1674         }
1675 
1676     }
1677 
1678     /**
1679      * <p>
1680      * <strong>Warning:</strong>
1681      * Serialized objects of this class will not be compatible with
1682      * future Swing releases. The current serialization support is
1683      * appropriate for short term storage or RMI between applications running
1684      * the same version of Swing.  As of 1.4, support for long term storage
1685      * of all JavaBeans&trade;
1686      * has been added to the <code>java.beans</code> package.
1687      * Please see {@link java.beans.XMLEncoder}.
1688      */
1689     @SuppressWarnings("serial") // Same-version serialization only
1690     public static class FolderIcon16 implements Icon, Serializable {
1691 
1692         ImageCacher imageCacher;
1693 
1694         public void paintIcon(Component c, Graphics g, int x, int y) {
1695             GraphicsConfiguration gc = c.getGraphicsConfiguration();
1696             if (imageCacher == null) {
1697                 imageCacher = new ImageCacher();
1698             }
1699             Image image = imageCacher.getImage(gc);
1700             if (image == null) {
1701                 if (gc != null) {
1702                     image = gc.createCompatibleImage(getIconWidth(),
1703                                                      getIconHeight(),
1704                                                      Transparency.BITMASK);
1705                 } else {
1706                     image = new BufferedImage(getIconWidth(),
1707                                               getIconHeight(),
1708                                               BufferedImage.TYPE_INT_ARGB);
1709                 }
1710                 Graphics imageG = image.getGraphics();
1711                 paintMe(c,imageG);
1712                 imageG.dispose();
1713                 imageCacher.cacheImage(image, gc);
1714             }
1715             g.drawImage(image, x, y+getShift(), null);
1716         }
1717 
1718 
1719         private void paintMe(Component c, Graphics g) {
1720 
1721             int right = folderIcon16Size.width - 1;
1722             int bottom = folderIcon16Size.height - 1;
1723 
1724             // Draw tab top
1725             g.setColor( MetalLookAndFeel.getPrimaryControlDarkShadow() );
1726             g.drawLine( right - 5, 3, right, 3 );
1727             g.drawLine( right - 6, 4, right, 4 );
1728 
1729             // Draw folder front
1730             g.setColor( MetalLookAndFeel.getPrimaryControl() );
1731             g.fillRect( 2, 7, 13, 8 );
1732 
1733             // Draw tab bottom
1734             g.setColor( MetalLookAndFeel.getPrimaryControlShadow() );
1735             g.drawLine( right - 6, 5, right - 1, 5 );
1736 
1737             // Draw outline
1738             g.setColor( MetalLookAndFeel.getPrimaryControlInfo() );
1739             g.drawLine( 0, 6, 0, bottom );            // left side
1740             g.drawLine( 1, 5, right - 7, 5 );         // first part of top
1741             g.drawLine( right - 6, 6, right - 1, 6 ); // second part of top
1742             g.drawLine( right, 5, right, bottom );    // right side
1743             g.drawLine( 0, bottom, right, bottom );   // bottom
1744 
1745             // Draw highlight
1746             g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() );
1747             g.drawLine( 1, 6, 1, bottom - 1 );
1748             g.drawLine( 1, 6, right - 7, 6 );
1749             g.drawLine( right - 6, 7, right - 1, 7 );
1750 
1751         }
1752 
1753         /**
1754          * Returns a shift of the icon.
1755          *
1756          * @return a shift of the icon
1757          */
1758         public int getShift() { return 0; }
1759 
1760         /**
1761          * Returns an additional height of the icon.
1762          *
1763          * @return an additional height of the icon
1764          */
1765         public int getAdditionalHeight() { return 0; }
1766 
1767         public int getIconWidth() { return folderIcon16Size.width; }
1768         public int getIconHeight() { return folderIcon16Size.height + getAdditionalHeight(); }
1769     }
1770 
1771 
1772     /**
1773      * <p>
1774      * <strong>Warning:</strong>
1775      * Serialized objects of this class will not be compatible with
1776      * future Swing releases. The current serialization support is
1777      * appropriate for short term storage or RMI between applications running
1778      * the same version of Swing.  As of 1.4, support for long term storage
1779      * of all JavaBeans&trade;
1780      * has been added to the <code>java.beans</code> package.
1781      * Please see {@link java.beans.XMLEncoder}.
1782      */
1783     @SuppressWarnings("serial") // Same-version serialization only
1784     public static class TreeFolderIcon extends FolderIcon16 {
1785         public int getShift() { return -1; }
1786         public int getAdditionalHeight() { return 2; }
1787     }
1788 
1789 
1790     static private final Dimension fileIcon16Size = new Dimension( 16, 16 );
1791 
1792     /**
1793      * <p>
1794      * <strong>Warning:</strong>
1795      * Serialized objects of this class will not be compatible with
1796      * future Swing releases. The current serialization support is
1797      * appropriate for short term storage or RMI between applications running
1798      * the same version of Swing.  As of 1.4, support for long term storage
1799      * of all JavaBeans&trade;
1800      * has been added to the <code>java.beans</code> package.
1801      * Please see {@link java.beans.XMLEncoder}.
1802      */
1803     @SuppressWarnings("serial") // Same-version serialization only
1804     public static class FileIcon16 implements Icon, Serializable {
1805 
1806         ImageCacher imageCacher;
1807 
1808         public void paintIcon(Component c, Graphics g, int x, int y) {
1809             GraphicsConfiguration gc = c.getGraphicsConfiguration();
1810             if (imageCacher == null) {
1811                 imageCacher = new ImageCacher();
1812             }
1813             Image image = imageCacher.getImage(gc);
1814             if (image == null) {
1815                 if (gc != null) {
1816                     image = gc.createCompatibleImage(getIconWidth(),
1817                                                      getIconHeight(),
1818                                                      Transparency.BITMASK);
1819                 } else {
1820                     image = new BufferedImage(getIconWidth(),
1821                                               getIconHeight(),
1822                                               BufferedImage.TYPE_INT_ARGB);
1823                 }
1824                 Graphics imageG = image.getGraphics();
1825                 paintMe(c,imageG);
1826                 imageG.dispose();
1827                 imageCacher.cacheImage(image, gc);
1828             }
1829             g.drawImage(image, x, y+getShift(), null);
1830         }
1831 
1832         private void paintMe(Component c, Graphics g) {
1833 
1834                 int right = fileIcon16Size.width - 1;
1835                 int bottom = fileIcon16Size.height - 1;
1836 
1837                 // Draw fill
1838                 g.setColor( MetalLookAndFeel.getWindowBackground() );
1839                 g.fillRect( 4, 2, 9, 12 );
1840 
1841                 // Draw frame
1842                 g.setColor( MetalLookAndFeel.getPrimaryControlInfo() );
1843                 g.drawLine( 2, 0, 2, bottom );                 // left
1844                 g.drawLine( 2, 0, right - 4, 0 );              // top
1845                 g.drawLine( 2, bottom, right - 1, bottom );    // bottom
1846                 g.drawLine( right - 1, 6, right - 1, bottom ); // right
1847                 g.drawLine( right - 6, 2, right - 2, 6 );      // slant 1
1848                 g.drawLine( right - 5, 1, right - 4, 1 );      // part of slant 2
1849                 g.drawLine( right - 3, 2, right - 3, 3 );      // part of slant 2
1850                 g.drawLine( right - 2, 4, right - 2, 5 );      // part of slant 2
1851 
1852                 // Draw highlight
1853                 g.setColor( MetalLookAndFeel.getPrimaryControl() );
1854                 g.drawLine( 3, 1, 3, bottom - 1 );                  // left
1855                 g.drawLine( 3, 1, right - 6, 1 );                   // top
1856                 g.drawLine( right - 2, 7, right - 2, bottom - 1 );  // right
1857                 g.drawLine( right - 5, 2, right - 3, 4 );           // slant
1858                 g.drawLine( 3, bottom - 1, right - 2, bottom - 1 ); // bottom
1859 
1860         }
1861 
1862         /**
1863          * Returns a shift of the icon.
1864          *
1865          * @return a shift of the icon
1866          */
1867         public int getShift() { return 0; }
1868 
1869         /**
1870          * Returns an additional height of the icon.
1871          *
1872          * @return an additional height of the icon
1873          */
1874         public int getAdditionalHeight() { return 0; }
1875 
1876         public int getIconWidth() { return fileIcon16Size.width; }
1877         public int getIconHeight() { return fileIcon16Size.height + getAdditionalHeight(); }
1878     }
1879 
1880 
1881     /**
1882      * The class represents a tree leaf icon.
1883      */
1884     public static class TreeLeafIcon extends FileIcon16 {
1885         public int getShift() { return 2; }
1886         public int getAdditionalHeight() { return 4; }
1887     }
1888 
1889 
1890     static private final Dimension treeControlSize = new Dimension( 18, 18 );
1891 
1892     /**
1893      * <p>
1894      * <strong>Warning:</strong>
1895      * Serialized objects of this class will not be compatible with
1896      * future Swing releases. The current serialization support is
1897      * appropriate for short term storage or RMI between applications running
1898      * the same version of Swing.  As of 1.4, support for long term storage
1899      * of all JavaBeans&trade;
1900      * has been added to the <code>java.beans</code> package.
1901      * Please see {@link java.beans.XMLEncoder}.
1902      */
1903     @SuppressWarnings("serial") // Same-version serialization only
1904     public static class TreeControlIcon implements Icon, Serializable {
1905 
1906         /**
1907          * if {@code true} the icon is collapsed.
1908          * NOTE: This data member should not have been exposed. It's called
1909          * {@code isLight}, but now it really means {@code isCollapsed}.
1910          * Since we can't change any APIs... that's life.
1911          */
1912         protected boolean isLight;
1913 
1914         /**
1915          * Constructs an instance of {@code TreeControlIcon}.
1916          *
1917          * @param isCollapsed if {@code true} the icon is collapsed
1918          */
1919         public TreeControlIcon( boolean isCollapsed ) {
1920             isLight = isCollapsed;
1921         }
1922 
1923         ImageCacher imageCacher;
1924 
1925         transient boolean cachedOrientation = true;
1926 
1927         public void paintIcon(Component c, Graphics g, int x, int y) {
1928 
1929             GraphicsConfiguration gc = c.getGraphicsConfiguration();
1930 
1931             if (imageCacher == null) {
1932                 imageCacher = new ImageCacher();
1933             }
1934             Image image = imageCacher.getImage(gc);
1935 
1936             if (image == null || cachedOrientation != MetalUtils.isLeftToRight(c)) {
1937                 cachedOrientation = MetalUtils.isLeftToRight(c);
1938                 if (gc != null) {
1939                     image = gc.createCompatibleImage(getIconWidth(),
1940                                                      getIconHeight(),
1941                                                      Transparency.BITMASK);
1942                 } else {
1943                     image = new BufferedImage(getIconWidth(),
1944                                               getIconHeight(),
1945                                               BufferedImage.TYPE_INT_ARGB);
1946                 }
1947                 Graphics imageG = image.getGraphics();
1948                 paintMe(c,imageG,x,y);
1949                 imageG.dispose();
1950                 imageCacher.cacheImage(image, gc);
1951 
1952             }
1953 
1954             if (MetalUtils.isLeftToRight(c)) {
1955                 if (isLight) {    // isCollapsed
1956                     g.drawImage(image, x+5, y+3, x+18, y+13,
1957                                        4,3, 17, 13, null);
1958                 }
1959                 else {
1960                     g.drawImage(image, x+5, y+3, x+18, y+17,
1961                                        4,3, 17, 17, null);
1962                 }
1963             }
1964             else {
1965                 if (isLight) {    // isCollapsed
1966                     g.drawImage(image, x+3, y+3, x+16, y+13,
1967                                        4, 3, 17, 13, null);
1968                 }
1969                 else {
1970                     g.drawImage(image, x+3, y+3, x+16, y+17,
1971                                        4, 3, 17, 17, null);
1972                 }
1973             }
1974         }
1975 
1976         /**
1977          * Paints the {@code TreeControlIcon}.
1978          *
1979          * @param c a component
1980          * @param g an instance of {@code Graphics}
1981          * @param x an X coordinate
1982          * @param y an Y coordinate
1983          */
1984         public void paintMe(Component c, Graphics g, int x, int y) {
1985 
1986             g.setColor( MetalLookAndFeel.getPrimaryControlInfo() );
1987 
1988             int xoff = (MetalUtils.isLeftToRight(c)) ? 0 : 4;
1989 
1990             // Draw circle
1991             g.drawLine( xoff + 4, 6, xoff + 4, 9 );     // left
1992             g.drawLine( xoff + 5, 5, xoff + 5, 5 );     // top left dot
1993             g.drawLine( xoff + 6, 4, xoff + 9, 4 );     // top
1994             g.drawLine( xoff + 10, 5, xoff + 10, 5 );   // top right dot
1995             g.drawLine( xoff + 11, 6, xoff + 11, 9 );   // right
1996             g.drawLine( xoff + 10, 10, xoff + 10, 10 ); // bottom right dot
1997             g.drawLine( xoff + 6, 11, xoff + 9, 11 );   // bottom
1998             g.drawLine( xoff + 5, 10, xoff + 5, 10 );   // bottom left dot
1999 
2000             // Draw Center Dot
2001             g.drawLine( xoff + 7, 7, xoff + 8, 7 );
2002             g.drawLine( xoff + 7, 8, xoff + 8, 8 );
2003 
2004             // Draw Handle
2005             if ( isLight ) {    // isCollapsed
2006                 if( MetalUtils.isLeftToRight(c) ) {
2007                     g.drawLine( 12, 7, 15, 7 );
2008                     g.drawLine( 12, 8, 15, 8 );
2009                     //  g.setColor( c.getBackground() );
2010                     //  g.drawLine( 16, 7, 16, 8 );
2011                 }
2012                 else {
2013                     g.drawLine(4, 7, 7, 7);
2014                     g.drawLine(4, 8, 7, 8);
2015                 }
2016             }
2017             else {
2018                 g.drawLine( xoff + 7, 12, xoff + 7, 15 );
2019                 g.drawLine( xoff + 8, 12, xoff + 8, 15 );
2020                 //      g.setColor( c.getBackground() );
2021                 //      g.drawLine( xoff + 7, 16, xoff + 8, 16 );
2022             }
2023 
2024             // Draw Fill
2025             g.setColor( MetalLookAndFeel.getPrimaryControlDarkShadow() );
2026             g.drawLine( xoff + 5, 6, xoff + 5, 9 );      // left shadow
2027             g.drawLine( xoff + 6, 5, xoff + 9, 5 );      // top shadow
2028 
2029             g.setColor( MetalLookAndFeel.getPrimaryControlShadow() );
2030             g.drawLine( xoff + 6, 6, xoff + 6, 6 );      // top left fill
2031             g.drawLine( xoff + 9, 6, xoff + 9, 6 );      // top right fill
2032             g.drawLine( xoff + 6, 9, xoff + 6, 9 );      // bottom left fill
2033             g.drawLine( xoff + 10, 6, xoff + 10, 9 );    // right fill
2034             g.drawLine( xoff + 6, 10, xoff + 9, 10 );    // bottom fill
2035 
2036             g.setColor( MetalLookAndFeel.getPrimaryControl() );
2037             g.drawLine( xoff + 6, 7, xoff + 6, 8 );      // left highlight
2038             g.drawLine( xoff + 7, 6, xoff + 8, 6 );      // top highlight
2039             g.drawLine( xoff + 9, 7, xoff + 9, 7 );      // right highlight
2040             g.drawLine( xoff + 7, 9, xoff + 7, 9 );      // bottom highlight
2041 
2042             g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() );
2043             g.drawLine( xoff + 8, 9, xoff + 9, 9 );
2044             g.drawLine( xoff + 9, 8, xoff + 9, 8 );
2045         }
2046 
2047         public int getIconWidth() { return treeControlSize.width; }
2048         public int getIconHeight() { return treeControlSize.height; }
2049     }
2050 
2051   //
2052   // Menu Icons
2053   //
2054 
2055     static private final Dimension menuArrowIconSize = new Dimension( 4, 8 );
2056     static private final Dimension menuCheckIconSize = new Dimension( 10, 10 );
2057     static private final int xOff = 4;
2058 
2059     private static class MenuArrowIcon implements Icon, UIResource, Serializable
2060     {
2061         public void paintIcon( Component c, Graphics g, int x, int y )
2062         {
2063             JMenuItem b = (JMenuItem) c;
2064             ButtonModel model = b.getModel();
2065 
2066             g.translate( x, y );
2067 
2068             if ( !model.isEnabled() )
2069             {
2070                 g.setColor( MetalLookAndFeel.getMenuDisabledForeground() );
2071             }
2072             else
2073             {
2074                 if ( model.isArmed() || ( c instanceof JMenu && model.isSelected() ) )
2075                 {
2076                     g.setColor( MetalLookAndFeel.getMenuSelectedForeground() );
2077                 }
2078                 else
2079                 {
2080                     g.setColor( b.getForeground() );
2081                 }
2082             }
2083             if( MetalUtils.isLeftToRight(b) ) {
2084                 g.drawLine( 0, 0, 0, 7 );
2085                 g.drawLine( 1, 1, 1, 6 );
2086                 g.drawLine( 2, 2, 2, 5 );
2087                 g.drawLine( 3, 3, 3, 4 );
2088             } else {
2089                 g.drawLine( 4, 0, 4, 7 );
2090                 g.drawLine( 3, 1, 3, 6 );
2091                 g.drawLine( 2, 2, 2, 5 );
2092                 g.drawLine( 1, 3, 1, 4 );
2093             }
2094 
2095             g.translate( -x, -y );
2096         }
2097 
2098         public int getIconWidth() { return menuArrowIconSize.width; }
2099 
2100         public int getIconHeight() { return menuArrowIconSize.height; }
2101 
2102     } // End class MenuArrowIcon
2103 
2104     private static class MenuItemArrowIcon implements Icon, UIResource, Serializable
2105     {
2106         public void paintIcon( Component c, Graphics g, int x, int y )
2107         {
2108         }
2109 
2110         public int getIconWidth() { return menuArrowIconSize.width; }
2111 
2112         public int getIconHeight() { return menuArrowIconSize.height; }
2113 
2114     } // End class MenuItemArrowIcon
2115 
2116     private static class CheckBoxMenuItemIcon implements Icon, UIResource, Serializable
2117     {
2118         public void paintOceanIcon(Component c, Graphics g, int x, int y) {
2119             ButtonModel model = ((JMenuItem)c).getModel();
2120             boolean isSelected = model.isSelected();
2121             boolean isEnabled = model.isEnabled();
2122             boolean isPressed = model.isPressed();
2123             boolean isArmed = model.isArmed();
2124 
2125             g.translate(x, y);
2126             if (isEnabled) {
2127                 MetalUtils.drawGradient(c, g, "CheckBoxMenuItem.gradient",
2128                                         1, 1, 7, 7, true);
2129                 if (isPressed || isArmed) {
2130                     g.setColor(MetalLookAndFeel.getControlInfo());
2131                     g.drawLine( 0, 0, 8, 0 );
2132                     g.drawLine( 0, 0, 0, 8 );
2133                     g.drawLine( 8, 2, 8, 8 );
2134                     g.drawLine( 2, 8, 8, 8 );
2135 
2136                     g.setColor(MetalLookAndFeel.getPrimaryControl());
2137                     g.drawLine( 9, 1, 9, 9 );
2138                     g.drawLine( 1, 9, 9, 9 );
2139                 }
2140                 else {
2141                     g.setColor(MetalLookAndFeel.getControlDarkShadow());
2142                     g.drawLine( 0, 0, 8, 0 );
2143                     g.drawLine( 0, 0, 0, 8 );
2144                     g.drawLine( 8, 2, 8, 8 );
2145                     g.drawLine( 2, 8, 8, 8 );
2146 
2147                     g.setColor(MetalLookAndFeel.getControlHighlight());
2148                     g.drawLine( 9, 1, 9, 9 );
2149                     g.drawLine( 1, 9, 9, 9 );
2150                 }
2151             }
2152             else {
2153                 g.setColor(MetalLookAndFeel.getMenuDisabledForeground());
2154                 g.drawRect( 0, 0, 8, 8 );
2155             }
2156             if (isSelected) {
2157                 if (isEnabled) {
2158                     if (isArmed || ( c instanceof JMenu && isSelected)) {
2159                         g.setColor(
2160                             MetalLookAndFeel.getMenuSelectedForeground() );
2161                     }
2162                     else {
2163                          g.setColor(MetalLookAndFeel.getControlInfo());
2164                     }
2165                 }
2166                 else {
2167                     g.setColor( MetalLookAndFeel.getMenuDisabledForeground());
2168                 }
2169 
2170                 g.drawLine( 2, 2, 2, 6 );
2171                 g.drawLine( 3, 2, 3, 6 );
2172                 g.drawLine( 4, 4, 8, 0 );
2173                 g.drawLine( 4, 5, 9, 0 );
2174             }
2175             g.translate( -x, -y );
2176         }
2177 
2178         public void paintIcon( Component c, Graphics g, int x, int y )
2179         {
2180             if (MetalLookAndFeel.usingOcean()) {
2181                 paintOceanIcon(c, g, x, y);
2182                 return;
2183             }
2184             JMenuItem b = (JMenuItem) c;
2185             ButtonModel model = b.getModel();
2186 
2187             boolean isSelected = model.isSelected();
2188             boolean isEnabled = model.isEnabled();
2189             boolean isPressed = model.isPressed();
2190             boolean isArmed = model.isArmed();
2191 
2192             g.translate( x, y );
2193 
2194             if ( isEnabled )
2195             {
2196                 if ( isPressed || isArmed )
2197                 {
2198                     g.setColor( MetalLookAndFeel.getControlInfo()  );
2199                     g.drawLine( 0, 0, 8, 0 );
2200                     g.drawLine( 0, 0, 0, 8 );
2201                     g.drawLine( 8, 2, 8, 8 );
2202                     g.drawLine( 2, 8, 8, 8 );
2203 
2204                     g.setColor( MetalLookAndFeel.getPrimaryControl()  );
2205                     g.drawLine( 1, 1, 7, 1 );
2206                     g.drawLine( 1, 1, 1, 7 );
2207                     g.drawLine( 9, 1, 9, 9 );
2208                     g.drawLine( 1, 9, 9, 9 );
2209                 }
2210                 else
2211                 {
2212                     g.setColor( MetalLookAndFeel.getControlDarkShadow()  );
2213                     g.drawLine( 0, 0, 8, 0 );
2214                     g.drawLine( 0, 0, 0, 8 );
2215                     g.drawLine( 8, 2, 8, 8 );
2216                     g.drawLine( 2, 8, 8, 8 );
2217 
2218                     g.setColor( MetalLookAndFeel.getControlHighlight()  );
2219                     g.drawLine( 1, 1, 7, 1 );
2220                     g.drawLine( 1, 1, 1, 7 );
2221                     g.drawLine( 9, 1, 9, 9 );
2222                     g.drawLine( 1, 9, 9, 9 );
2223                 }
2224             }
2225             else
2226             {
2227                 g.setColor( MetalLookAndFeel.getMenuDisabledForeground()  );
2228                 g.drawRect( 0, 0, 8, 8 );
2229             }
2230 
2231             if ( isSelected )
2232             {
2233                 if ( isEnabled )
2234                 {
2235                     if ( model.isArmed() || ( c instanceof JMenu && model.isSelected() ) )
2236                     {
2237                         g.setColor( MetalLookAndFeel.getMenuSelectedForeground() );
2238                     }
2239                     else
2240                     {
2241                         g.setColor( b.getForeground() );
2242                     }
2243                 }
2244                 else
2245                 {
2246                     g.setColor( MetalLookAndFeel.getMenuDisabledForeground()  );
2247                 }
2248 
2249                 g.drawLine( 2, 2, 2, 6 );
2250                 g.drawLine( 3, 2, 3, 6 );
2251                 g.drawLine( 4, 4, 8, 0 );
2252                 g.drawLine( 4, 5, 9, 0 );
2253             }
2254 
2255             g.translate( -x, -y );
2256         }
2257 
2258         public int getIconWidth() { return menuCheckIconSize.width; }
2259 
2260         public int getIconHeight() { return menuCheckIconSize.height; }
2261 
2262     }  // End class CheckBoxMenuItemIcon
2263 
2264     private static class RadioButtonMenuItemIcon implements Icon, UIResource, Serializable
2265     {
2266         public void paintOceanIcon(Component c, Graphics g, int x, int y) {
2267             ButtonModel model = ((JMenuItem)c).getModel();
2268             boolean isSelected = model.isSelected();
2269             boolean isEnabled = model.isEnabled();
2270             boolean isPressed = model.isPressed();
2271             boolean isArmed = model.isArmed();
2272 
2273             g.translate( x, y );
2274 
2275             if (isEnabled) {
2276                 MetalUtils.drawGradient(c, g, "RadioButtonMenuItem.gradient",
2277                                         1, 1, 7, 7, true);
2278                 if (isPressed || isArmed) {
2279                     g.setColor(MetalLookAndFeel.getPrimaryControl());
2280                 }
2281                 else {
2282                     g.setColor(MetalLookAndFeel.getControlHighlight());
2283                 }
2284                 g.drawLine( 2, 9, 7, 9 );
2285                 g.drawLine( 9, 2, 9, 7 );
2286                 g.drawLine( 8, 8, 8, 8 );
2287 
2288                 if (isPressed || isArmed) {
2289                     g.setColor(MetalLookAndFeel.getControlInfo());
2290                 }
2291                 else {
2292                     g.setColor(MetalLookAndFeel.getControlDarkShadow());
2293                 }
2294             }
2295             else {
2296                 g.setColor( MetalLookAndFeel.getMenuDisabledForeground()  );
2297             }
2298             g.drawLine( 2, 0, 6, 0 );
2299             g.drawLine( 2, 8, 6, 8 );
2300             g.drawLine( 0, 2, 0, 6 );
2301             g.drawLine( 8, 2, 8, 6 );
2302             g.drawLine( 1, 1, 1, 1 );
2303             g.drawLine( 7, 1, 7, 1 );
2304             g.drawLine( 1, 7, 1, 7 );
2305             g.drawLine( 7, 7, 7, 7 );
2306 
2307             if (isSelected) {
2308                 if (isEnabled) {
2309                     if (isArmed || (c instanceof JMenu && model.isSelected())){
2310                         g.setColor(MetalLookAndFeel.
2311                                    getMenuSelectedForeground() );
2312                     }
2313                     else {
2314                         g.setColor(MetalLookAndFeel.getControlInfo());
2315                     }
2316                 }
2317                 else {
2318                     g.setColor(MetalLookAndFeel.getMenuDisabledForeground());
2319                 }
2320                 g.drawLine( 3, 2, 5, 2 );
2321                 g.drawLine( 2, 3, 6, 3 );
2322                 g.drawLine( 2, 4, 6, 4 );
2323                 g.drawLine( 2, 5, 6, 5 );
2324                 g.drawLine( 3, 6, 5, 6 );
2325             }
2326 
2327             g.translate( -x, -y );
2328         }
2329 
2330         public void paintIcon( Component c, Graphics g, int x, int y )
2331         {
2332             if (MetalLookAndFeel.usingOcean()) {
2333                 paintOceanIcon(c, g, x, y);
2334                 return;
2335             }
2336             JMenuItem b = (JMenuItem) c;
2337             ButtonModel model = b.getModel();
2338 
2339             boolean isSelected = model.isSelected();
2340             boolean isEnabled = model.isEnabled();
2341             boolean isPressed = model.isPressed();
2342             boolean isArmed = model.isArmed();
2343 
2344             g.translate( x, y );
2345 
2346             if ( isEnabled )
2347             {
2348                 if ( isPressed || isArmed )
2349                 {
2350                     g.setColor( MetalLookAndFeel.getPrimaryControl()  );
2351                     g.drawLine( 3, 1, 8, 1 );
2352                     g.drawLine( 2, 9, 7, 9 );
2353                     g.drawLine( 1, 3, 1, 8 );
2354                     g.drawLine( 9, 2, 9, 7 );
2355                     g.drawLine( 2, 2, 2, 2 );
2356                     g.drawLine( 8, 8, 8, 8 );
2357 
2358                     g.setColor( MetalLookAndFeel.getControlInfo()  );
2359                     g.drawLine( 2, 0, 6, 0 );
2360                     g.drawLine( 2, 8, 6, 8 );
2361                     g.drawLine( 0, 2, 0, 6 );
2362                     g.drawLine( 8, 2, 8, 6 );
2363                     g.drawLine( 1, 1, 1, 1 );
2364                     g.drawLine( 7, 1, 7, 1 );
2365                     g.drawLine( 1, 7, 1, 7 );
2366                     g.drawLine( 7, 7, 7, 7 );
2367                 }
2368                 else
2369                 {
2370                     g.setColor( MetalLookAndFeel.getControlHighlight()  );
2371                     g.drawLine( 3, 1, 8, 1 );
2372                     g.drawLine( 2, 9, 7, 9 );
2373                     g.drawLine( 1, 3, 1, 8 );
2374                     g.drawLine( 9, 2, 9, 7 );
2375                     g.drawLine( 2, 2, 2, 2 );
2376                     g.drawLine( 8, 8, 8, 8 );
2377 
2378                     g.setColor( MetalLookAndFeel.getControlDarkShadow()  );
2379                     g.drawLine( 2, 0, 6, 0 );
2380                     g.drawLine( 2, 8, 6, 8 );
2381                     g.drawLine( 0, 2, 0, 6 );
2382                     g.drawLine( 8, 2, 8, 6 );
2383                     g.drawLine( 1, 1, 1, 1 );
2384                     g.drawLine( 7, 1, 7, 1 );
2385                     g.drawLine( 1, 7, 1, 7 );
2386                     g.drawLine( 7, 7, 7, 7 );
2387                 }
2388             }
2389             else
2390             {
2391                 g.setColor( MetalLookAndFeel.getMenuDisabledForeground()  );
2392                 g.drawLine( 2, 0, 6, 0 );
2393                 g.drawLine( 2, 8, 6, 8 );
2394                 g.drawLine( 0, 2, 0, 6 );
2395                 g.drawLine( 8, 2, 8, 6 );
2396                 g.drawLine( 1, 1, 1, 1 );
2397                 g.drawLine( 7, 1, 7, 1 );
2398                 g.drawLine( 1, 7, 1, 7 );
2399                 g.drawLine( 7, 7, 7, 7 );
2400             }
2401 
2402             if ( isSelected )
2403             {
2404                 if ( isEnabled )
2405                 {
2406                     if ( model.isArmed() || ( c instanceof JMenu && model.isSelected() ) )
2407                     {
2408                         g.setColor( MetalLookAndFeel.getMenuSelectedForeground() );
2409                     }
2410                     else
2411                     {
2412                         g.setColor( b.getForeground() );
2413                     }
2414                 }
2415                 else
2416                 {
2417                     g.setColor( MetalLookAndFeel.getMenuDisabledForeground()  );
2418                 }
2419 
2420                 g.drawLine( 3, 2, 5, 2 );
2421                 g.drawLine( 2, 3, 6, 3 );
2422                 g.drawLine( 2, 4, 6, 4 );
2423                 g.drawLine( 2, 5, 6, 5 );
2424                 g.drawLine( 3, 6, 5, 6 );
2425             }
2426 
2427             g.translate( -x, -y );
2428         }
2429 
2430         public int getIconWidth() { return menuCheckIconSize.width; }
2431 
2432         public int getIconHeight() { return menuCheckIconSize.height; }
2433 
2434     }  // End class RadioButtonMenuItemIcon
2435 
2436 private static class VerticalSliderThumbIcon implements Icon, Serializable, UIResource {
2437     protected static MetalBumps controlBumps;
2438     protected static MetalBumps primaryBumps;
2439 
2440     public VerticalSliderThumbIcon() {
2441         controlBumps = new MetalBumps( 6, 10,
2442                                 MetalLookAndFeel.getControlHighlight(),
2443                                 MetalLookAndFeel.getControlInfo(),
2444                                 MetalLookAndFeel.getControl() );
2445         primaryBumps = new MetalBumps( 6, 10,
2446                                 MetalLookAndFeel.getPrimaryControl(),
2447                                 MetalLookAndFeel.getPrimaryControlDarkShadow(),
2448                                 MetalLookAndFeel.getPrimaryControlShadow() );
2449     }
2450 
2451     public void paintIcon( Component c, Graphics g, int x, int y ) {
2452         boolean leftToRight = MetalUtils.isLeftToRight(c);
2453 
2454         g.translate( x, y );
2455 
2456         // Draw the frame
2457         if ( c.hasFocus() ) {
2458             g.setColor( MetalLookAndFeel.getPrimaryControlInfo() );
2459         }
2460         else {
2461             g.setColor( c.isEnabled() ? MetalLookAndFeel.getPrimaryControlInfo() :
2462                                              MetalLookAndFeel.getControlDarkShadow() );
2463         }
2464 
2465         if (leftToRight) {
2466             g.drawLine(  1,0  ,  8,0  ); // top
2467             g.drawLine(  0,1  ,  0,13 ); // left
2468             g.drawLine(  1,14 ,  8,14 ); // bottom
2469             g.drawLine(  9,1  , 15,7  ); // top slant
2470             g.drawLine(  9,13 , 15,7  ); // bottom slant
2471         }
2472         else {
2473             g.drawLine(  7,0  , 14,0  ); // top
2474             g.drawLine( 15,1  , 15,13 ); // right
2475             g.drawLine(  7,14 , 14,14 ); // bottom
2476             g.drawLine(  0,7  ,  6,1  ); // top slant
2477             g.drawLine(  0,7  ,  6,13 ); // bottom slant
2478         }
2479 
2480         // Fill in the background
2481         if ( c.hasFocus() ) {
2482             g.setColor( c.getForeground() );
2483         }
2484         else {
2485             g.setColor( MetalLookAndFeel.getControl() );
2486         }
2487 
2488         if (leftToRight) {
2489             g.fillRect(  1,1 ,  8,13 );
2490 
2491             g.drawLine(  9,2 ,  9,12 );
2492             g.drawLine( 10,3 , 10,11 );
2493             g.drawLine( 11,4 , 11,10 );
2494             g.drawLine( 12,5 , 12,9 );
2495             g.drawLine( 13,6 , 13,8 );
2496             g.drawLine( 14,7 , 14,7 );
2497         }
2498         else {
2499             g.fillRect(  7,1,   8,13 );
2500 
2501             g.drawLine(  6,3 ,  6,12 );
2502             g.drawLine(  5,4 ,  5,11 );
2503             g.drawLine(  4,5 ,  4,10 );
2504             g.drawLine(  3,6 ,  3,9 );
2505             g.drawLine(  2,7 ,  2,8 );
2506         }
2507 
2508         // Draw the bumps
2509         int offset = (leftToRight) ? 2 : 8;
2510         if ( c.isEnabled() ) {
2511             if ( c.hasFocus() ) {
2512                 primaryBumps.paintIcon( c, g, offset, 2 );
2513             }
2514             else {
2515                 controlBumps.paintIcon( c, g, offset, 2 );
2516             }
2517         }
2518 
2519         // Draw the highlight
2520         if ( c.isEnabled() ) {
2521             g.setColor( c.hasFocus() ? MetalLookAndFeel.getPrimaryControl()
2522                         : MetalLookAndFeel.getControlHighlight() );
2523             if (leftToRight) {
2524                 g.drawLine( 1, 1, 8, 1 );
2525                 g.drawLine( 1, 1, 1, 13 );
2526             }
2527             else {
2528                 g.drawLine(  8,1  , 14,1  ); // top
2529                 g.drawLine(  1,7  ,  7,1  ); // top slant
2530             }
2531         }
2532 
2533         g.translate( -x, -y );
2534     }
2535 
2536     public int getIconWidth() {
2537         return 16;
2538     }
2539 
2540     public int getIconHeight() {
2541         return 15;
2542     }
2543 }
2544 
2545 private static class HorizontalSliderThumbIcon implements Icon, Serializable, UIResource {
2546     protected static MetalBumps controlBumps;
2547     protected static MetalBumps primaryBumps;
2548 
2549     public HorizontalSliderThumbIcon() {
2550         controlBumps = new MetalBumps( 10, 6,
2551                                 MetalLookAndFeel.getControlHighlight(),
2552                                 MetalLookAndFeel.getControlInfo(),
2553                                 MetalLookAndFeel.getControl() );
2554         primaryBumps = new MetalBumps( 10, 6,
2555                                 MetalLookAndFeel.getPrimaryControl(),
2556                                 MetalLookAndFeel.getPrimaryControlDarkShadow(),
2557                                 MetalLookAndFeel.getPrimaryControlShadow() );
2558     }
2559 
2560     public void paintIcon( Component c, Graphics g, int x, int y ) {
2561         g.translate( x, y );
2562 
2563         // Draw the frame
2564         if ( c.hasFocus() ) {
2565             g.setColor( MetalLookAndFeel.getPrimaryControlInfo() );
2566         }
2567         else {
2568             g.setColor( c.isEnabled() ? MetalLookAndFeel.getPrimaryControlInfo() :
2569                                              MetalLookAndFeel.getControlDarkShadow() );
2570         }
2571 
2572         g.drawLine(  1,0  , 13,0 );  // top
2573         g.drawLine(  0,1  ,  0,8 );  // left
2574         g.drawLine( 14,1  , 14,8 );  // right
2575         g.drawLine(  1,9  ,  7,15 ); // left slant
2576         g.drawLine(  7,15 , 14,8 );  // right slant
2577 
2578         // Fill in the background
2579         if ( c.hasFocus() ) {
2580             g.setColor( c.getForeground() );
2581         }
2582         else {
2583             g.setColor( MetalLookAndFeel.getControl() );
2584         }
2585         g.fillRect( 1,1, 13, 8 );
2586 
2587         g.drawLine( 2,9  , 12,9 );
2588         g.drawLine( 3,10 , 11,10 );
2589         g.drawLine( 4,11 , 10,11 );
2590         g.drawLine( 5,12 ,  9,12 );
2591         g.drawLine( 6,13 ,  8,13 );
2592         g.drawLine( 7,14 ,  7,14 );
2593 
2594         // Draw the bumps
2595         if ( c.isEnabled() ) {
2596             if ( c.hasFocus() ) {
2597                 primaryBumps.paintIcon( c, g, 2, 2 );
2598             }
2599             else {
2600                 controlBumps.paintIcon( c, g, 2, 2 );
2601             }
2602         }
2603 
2604         // Draw the highlight
2605         if ( c.isEnabled() ) {
2606             g.setColor( c.hasFocus() ? MetalLookAndFeel.getPrimaryControl()
2607                         : MetalLookAndFeel.getControlHighlight() );
2608             g.drawLine( 1, 1, 13, 1 );
2609             g.drawLine( 1, 1, 1, 8 );
2610         }
2611 
2612         g.translate( -x, -y );
2613     }
2614 
2615     public int getIconWidth() {
2616         return 15;
2617     }
2618 
2619     public int getIconHeight() {
2620         return 16;
2621     }
2622 }
2623 
2624     private static class OceanVerticalSliderThumbIcon extends CachedPainter
2625                               implements Icon, Serializable, UIResource {
2626         // Used for clipping when the orientation is left to right
2627         private static Polygon LTR_THUMB_SHAPE;
2628         // Used for clipping when the orientation is right to left
2629         private static Polygon RTL_THUMB_SHAPE;
2630 
2631         static {
2632             LTR_THUMB_SHAPE = new Polygon(new int[] { 0,  8, 15,  8,  0},
2633                                           new int[] { 0,  0,  7, 14, 14 }, 5);
2634             RTL_THUMB_SHAPE = new Polygon(new int[] { 15, 15,  7,  0,  7},
2635                                           new int[] {  0, 14, 14,  7,  0}, 5);
2636         }
2637 
2638         OceanVerticalSliderThumbIcon() {
2639             super(3);
2640         }
2641 
2642         public void paintIcon(Component c, Graphics g, int x, int y) {
2643             if (!(g instanceof Graphics2D)) {
2644                 return;
2645             }
2646             paint(c, g, x, y, getIconWidth(), getIconHeight(),
2647                   MetalUtils.isLeftToRight(c), c.hasFocus(), c.isEnabled(),
2648                   MetalLookAndFeel.getCurrentTheme());
2649         }
2650 
2651         protected void paintToImage(Component c, Image image, Graphics g2,
2652                                     int w, int h, Object[] args) {
2653             Graphics2D g = (Graphics2D)g2;
2654             boolean leftToRight = ((Boolean)args[0]).booleanValue();
2655             boolean hasFocus = ((Boolean)args[1]).booleanValue();
2656             boolean enabled = ((Boolean)args[2]).booleanValue();
2657 
2658             Rectangle clip = g.getClipBounds();
2659             if (leftToRight) {
2660                 g.clip(LTR_THUMB_SHAPE);
2661             }
2662             else {
2663                 g.clip(RTL_THUMB_SHAPE);
2664             }
2665             if (!enabled) {
2666                 g.setColor(MetalLookAndFeel.getControl());
2667                 g.fillRect(1, 1, 14, 14);
2668             }
2669             else if (hasFocus) {
2670                 MetalUtils.drawGradient(c, g, "Slider.focusGradient",
2671                                         1, 1, 14, 14, false);
2672             }
2673             else {
2674                 MetalUtils.drawGradient(c, g, "Slider.gradient",
2675                                         1, 1, 14, 14, false);
2676             }
2677             g.setClip(clip);
2678 
2679             // Draw the frame
2680             if (hasFocus) {
2681                 g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
2682             }
2683             else {
2684                 g.setColor(enabled ? MetalLookAndFeel.getPrimaryControlInfo() :
2685                            MetalLookAndFeel.getControlDarkShadow());
2686             }
2687 
2688             if (leftToRight) {
2689                 g.drawLine(  1,0  ,  8,0  ); // top
2690                 g.drawLine(  0,1  ,  0,13 ); // left
2691                 g.drawLine(  1,14 ,  8,14 ); // bottom
2692                 g.drawLine(  9,1  , 15,7  ); // top slant
2693                 g.drawLine(  9,13 , 15,7  ); // bottom slant
2694             }
2695             else {
2696                 g.drawLine(  7,0  , 14,0  ); // top
2697                 g.drawLine( 15,1  , 15,13 ); // right
2698                 g.drawLine(  7,14 , 14,14 ); // bottom
2699                 g.drawLine(  0,7  ,  6,1  ); // top slant
2700                 g.drawLine(  0,7  ,  6,13 ); // bottom slant
2701             }
2702 
2703             if (hasFocus && enabled) {
2704                 // Inner line.
2705                 g.setColor(MetalLookAndFeel.getPrimaryControl());
2706                 if (leftToRight) {
2707                     g.drawLine(  1,1  ,  8,1  ); // top
2708                     g.drawLine(  1,1  ,  1,13 ); // left
2709                     g.drawLine(  1,13 ,  8,13 ); // bottom
2710                     g.drawLine(  9,2  , 14,7  ); // top slant
2711                     g.drawLine(  9,12 , 14,7  ); // bottom slant
2712                 }
2713                 else {
2714                     g.drawLine(  7,1  , 14,1  ); // top
2715                     g.drawLine( 14,1  , 14,13 ); // right
2716                     g.drawLine(  7,13 , 14,13 ); // bottom
2717                     g.drawLine(  1,7  ,  7,1  ); // top slant
2718                     g.drawLine(  1,7  ,  7,13 ); // bottom slant
2719                 }
2720             }
2721         }
2722 
2723         public int getIconWidth() {
2724             return 16;
2725         }
2726 
2727         public int getIconHeight() {
2728             return 15;
2729         }
2730 
2731         protected Image createImage(Component c, int w, int h,
2732                                     GraphicsConfiguration config,
2733                                     Object[] args) {
2734             if (config == null) {
2735                 return new BufferedImage(w, h,BufferedImage.TYPE_INT_ARGB);
2736             }
2737             return config.createCompatibleImage(
2738                                 w, h, Transparency.BITMASK);
2739         }
2740     }
2741 
2742 
2743     private static class OceanHorizontalSliderThumbIcon extends CachedPainter
2744                               implements Icon, Serializable, UIResource {
2745         // Used for clipping
2746         private static Polygon THUMB_SHAPE;
2747 
2748         static {
2749             THUMB_SHAPE = new Polygon(new int[] { 0, 14, 14,  7,  0 },
2750                                       new int[] { 0,  0,  8, 15,  8 }, 5);
2751         }
2752 
2753         OceanHorizontalSliderThumbIcon() {
2754             super(3);
2755         }
2756 
2757         public void paintIcon(Component c, Graphics g, int x, int y) {
2758             if (!(g instanceof Graphics2D)) {
2759                 return;
2760             }
2761             paint(c, g, x, y, getIconWidth(), getIconHeight(),
2762                   c.hasFocus(), c.isEnabled(),
2763                   MetalLookAndFeel.getCurrentTheme());
2764         }
2765 
2766 
2767         protected Image createImage(Component c, int w, int h,
2768                                     GraphicsConfiguration config,
2769                                     Object[] args) {
2770             if (config == null) {
2771                 return new BufferedImage(w, h,BufferedImage.TYPE_INT_ARGB);
2772             }
2773             return config.createCompatibleImage(
2774                                 w, h, Transparency.BITMASK);
2775         }
2776 
2777         protected void paintToImage(Component c, Image image, Graphics g2,
2778                                     int w, int h, Object[] args) {
2779             Graphics2D g = (Graphics2D)g2;
2780             boolean hasFocus = ((Boolean)args[0]).booleanValue();
2781             boolean enabled = ((Boolean)args[1]).booleanValue();
2782 
2783             // Fill in the background
2784             Rectangle clip = g.getClipBounds();
2785             g.clip(THUMB_SHAPE);
2786             if (!enabled) {
2787                 g.setColor(MetalLookAndFeel.getControl());
2788                 g.fillRect(1, 1, 13, 14);
2789             }
2790             else if (hasFocus) {
2791                 MetalUtils.drawGradient(c, g, "Slider.focusGradient",
2792                                         1, 1, 13, 14, true);
2793             }
2794             else {
2795                 MetalUtils.drawGradient(c, g, "Slider.gradient",
2796                                         1, 1, 13, 14, true);
2797             }
2798             g.setClip(clip);
2799 
2800             // Draw the frame
2801             if (hasFocus) {
2802                 g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
2803             }
2804             else {
2805                 g.setColor(enabled ? MetalLookAndFeel.getPrimaryControlInfo() :
2806                            MetalLookAndFeel.getControlDarkShadow());
2807             }
2808 
2809             g.drawLine(  1,0  , 13,0 );  // top
2810             g.drawLine(  0,1  ,  0,8 );  // left
2811             g.drawLine( 14,1  , 14,8 );  // right
2812             g.drawLine(  1,9  ,  7,15 ); // left slant
2813             g.drawLine(  7,15 , 14,8 );  // right slant
2814 
2815             if (hasFocus && enabled) {
2816                 // Inner line.
2817                 g.setColor(MetalLookAndFeel.getPrimaryControl());
2818                 g.fillRect(1, 1, 13, 1);
2819                 g.fillRect(1, 2, 1, 7);
2820                 g.fillRect(13, 2, 1, 7);
2821                 g.drawLine(2, 9, 7, 14);
2822                 g.drawLine(8, 13, 12, 9);
2823             }
2824         }
2825 
2826         public int getIconWidth() {
2827             return 15;
2828         }
2829 
2830         public int getIconHeight() {
2831             return 16;
2832         }
2833     }
2834 }