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