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