1 /*
2  * Copyright (c) 1997, 2017, 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 com.sun.java.swing.plaf.motif;
27 
28 import javax.swing.*;
29 
30 import javax.swing.plaf.UIResource;
31 
32 import java.awt.Color;
33 import java.awt.Component;
34 import java.awt.Dimension;
35 import java.awt.Graphics;
36 import java.awt.Polygon;
37 
38 import java.io.Serializable;
39 
40 /**
41  * Icon factory for the CDE/Motif Look and Feel
42  * <p>
43  * <strong>Warning:</strong>
44  * Serialized objects of this class will not be compatible with
45  * future Swing releases.  The current serialization support is appropriate
46  * for short term storage or RMI between applications running the same
47  * version of Swing.  A future release of Swing will provide support for
48  * long term persistence.
49  *
50  * 1.20 04/27/99
51  * @author Georges Saab
52  */
53 @SuppressWarnings("serial") // Same-version serialization only
54 public class MotifIconFactory implements Serializable
55 {
56     private static Icon checkBoxIcon;
57     private static Icon radioButtonIcon;
58     private static Icon menuItemCheckIcon;
59     private static Icon menuItemArrowIcon;
60     private static Icon menuArrowIcon;
61 
getMenuItemCheckIcon()62     public static Icon getMenuItemCheckIcon() {
63         return null;
64     }
65 
getMenuItemArrowIcon()66     public static Icon getMenuItemArrowIcon() {
67         if (menuItemArrowIcon == null) {
68             menuItemArrowIcon = new MenuItemArrowIcon();
69         }
70         return menuItemArrowIcon;
71     }
72 
getMenuArrowIcon()73     public static Icon getMenuArrowIcon() {
74         if (menuArrowIcon == null) {
75             menuArrowIcon = new MenuArrowIcon();
76         }
77         return menuArrowIcon;
78     }
79 
getCheckBoxIcon()80     public static Icon getCheckBoxIcon() {
81         if (checkBoxIcon == null) {
82             checkBoxIcon = new CheckBoxIcon();
83         }
84         return checkBoxIcon;
85     }
86 
getRadioButtonIcon()87     public static Icon getRadioButtonIcon() {
88         if (radioButtonIcon == null) {
89             radioButtonIcon = new RadioButtonIcon();
90         }
91         return radioButtonIcon;
92     }
93 
94     @SuppressWarnings("serial") // Same-version serialization only
95     private static class CheckBoxIcon implements Icon, UIResource, Serializable  {
96         static final int csize = 13;
97 
98         private Color control = UIManager.getColor("control");
99         private Color foreground = UIManager.getColor("CheckBox.foreground");
100         private Color shadow = UIManager.getColor("controlShadow");
101         private Color highlight = UIManager.getColor("controlHighlight");
102         private Color lightShadow = UIManager.getColor("controlLightShadow");
103 
paintIcon(Component c, Graphics g, int x, int y)104         public void paintIcon(Component c, Graphics g, int x, int y) {
105             AbstractButton b = (AbstractButton) c;
106             ButtonModel model = b.getModel();
107 
108             boolean flat = false;
109 
110             if(b instanceof JCheckBox) {
111                 flat = ((JCheckBox)b).isBorderPaintedFlat();
112             }
113 
114             boolean isPressed = model.isPressed();
115             boolean isArmed = model.isArmed();
116             boolean isEnabled = model.isEnabled();
117             boolean isSelected = model.isSelected();
118 
119             // There are 4 "looks" to the Motif CheckBox:
120             //  drawCheckBezelOut  -  default unchecked state
121             //  drawBezel          -  when we uncheck in toggled state
122             //  drawCheckBezel     -  when we check in toggle state
123             //  drawCheckBezelIn   -  selected, mouseReleased
124             boolean checkToggleIn = ((isPressed &&
125                                       !isArmed   &&
126                                       isSelected) ||
127                                      (isPressed &&
128                                       isArmed   &&
129                                       !isSelected));
130             boolean uncheckToggleOut = ((isPressed &&
131                                          !isArmed &&
132                                          !isSelected) ||
133                                         (isPressed &&
134                                          isArmed &&
135                                          isSelected));
136 
137             boolean checkIn = (!isPressed  &&
138                                isArmed    &&
139                                isSelected  ||
140                                (!isPressed &&
141                                 !isArmed  &&
142                                 isSelected));
143 
144 
145             if(flat) {
146                 g.setColor(shadow);
147                 g.drawRect(x+2,y,csize-1,csize-1);
148                 if(uncheckToggleOut || checkToggleIn) {
149                     g.setColor(control);
150                     g.fillRect(x+3,y+1,csize-2,csize-2);
151                 }
152             }
153 
154             if (checkToggleIn) {
155                 // toggled from unchecked to checked
156                 drawCheckBezel(g,x,y,csize,true,false,false,flat);
157             } else if (uncheckToggleOut) {
158                 // MotifBorderFactory.drawBezel(g,x,y,csize,csize,false,false);
159                 drawCheckBezel(g,x,y,csize,true,true,false,flat);
160             } else if (checkIn) {
161                 // show checked, unpressed state
162                 drawCheckBezel(g,x,y,csize,false,false,true,flat);
163             } else if(!flat) {
164                 //  show unchecked state
165                 drawCheckBezelOut(g,x,y,csize);
166             }
167         }
168 
getIconWidth()169         public int getIconWidth() {
170             return csize;
171         }
172 
getIconHeight()173         public int getIconHeight() {
174             return csize;
175         }
176 
drawCheckBezelOut(Graphics g, int x, int y, int csize)177         public void drawCheckBezelOut(Graphics g, int x, int y, int csize){
178             Color controlShadow = UIManager.getColor("controlShadow");
179 
180             int w = csize;
181             int h = csize;
182             Color oldColor = g.getColor();
183 
184             g.translate(x,y);
185             g.setColor(highlight);    // inner 3D border
186             g.drawLine(0, 0, 0, h-1);
187             g.drawLine(1, 0, w-1, 0);
188 
189             g.setColor(shadow);         // black drop shadow  __|
190             g.drawLine(1, h-1, w-1, h-1);
191             g.drawLine(w-1, h-1, w-1, 1);
192             g.translate(-x,-y);
193             g.setColor(oldColor);
194         }
195 
drawCheckBezel(Graphics g, int x, int y, int csize, boolean shade, boolean out, boolean check, boolean flat)196         public void drawCheckBezel(Graphics g, int x, int y, int csize,
197                                    boolean shade, boolean out, boolean check, boolean flat)
198             {
199 
200 
201                 Color oldColor = g.getColor();
202                 g.translate(x, y);
203 
204 
205                 //bottom
206                 if(!flat) {
207                     if (out) {
208                         g.setColor(control);
209                         g.fillRect(1,1,csize-2,csize-2);
210                         g.setColor(shadow);
211                     } else {
212                         g.setColor(lightShadow);
213                         g.fillRect(0,0,csize,csize);
214                         g.setColor(highlight);
215                     }
216 
217                     g.drawLine(1,csize-1,csize-2,csize-1);
218                     if (shade) {
219                         g.drawLine(2,csize-2,csize-3,csize-2);
220                         g.drawLine(csize-2,2,csize-2 ,csize-1);
221                         if (out) {
222                             g.setColor(highlight);
223                         } else {
224                             g.setColor(shadow);
225                         }
226                         g.drawLine(1,2,1,csize-2);
227                         g.drawLine(1,1,csize-3,1);
228                         if (out) {
229                             g.setColor(shadow);
230                         } else {
231                             g.setColor(highlight);
232                         }
233                     }
234                     //right
235                     g.drawLine(csize-1,1,csize-1,csize-1);
236 
237                     //left
238                     if (out) {
239                         g.setColor(highlight);
240                     } else {
241                         g.setColor(shadow);
242                     }
243                     g.drawLine(0,1,0,csize-1);
244 
245                     //top
246                     g.drawLine(0,0,csize-1,0);
247                 }
248 
249                 if (check) {
250                     // draw check
251                     g.setColor(foreground);
252                     int[] xa = {csize - 12, csize - 8, csize - 7, csize - 4,
253                                 csize - 2, csize - 2, csize - 8, csize - 10,
254                                 csize - 11};
255                     int[] ya = new int[]{6, 10, 10, 4, 2, 1, 7, 5, 5};
256                     g.fillPolygon(xa, ya, 9);
257                 }
258                 g.translate(-x, -y);
259                 g.setColor(oldColor);
260             }
261     } // end class CheckBoxIcon
262 
263     @SuppressWarnings("serial") // Same-version serialization only
264     private static class RadioButtonIcon implements Icon, UIResource, Serializable {
265         private Color dot = UIManager.getColor("activeCaptionBorder");
266         private Color highlight = UIManager.getColor("controlHighlight");
267         private Color shadow = UIManager.getColor("controlShadow");
268 
paintIcon(Component c, Graphics g, int x, int y)269         public void paintIcon(Component c, Graphics g, int x, int y) {
270             // fill interior
271             AbstractButton b = (AbstractButton) c;
272             ButtonModel model = b.getModel();
273 
274             int w = getIconWidth();
275             int h = getIconHeight();
276 
277             boolean isPressed = model.isPressed();
278             boolean isArmed = model.isArmed();
279             boolean isEnabled = model.isEnabled();
280             boolean isSelected = model.isSelected();
281 
282             boolean checkIn = ((isPressed &&
283                                 !isArmed   &&
284                                 isSelected) ||
285                                (isPressed &&
286                                 isArmed   &&
287                                 !isSelected)
288                                ||
289                                (!isPressed  &&
290                                 isArmed    &&
291                                 isSelected  ||
292                                 (!isPressed &&
293                                  !isArmed  &&
294                                  isSelected)));
295 
296             if (checkIn){
297                 g.setColor(shadow);
298                 g.drawArc(x, y, w - 1, h - 1, 45, 180);
299                 g.setColor(highlight);
300                 g.drawArc(x, y, w - 1, h - 1, 45, -180);
301                 g.setColor(dot);
302                 g.fillOval(x + 3, y + 3, 7, 7);
303             }
304             else {
305                 g.setColor(highlight);
306                 g.drawArc(x, y, w - 1, h - 1, 45, 180);
307 
308                 g.setColor(shadow);
309                 g.drawArc(x, y, w - 1, h - 1, 45, -180);
310 
311             }
312         }
313 
getIconWidth()314         public int getIconWidth() {
315             return 14;
316         }
317 
getIconHeight()318         public int getIconHeight() {
319             return 14;
320         }
321     } // end class RadioButtonIcon
322 
323     @SuppressWarnings("serial") // Same-version serialization only
324     private static class MenuItemCheckIcon implements Icon, UIResource, Serializable
325     {
paintIcon(Component c,Graphics g, int x, int y)326         public void paintIcon(Component c,Graphics g, int x, int y)
327             {
328             }
getIconWidth()329         public int getIconWidth() { return 0; }
getIconHeight()330         public int getIconHeight() { return 0; }
331     }  // end class MenuItemCheckIcon
332 
333 
334     @SuppressWarnings("serial") // Same-version serialization only
335     private static class MenuItemArrowIcon implements Icon, UIResource, Serializable
336     {
paintIcon(Component c,Graphics g, int x, int y)337         public void paintIcon(Component c,Graphics g, int x, int y)
338             {
339             }
getIconWidth()340         public int getIconWidth() { return 0; }
getIconHeight()341         public int getIconHeight() { return 0; }
342     }  // end class MenuItemArrowIcon
343 
344     @SuppressWarnings("serial") // Same-version serialization only
345     private static class MenuArrowIcon implements Icon, UIResource, Serializable
346     {
347         private Color focus = UIManager.getColor("windowBorder");
348         private Color shadow = UIManager.getColor("controlShadow");
349         private Color highlight = UIManager.getColor("controlHighlight");
350 
paintIcon(Component c, Graphics g, int x, int y)351         public void paintIcon(Component c, Graphics g, int x, int y) {
352             AbstractButton b = (AbstractButton) c;
353             ButtonModel model = b.getModel();
354 
355             // These variables are kind of pointless as the following code
356             // assumes the icon will be 10 x 10 regardless of their value.
357             int w = getIconWidth();
358             int h = getIconHeight();
359 
360             Color oldColor = g.getColor();
361 
362             if (model.isSelected()){
363                 if (c.getComponentOrientation().isLeftToRight()) {
364                     g.setColor(shadow);
365                     g.fillRect(x+1,y+1,2,h);
366                     g.drawLine(x+4,y+2,x+4,y+2);
367                     g.drawLine(x+6,y+3,x+6,y+3);
368                     g.drawLine(x+8,y+4,x+8,y+5);
369                     g.setColor(focus);
370                     g.fillRect(x+2,y+2,2,h-2);
371                     g.fillRect(x+4,y+3,2,h-4);
372                     g.fillRect(x+6,y+4,2,h-6);
373                     g.setColor(highlight);
374                     g.drawLine(x+2,y+h,x+2,y+h);
375                     g.drawLine(x+4,y+h-1,x+4,y+h-1);
376                     g.drawLine(x+6,y+h-2,x+6,y+h-2);
377                     g.drawLine(x+8,y+h-4,x+8,y+h-3);
378                 } else {
379                     g.setColor(highlight);
380                     g.fillRect(x+7,y+1,2,10);
381                     g.drawLine(x+5,y+9,x+5,y+9);
382                     g.drawLine(x+3,y+8,x+3,y+8);
383                     g.drawLine(x+1,y+6,x+1,y+7);
384                     g.setColor(focus);
385                     g.fillRect(x+6,y+2,2,8);
386                     g.fillRect(x+4,y+3,2,6);
387                     g.fillRect(x+2,y+4,2,4);
388                     g.setColor(shadow);
389                     g.drawLine(x+1,y+4,x+1,y+5);
390                     g.drawLine(x+3,y+3,x+3,y+3);
391                     g.drawLine(x+5,y+2,x+5,y+2);
392                     g.drawLine(x+7,y+1,x+7,y+1);
393                 }
394             } else {
395                 if (c.getComponentOrientation().isLeftToRight()) {
396                     g.setColor(highlight);
397                     g.drawLine(x+1,y+1,x+1,y+h);
398                     g.drawLine(x+2,y+1,x+2,y+h-2);
399                     g.fillRect(x+3,y+2,2,2);
400                     g.fillRect(x+5,y+3,2,2);
401                     g.fillRect(x+7,y+4,2,2);
402                     g.setColor(shadow);
403                     g.drawLine(x+2,y+h-1,x+2,y+h);
404                     g.fillRect(x+3,y+h-2,2,2);
405                     g.fillRect(x+5,y+h-3,2,2);
406                     g.fillRect(x+7,y+h-4,2,2);
407                     g.setColor(oldColor);
408                 } else {
409                     g.setColor(highlight);
410                     g.fillRect(x+1,y+4,2,2);
411                     g.fillRect(x+3,y+3,2,2);
412                     g.fillRect(x+5,y+2,2,2);
413                     g.drawLine(x+7,y+1,x+7,y+2);
414                     g.setColor(shadow);
415                     g.fillRect(x+1,y+h-4,2,2);
416                     g.fillRect(x+3,y+h-3,2,2);
417                     g.fillRect(x+5,y+h-2,2,2);
418                     g.drawLine(x+7,y+3,x+7,y+h);
419                     g.drawLine(x+8,y+1,x+8,y+h);
420                     g.setColor(oldColor);
421                 }
422             }
423 
424         }
getIconWidth()425         public int getIconWidth() { return 10; }
getIconHeight()426         public int getIconHeight() { return 10; }
427     } // End class MenuArrowIcon
428 }
429