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