001 /*
002 * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package javax.swing.plaf.metal;
027
028 import javax.swing.plaf.*;
029 import javax.swing.*;
030 import java.awt.*;
031
032 import sun.awt.AppContext;
033 import sun.security.action.GetPropertyAction;
034 import sun.swing.SwingUtilities2;
035
036 /**
037 * A concrete implementation of {@code MetalTheme} providing
038 * the original look of the Java Look and Feel, code-named "Steel". Refer
039 * to {@link MetalLookAndFeel#setCurrentTheme} for details on changing
040 * the default theme.
041 * <p>
042 * All colors returned by {@code DefaultMetalTheme} are completely
043 * opaque.
044 *
045 * <h3><a name="fontStyle"></a>Font Style</h3>
046 *
047 * {@code DefaultMetalTheme} uses bold fonts for many controls. To make all
048 * controls (with the exception of the internal frame title bars and
049 * client decorated frame title bars) use plain fonts you can do either of
050 * the following:
051 * <ul>
052 * <li>Set the system property <code>swing.boldMetal</code> to
053 * <code>false</code>. For example,
054 * <code>java -Dswing.boldMetal=false MyApp</code>.
055 * <li>Set the defaults property <code>swing.boldMetal</code> to
056 * <code>Boolean.FALSE</code>. For example:
057 * <code>UIManager.put("swing.boldMetal", Boolean.FALSE);</code>
058 * </ul>
059 * The defaults property <code>swing.boldMetal</code>, if set,
060 * takes precendence over the system property of the same name. After
061 * setting this defaults property you need to re-install
062 * <code>MetalLookAndFeel</code>, as well as update the UI
063 * of any previously created widgets. Otherwise the results are undefined.
064 * The following illustrates how to do this:
065 * <pre>
066 * // turn off bold fonts
067 * UIManager.put("swing.boldMetal", Boolean.FALSE);
068 *
069 * // re-install the Metal Look and Feel
070 * UIManager.setLookAndFeel(new MetalLookAndFeel());
071 *
072 * // Update the ComponentUIs for all Components. This
073 * // needs to be invoked for all windows.
074 * SwingUtilities.updateComponentTreeUI(rootComponent);
075 * </pre>
076 * <p>
077 * <strong>Warning:</strong>
078 * Serialized objects of this class will not be compatible with
079 * future Swing releases. The current serialization support is
080 * appropriate for short term storage or RMI between applications running
081 * the same version of Swing. As of 1.4, support for long term storage
082 * of all JavaBeans<sup><font size="-2">TM</font></sup>
083 * has been added to the <code>java.beans</code> package.
084 * Please see {@link java.beans.XMLEncoder}.
085 *
086 * @see MetalLookAndFeel
087 * @see MetalLookAndFeel#setCurrentTheme
088 *
089 * @version 1.37 05/05/07
090 * @author Steve Wilson
091 */
092 public class DefaultMetalTheme extends MetalTheme {
093 /**
094 * Whether or not fonts should be plain. This is only used if
095 * the defaults property 'swing.boldMetal' == "false".
096 */
097 private static final boolean PLAIN_FONTS;
098
099 /**
100 * Names of the fonts to use.
101 */
102 private static final String[] fontNames = { Font.DIALOG,
103 Font.DIALOG, Font.DIALOG, Font.DIALOG, Font.DIALOG,
104 Font.DIALOG };
105 /**
106 * Styles for the fonts. This is ignored if the defaults property
107 * <code>swing.boldMetal</code> is false, or PLAIN_FONTS is true.
108 */
109 private static final int[] fontStyles = { Font.BOLD, Font.PLAIN,
110 Font.PLAIN, Font.BOLD, Font.BOLD, Font.PLAIN };
111 /**
112 * Sizes for the fonts.
113 */
114 private static final int[] fontSizes = { 12, 12, 12, 12, 12, 10 };
115
116 // note the properties listed here can currently be used by people
117 // providing runtimes to hint what fonts are good. For example the bold
118 // dialog font looks bad on a Mac, so Apple could use this property to
119 // hint at a good font.
120 //
121 // However, we don't promise to support these forever. We may move
122 // to getting these from the swing.properties file, or elsewhere.
123 /**
124 * System property names used to look up fonts.
125 */
126 private static final String[] defaultNames = {
127 "swing.plaf.metal.controlFont",
128 "swing.plaf.metal.systemFont", "swing.plaf.metal.userFont",
129 "swing.plaf.metal.controlFont",
130 "swing.plaf.metal.controlFont",
131 "swing.plaf.metal.smallFont" };
132
133 /**
134 * Returns the ideal font name for the font identified by key.
135 */
136 static String getDefaultFontName(int key) {
137 return fontNames[key];
138 }
139
140 /**
141 * Returns the ideal font size for the font identified by key.
142 */
143 static int getDefaultFontSize(int key) {
144 return fontSizes[key];
145 }
146
147 /**
148 * Returns the ideal font style for the font identified by key.
149 */
150 static int getDefaultFontStyle(int key) {
151 if (key != WINDOW_TITLE_FONT) {
152 Object boldMetal = null;
153 if (AppContext.getAppContext().get(
154 SwingUtilities2.LAF_STATE_KEY) != null) {
155 // Only access the boldMetal key if a look and feel has
156 // been loaded, otherwise we'll trigger loading the look
157 // and feel.
158 boldMetal = UIManager.get("swing.boldMetal");
159 }
160 if (boldMetal != null) {
161 if (Boolean.FALSE.equals(boldMetal)) {
162 return Font.PLAIN;
163 }
164 } else if (PLAIN_FONTS) {
165 return Font.PLAIN;
166 }
167 }
168 return fontStyles[key];
169 }
170
171 /**
172 * Returns the default used to look up the specified font.
173 */
174 static String getDefaultPropertyName(int key) {
175 return defaultNames[key];
176 }
177
178 static {
179 Object boldProperty = java.security.AccessController
180 .doPrivileged(new GetPropertyAction("swing.boldMetal"));
181 if (boldProperty == null || !"false".equals(boldProperty)) {
182 PLAIN_FONTS = false;
183 } else {
184 PLAIN_FONTS = true;
185 }
186 }
187
188 private static final ColorUIResource primary1 = new ColorUIResource(
189 102, 102, 153);
190 private static final ColorUIResource primary2 = new ColorUIResource(
191 153, 153, 204);
192 private static final ColorUIResource primary3 = new ColorUIResource(
193 204, 204, 255);
194 private static final ColorUIResource secondary1 = new ColorUIResource(
195 102, 102, 102);
196 private static final ColorUIResource secondary2 = new ColorUIResource(
197 153, 153, 153);
198 private static final ColorUIResource secondary3 = new ColorUIResource(
199 204, 204, 204);
200
201 private FontDelegate fontDelegate;
202
203 /**
204 * Returns the name of this theme. This returns {@code "Steel"}.
205 *
206 * @return the name of this theme.
207 */
208 public String getName() {
209 return "Steel";
210 }
211
212 /**
213 * Creates and returns an instance of {@code DefaultMetalTheme}.
214 */
215 public DefaultMetalTheme() {
216 install();
217 }
218
219 /**
220 * Returns the primary 1 color. This returns a color with rgb values
221 * of 102, 102, and 153, respectively.
222 *
223 * @return the primary 1 color
224 */
225 protected ColorUIResource getPrimary1() {
226 return primary1;
227 }
228
229 /**
230 * Returns the primary 2 color. This returns a color with rgb values
231 * of 153, 153, 204, respectively.
232 *
233 * @return the primary 2 color
234 */
235 protected ColorUIResource getPrimary2() {
236 return primary2;
237 }
238
239 /**
240 * Returns the primary 3 color. This returns a color with rgb values
241 * 204, 204, 255, respectively.
242 *
243 * @return the primary 3 color
244 */
245 protected ColorUIResource getPrimary3() {
246 return primary3;
247 }
248
249 /**
250 * Returns the secondary 1 color. This returns a color with rgb values
251 * 102, 102, and 102, respectively.
252 *
253 * @return the secondary 1 color
254 */
255 protected ColorUIResource getSecondary1() {
256 return secondary1;
257 }
258
259 /**
260 * Returns the secondary 2 color. This returns a color with rgb values
261 * 153, 153, and 153, respectively.
262 *
263 * @return the secondary 2 color
264 */
265 protected ColorUIResource getSecondary2() {
266 return secondary2;
267 }
268
269 /**
270 * Returns the secondary 3 color. This returns a color with rgb values
271 * 204, 204, and 204, respectively.
272 *
273 * @return the secondary 3 color
274 */
275 protected ColorUIResource getSecondary3() {
276 return secondary3;
277 }
278
279 /**
280 * Returns the control text font. This returns Dialog, 12pt. If
281 * plain fonts have been enabled as described in <a href="#fontStyle">
282 * font style</a>, the font style is plain. Otherwise the font style is
283 * bold.
284 *
285 * @return the control text font
286 */
287 public FontUIResource getControlTextFont() {
288 return getFont(CONTROL_TEXT_FONT);
289 }
290
291 /**
292 * Returns the system text font. This returns Dialog, 12pt, plain.
293 *
294 * @return the sytem text font
295 */
296 public FontUIResource getSystemTextFont() {
297 return getFont(SYSTEM_TEXT_FONT);
298 }
299
300 /**
301 * Returns the user text font. This returns Dialog, 12pt, plain.
302 *
303 * @return the user text font
304 */
305 public FontUIResource getUserTextFont() {
306 return getFont(USER_TEXT_FONT);
307 }
308
309 /**
310 * Returns the menu text font. This returns Dialog, 12pt. If
311 * plain fonts have been enabled as described in <a href="#fontStyle">
312 * font style</a>, the font style is plain. Otherwise the font style is
313 * bold.
314 *
315 * @return the menu text font
316 */
317 public FontUIResource getMenuTextFont() {
318 return getFont(MENU_TEXT_FONT);
319 }
320
321 /**
322 * Returns the window title font. This returns Dialog, 12pt, bold.
323 *
324 * @return the window title font
325 */
326 public FontUIResource getWindowTitleFont() {
327 return getFont(WINDOW_TITLE_FONT);
328 }
329
330 /**
331 * Returns the sub-text font. This returns Dialog, 10pt, plain.
332 *
333 * @return the sub-text font
334 */
335 public FontUIResource getSubTextFont() {
336 return getFont(SUB_TEXT_FONT);
337 }
338
339 private FontUIResource getFont(int key) {
340 return fontDelegate.getFont(key);
341 }
342
343 void install() {
344 if (MetalLookAndFeel.isWindows()
345 && MetalLookAndFeel.useSystemFonts()) {
346 fontDelegate = new WindowsFontDelegate();
347 } else {
348 fontDelegate = new FontDelegate();
349 }
350 }
351
352 /**
353 * Returns true if this is a theme provided by the core platform.
354 */
355 boolean isSystemTheme() {
356 return (getClass() == DefaultMetalTheme.class);
357 }
358
359 /**
360 * FontDelegates add an extra level of indirection to obtaining fonts.
361 */
362 private static class FontDelegate {
363 private static int[] defaultMapping = { CONTROL_TEXT_FONT,
364 SYSTEM_TEXT_FONT, USER_TEXT_FONT, CONTROL_TEXT_FONT,
365 CONTROL_TEXT_FONT, SUB_TEXT_FONT };
366 FontUIResource fonts[];
367
368 // menu and window are mapped to controlFont
369 public FontDelegate() {
370 fonts = new FontUIResource[6];
371 }
372
373 public FontUIResource getFont(int type) {
374 int mappedType = defaultMapping[type];
375 if (fonts[type] == null) {
376 Font f = getPrivilegedFont(mappedType);
377
378 if (f == null) {
379 f = new Font(getDefaultFontName(type),
380 getDefaultFontStyle(type),
381 getDefaultFontSize(type));
382 }
383 fonts[type] = new FontUIResource(f);
384 }
385 return fonts[type];
386 }
387
388 /**
389 * This is the same as invoking
390 * <code>Font.getFont(key)</code>, with the exception
391 * that it is wrapped inside a <code>doPrivileged</code> call.
392 */
393 protected Font getPrivilegedFont(final int key) {
394 return (Font) java.security.AccessController
395 .doPrivileged(new java.security.PrivilegedAction() {
396 public Object run() {
397 return Font
398 .getFont(getDefaultPropertyName(key));
399 }
400 });
401 }
402 }
403
404 /**
405 * The WindowsFontDelegate uses DesktopProperties to obtain fonts.
406 */
407 private static class WindowsFontDelegate extends FontDelegate {
408 private MetalFontDesktopProperty[] props;
409 private boolean[] checkedPriviledged;
410
411 public WindowsFontDelegate() {
412 props = new MetalFontDesktopProperty[6];
413 checkedPriviledged = new boolean[6];
414 }
415
416 public FontUIResource getFont(int type) {
417 if (fonts[type] != null) {
418 return fonts[type];
419 }
420 if (!checkedPriviledged[type]) {
421 Font f = getPrivilegedFont(type);
422
423 checkedPriviledged[type] = true;
424 if (f != null) {
425 fonts[type] = new FontUIResource(f);
426 return fonts[type];
427 }
428 }
429 if (props[type] == null) {
430 props[type] = new MetalFontDesktopProperty(type);
431 }
432 // While passing null may seem bad, we don't actually use
433 // the table and looking it up is rather expensive.
434 return (FontUIResource) props[type].createValue(null);
435 }
436 }
437 }
|