KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > java > swing > plaf > nimbus > NimbusLookAndFeel


1 /*
2  * @(#)NimbusLookAndFeel.java 1.14 08/02/04
3  *
4  * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 package com.sun.java.swing.plaf.nimbus;
8
9 import javax.swing.JComponent JavaDoc;
10 import javax.swing.UIDefaults JavaDoc;
11 import javax.swing.UIManager JavaDoc;
12 import javax.swing.plaf.synth.Region JavaDoc;
13 import javax.swing.plaf.synth.SynthLookAndFeel JavaDoc;
14 import javax.swing.plaf.synth.SynthStyle JavaDoc;
15 import javax.swing.plaf.synth.SynthStyleFactory JavaDoc;
16 import javax.swing.plaf.UIResource JavaDoc;
17 import java.security.AccessController JavaDoc;
18 import java.awt.Color JavaDoc;
19 import java.awt.Graphics2D JavaDoc;
20 import java.awt.image.BufferedImage JavaDoc;
21 import javax.swing.GrayFilter JavaDoc;
22 import javax.swing.Icon JavaDoc;
23 import javax.swing.border.TitledBorder JavaDoc;
24 import javax.swing.plaf.BorderUIResource JavaDoc;
25 import sun.swing.ImageIconUIResource;
26 import sun.swing.plaf.synth.SynthIcon;
27 import sun.swing.plaf.GTKKeybindings;
28 import sun.swing.plaf.WindowsKeybindings;
29 import sun.security.action.GetPropertyAction;
30
31 /**
32  * <p>The NimbusLookAndFeel class.</p>
33  *
34  * @author Jasper Potts
35  * @author Richard Bair
36  */

37 public class NimbusLookAndFeel extends SynthLookAndFeel JavaDoc {
38
39     /** Set of standard region names for UIDefaults Keys */
40     private static final String JavaDoc[] COMPONENT_KEYS = new String JavaDoc[]{"ArrowButton", "Button",
41                     "CheckBox", "CheckBoxMenuItem", "ColorChooser", "ComboBox",
42                     "DesktopPane", "DesktopIcon", "EditorPane", "FileChooser",
43                     "FormattedTextField", "InternalFrame",
44                     "InternalFrameTitlePane", "Label", "List", "Menu",
45                     "MenuBar", "MenuItem", "OptionPane", "Panel",
46                     "PasswordField", "PopupMenu", "PopupMenuSeparator",
47                     "ProgressBar", "RadioButton", "RadioButtonMenuItem",
48                     "RootPane", "ScrollBar", "ScrollBarTrack", "ScrollBarThumb",
49                     "ScrollPane", "Separator", "Slider", "SliderTrack",
50                     "SliderThumb", "Spinner", "SplitPane", "TabbedPane",
51                     "Table", "TableHeader", "TextArea", "TextField", "TextPane",
52                     "ToggleButton", "ToolBar", "ToolTip", "Tree", "Viewport"};
53
54     /**
55      * A reference to the auto-generated file NimbusDefaults. This file contains
56      * the default mappings and values for the look and feel as specified in the
57      * visual designer.
58      */

59     private NimbusDefaults defaults;
60
61     /**
62      * Reference to populated LAD uidefaults
63      */

64     private UIDefaults JavaDoc uiDefaults;
65     
66     /**
67      * Create a new NimbusLookAndFeel.
68      */

69     public NimbusLookAndFeel() {
70         super();
71         defaults = new NimbusDefaults();
72     }
73     
74     /** Called by UIManager when this look and feel is installed. */
75     @Override JavaDoc public void initialize() {
76         super.initialize();
77         defaults.initialize();
78         // create synth style factory
79
setStyleFactory(new SynthStyleFactory JavaDoc() {
80             @Override JavaDoc
81             public SynthStyle JavaDoc getStyle(JComponent JavaDoc c, Region JavaDoc r) {
82                 return defaults.getStyle(c, r);
83             }
84         });
85     }
86
87
88     /** Called by UIManager when this look and feel is uninstalled. */
89     @Override JavaDoc public void uninitialize() {
90         super.uninitialize();
91         defaults.uninitialize();
92         // clear all cached images to free memory
93
ImageCache.getInstance().flush();
94     }
95
96     /**
97      * @inheritDoc
98      */

99     @Override JavaDoc public UIDefaults JavaDoc getDefaults() {
100         if (uiDefaults== null){
101             // Detect platform
102
String JavaDoc osName = getSystemProperty("os.name");
103             boolean isWindows = osName != null && osName.contains("Windows");
104
105             // We need to call super for basic's properties file.
106
uiDefaults = super.getDefaults();
107             defaults.initializeDefaults(uiDefaults);
108
109             // Install Keybindings
110
if (isWindows) {
111                 WindowsKeybindings.installKeybindings(uiDefaults);
112             } else {
113                 GTKKeybindings.installKeybindings(uiDefaults);
114             }
115
116             // Add Titled Border
117
uiDefaults.put("TitledBorder.titlePosition",
118                     TitledBorder.ABOVE_TOP);
119             uiDefaults.put("TitledBorder.border", new BorderUIResource JavaDoc(
120                     new LoweredBorder()));
121             uiDefaults.put("TitledBorder.titleColor",
122                     getDerivedColor("text",0.0f,0.0f,0.23f,0,true));
123             uiDefaults.put("TitledBorder.font",
124                     new NimbusDefaults.DerivedFont("defaultFont",
125                             1f, true, null));
126             
127             // Choose Dialog button positions
128
uiDefaults.put("OptionPane.isYesLast", !isWindows);
129
130             // Store Table ScrollPane Corner Component
131
uiDefaults.put("Table.scrollPaneCornerComponent",
132                     TableScrollPaneCorner.class);
133
134             // Populate UIDefaults with a standard set of properties
135
for (String JavaDoc componentKey : COMPONENT_KEYS) {
136                 String JavaDoc key = componentKey+".foreground";
137                 if (!uiDefaults.containsKey(key)){
138                     uiDefaults.put(key,
139                             new NimbusProperty(componentKey,"textForeground"));
140                 }
141                 key = componentKey+".background";
142                 if (!uiDefaults.containsKey(key)){
143                     uiDefaults.put(key,
144                             new NimbusProperty(componentKey,"background"));
145                 }
146                 key = componentKey+".font";
147                 if (!uiDefaults.containsKey(key)){
148                     uiDefaults.put(key,
149                             new NimbusProperty(componentKey,"font"));
150                 }
151                 key = componentKey+".disabledText";
152                 if (!uiDefaults.containsKey(key)){
153                     uiDefaults.put(key,
154                             new NimbusProperty(componentKey,"Disabled",
155                                    "textForeground"));
156                 }
157                 key = componentKey+".disabled";
158                 if (!uiDefaults.containsKey(key)){
159                     uiDefaults.put(key,
160                             new NimbusProperty(componentKey,"Disabled",
161                                     "background"));
162                 }
163             }
164
165             // FileView icon keys are used by some applications, we don't have
166
// a computer icon at the moment so using home icon for now
167
uiDefaults.put("FileView.computerIcon",
168                     new LinkProperty("FileChooser.homeFolderIcon"));
169             uiDefaults.put("FileView.directoryIcon",
170                     new LinkProperty("FileChooser.directoryIcon"));
171             uiDefaults.put("FileView.fileIcon",
172                     new LinkProperty("FileChooser.fileIcon"));
173             uiDefaults.put("FileView.floppyDriveIcon",
174                     new LinkProperty("FileChooser.floppyDriveIcon"));
175             uiDefaults.put("FileView.hardDriveIcon",
176                     new LinkProperty("FileChooser.hardDriveIcon"));
177         }
178         return uiDefaults;
179     }
180     
181     /**
182      * Return a short string that identifies this look and feel.
183      *
184      * @return a short string identifying this look and feel.
185      */

186     @Override JavaDoc public String JavaDoc getName() {
187         return "Nimbus";
188     }
189     
190     /**
191      * Return a string that identifies this look and feel.
192      *
193      * @return a short string identifying this look and feel.
194      */

195     @Override JavaDoc public String JavaDoc getID() {
196         return "Nimbus";
197     }
198     
199     /**
200      * Returns a textual description of this look and feel.
201      *
202      * @return textual description of this look and feel.
203      */

204     @Override JavaDoc public String JavaDoc getDescription() {
205         return "Nimbus Look and Feel";
206     }
207
208     /**
209      * @inheritDoc
210      * @return true
211      */

212     @Override JavaDoc public boolean shouldUpdateStyleOnAncestorChanged() {
213         return true;
214     }
215
216     /**
217      * <p>Registers a third party component with the NimbusLookAndFeel.</p>
218      *
219      * <p>Regions represent Components and areas within Components that act as
220      * independent painting areas. Once registered with the NimbusLookAndFeel,
221      * NimbusStyles for these Regions can be retrieved via the
222      * <code>getStyle</code> method.</p>
223      *
224      * <p>The NimbusLookAndFeel uses a standard naming scheme for entries in the
225      * UIDefaults table. The key for each property, state, painter, and other
226      * default registered in UIDefaults for a specific Region will begin with
227      * the specified <code>prefix</code></p>
228      *
229      * <p>For example, suppose I had a component named JFoo. Suppose I then registered
230      * this component with the NimbusLookAndFeel in this manner:</p>
231      *
232      * <pre><code>
233      * laf.register(NimbusFooUI.FOO_REGION, "Foo");
234      * </code></pre>
235      *
236      * <p>In this case, I could then register properties for this component with
237      * UIDefaults in the following manner:</p>
238      *
239      * <pre><code>
240      * UIManager.put("Foo.background", new ColorUIResource(Color.BLACK));
241      * UIManager.put("Foo.Enabled.backgroundPainter", new FooBackgroundPainter());
242      * </code></pre>
243      *
244      * <p>It is also possible to register a named component with Nimbus.
245      * For example, suppose you wanted to style the background of a JPanel
246      * named "MyPanel" differently from other JPanels. You could accomplish this
247      * by doing the following:</p>
248      *
249      * <pre><code>
250      * laf.register(Region.PANEL, "\"MyPanel\"");
251      * UIManager.put("\"MyPanel\".background", new ColorUIResource(Color.RED));
252      * </code></pre>
253      *
254      * @param region The Synth Region that is being registered. Such as Button, or
255      * ScrollBarThumb, or NimbusFooUI.FOO_REGION.
256      * @param prefix The UIDefault prefix. For example, could be ComboBox, or if
257      * a named components, "MyComboBox", or even something like
258      * ToolBar."MyComboBox"."ComboBox.arrowButton"
259      */

260     public void register(Region JavaDoc region, String JavaDoc prefix) {
261         defaults.register(region, prefix);
262     }
263     
264     /**
265      * Simple utility method that reads system keys.
266      */

267     private String JavaDoc getSystemProperty(String JavaDoc key) {
268         return AccessController.doPrivileged(new GetPropertyAction(key));
269     }
270
271     @Override JavaDoc
272     public Icon JavaDoc getDisabledIcon(JComponent JavaDoc component, Icon JavaDoc icon) {
273         if (icon instanceof SynthIcon) {
274             SynthIcon si = (SynthIcon)icon;
275             BufferedImage JavaDoc img = EffectUtils.createCompatibleTranslucentImage(
276                     si.getIconWidth(), si.getIconHeight());
277             Graphics2D JavaDoc gfx = img.createGraphics();
278             si.paintIcon(component, gfx, 0, 0);
279             gfx.dispose();
280             return new ImageIconUIResource(GrayFilter.createDisabledImage(img));
281         } else {
282             return super.getDisabledIcon(component, icon);
283         }
284     }
285     
286     /**
287      * Get a derived color, derived colors are shared instances and is color
288      * value will change when its parent UIDefault color changes.
289      *
290      * @param uiDefaultParentName The parent UIDefault key
291      * @param hOffset The hue offset
292      * @param sOffset The saturation offset
293      * @param bOffset The brightness offset
294      * @param aOffset The alpha offset
295      * @param uiResource True if the derived color should be a
296      * UIResource, false if it should not be
297      * @return The stored derived color
298      */

299     public Color JavaDoc getDerivedColor(String JavaDoc uiDefaultParentName,
300                                  float hOffset, float sOffset,
301                                  float bOffset, int aOffset,
302                                  boolean uiResource) {
303         return defaults.getDerivedColor(uiDefaultParentName, hOffset, sOffset,
304                 bOffset, aOffset, uiResource);
305     }
306
307     /**
308      * Decodes and returns a color, which is derived from a offset between two
309      * other colors.
310      *
311      * @param color1 The first color
312      * @param color2 The second color
313      * @param midPoint The offset between color 1 and color 2, a value of 0.0 is
314      * color 1 and 1.0 is color 2;
315      * @param uiResource True if the derived color should be a UIResource
316      * @return The derived color, whos color value will change if either of the
317      * colors change, this will only work if they are color fetched from
318      * the other getDerivedColor(s,f,f,f,i) method as they fire property
319      * change events for then they change.
320      */

321     protected final Color JavaDoc getDerivedColor(Color JavaDoc color1, Color JavaDoc color2,
322                                       float midPoint, boolean uiResource) {
323         if (uiResource) {
324             return new DuoDerivedColor.UIResource(color1, color2, midPoint);
325         } else {
326             return new DuoDerivedColor(color1, color2, midPoint);
327         }
328     }
329
330     /**
331      * Decodes and returns a color, which is derived from a offset between two
332      * other colors.
333      *
334      * @param color1 The first color
335      * @param color2 The second color
336      * @param midPoint The offset between color 1 and color 2, a value of 0.0 is
337      * color 1 and 1.0 is color 2;
338      * @return The derived color, whos color value will change if either of the
339      * colors change, this will only work if they are color fetched from
340      * the other getDerivedColor(s,f,f,f,i) method as they fire property
341      * change events for then they change.
342      */

343     protected final Color JavaDoc getDerivedColor(Color JavaDoc color1, Color JavaDoc color2,
344                                       float midPoint) {
345         return getDerivedColor(color1, color2, midPoint, true);
346     }
347
348     /**
349      * Simple Symbolic Link style UIDefalts Property
350      */

351     private class LinkProperty implements UIDefaults.ActiveValue JavaDoc, UIResource JavaDoc{
352         private String JavaDoc dstPropName;
353
354         private LinkProperty(String JavaDoc dstPropName) {
355             this.dstPropName = dstPropName;
356         }
357
358         public Object JavaDoc createValue(UIDefaults JavaDoc table) {
359             return UIManager.get(dstPropName);
360         }
361     }
362
363     /**
364      * Nimbus Property that looks up Nimbus keys for standard key names. For
365      * example "Button.background" --> "Button[Enabled].backgound"
366      */

367     private class NimbusProperty implements UIDefaults.ActiveValue JavaDoc, UIResource JavaDoc{
368         private String JavaDoc prefix;
369         private String JavaDoc state = null;
370         private String JavaDoc suffix;
371         private boolean isFont;
372
373         private NimbusProperty(String JavaDoc prefix, String JavaDoc suffix) {
374             this.prefix = prefix;
375             this.suffix = suffix;
376             isFont = "font".equals(suffix);
377         }
378
379         private NimbusProperty(String JavaDoc prefix, String JavaDoc state, String JavaDoc suffix) {
380             this(prefix,suffix);
381             this.state = state;
382         }
383
384         /**
385          * Creates the value retrieved from the <code>UIDefaults</code> table.
386          * The object is created each time it is accessed.
387          *
388          * @param table a <code>UIDefaults</code> table
389          * @return the created <code>Object</code>
390          */

391         public Object JavaDoc createValue(UIDefaults JavaDoc table) {
392             Object JavaDoc obj = null;
393             // check specified state
394
if (state!=null){
395                 obj = uiDefaults.get(prefix+"["+state+"]."+suffix);
396             }
397             // check enabled state
398
if (obj==null){
399                 obj = uiDefaults.get(prefix+"[Enabled]."+suffix);
400             }
401             // check for defaults
402
if (obj==null){
403                 if (isFont) {
404                     obj = uiDefaults.get("defaultFont");
405                 } else {
406                     obj = uiDefaults.get(suffix);
407                 }
408             }
409             return obj;
410         }
411     }
412 }
413
Popular Tags