Java Examples In A Nutshell (3rd Edition) [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Java Examples In A Nutshell (3rd Edition) [Electronic resources] - نسخه متنی

O'Reilly Media, Inc

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید








11.13 Themes and the Metal Look-and-Feel


The default
platform-independent look-and-feel for Swing applications is known as
the Metal look-and-feel. One of the powerful but little-known
features of Metal is that the fonts and colors it uses are easily
customizable. All you have to do is pass a
MetalTheme object to the static
setCurrentTheme( ) method of
MetalLookAndFeel. (These classes are defined in
the infrequently used javax.swing.plaf.metal
package.)

The
MetalTheme class is abstract, so, in practice, you
work with DefaultMetalTheme. This class has six
methods that return the basic theme colors (really three shades each
of a primary and a secondary color) and four methods that return the
basic theme fonts. To define a new theme, all you have to do is
subclass DefaultMetalTheme and override these
methods to return the fonts and colors you want. (If you want more
customizability than this, you have to subclass
MetalTheme directly.)

Example 11-28 is a
listing of ThemeManager.java. This example
includes a subclass of DefaultMetalTheme, but
defines it as an inner class of ThemeManager. The
ThemeManager class provides the ability to read
theme definitions (i.e., color and font specifications) from a
GUIResourceBundle and defines methods for reading
the name of a default theme and a list of names of all available
themes from the bundle. Finally, ThemeManager can
return a JMenu component that displays a list of
available themes to the user and switches the current theme based on
the user's selection.

ThemeManager also demonstrates a feature unrelated
to DefaultMetalTheme: it includes the ability to
tell Swing whether it should provide audio feedback for all, some, or
none of the user actions for which Swing is capable of playing
sounds. It does this by setting an undocumented property[4] with the UIManager.put( ) method.

[4] The properties are not documented within the javadoc API, but
you can find out more by searching the web for the string
"AuditoryCues.playList".


ThemeManager, and the JMenu
component it creates, were used in the WebBrowser
class of Example 11-21. Before you examine the
ThemeManager code, take a look at the following
lines excerpted from the
WebBrowserResources.properties file, which define
the set of available themes for the web browser:

# This property defines the property 
names of all available themes.
themelist: theme.metal theme.rose, theme.lime, theme.primary,
theme.bigfont
# This property defines the name of the default property
defaultTheme: theme.metal
# This theme only has a name.
All font and color values are unchanged from
# the default Metal theme
theme.metal.name: Default Metal
# This theme uses shades of red/pink
theme.rose.name: Rose
theme.rose.primary: #905050
theme.rose.secondary: #906050
theme.rose.sounds: all
# This theme uses lime green colors
theme.lime.name: Lime
theme.lime.primary: #509050
theme.lime.secondary: #506060
theme.lime.sounds: none
# This theme uses bright primary colors
theme.primary.name: Primary Colors
theme.primary.primary: #202090
theme.primary.secondary: #209020
theme.primary.sounds: default
# This theme uses big fonts and the default colors
theme.bigfont.name: Big Fonts
theme.bigfont.controlFont: sansserif-bold-18
theme.bigfont.menuFont: sansserif-bold-18
theme.bigfont.smallFont: sansserif-plain-14
theme.bigfont.systemFont: sansserif-plain-14
theme.bigfont.userFont: sansserif-plain-14
theme.bigfont.titleFont: sansserif-bold-18

With these theme definitions, you should
have no trouble understanding the resource-parsing code of
ThemeManager. getThemeMenu( )
creates a JMenu populated by
JRadioButtonMenuItem objects, rather than
JMenuItem or Action objects, as
we've seen earlier in this chapter. This emphasizes
the fact that only one theme can be selected at a time. When the
theme is changed, the setTheme( ) method uses a
SwingUtilities method to propagate the change to
all components within the frame. Finally, note that the
Theme inner class doesn't use
Font and Color objects, but
uses FontUIResource and
ColorUIResource objects instead. These classes are
part of the javax.swing.plaf package and are
trivial subclasses of Font and
Color that implement the
UIResource marker interface. This interface allows
components to distinguish between property values assigned by the
look-and-feel, which all implement UIResource, and
property values assigned by the application. Based on this
distinction, application settings can override look-and-feel
settings, even when the look-and-feel (or theme) changes while the
application is running.

Example 11-28. ThemeManager.java

package je3.gui;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.*;
import javax.swing.plaf.metal.MetalLookAndFeel;
import javax.swing.plaf.metal.DefaultMetalTheme;
/**
* This class reads theme descriptions from a
GUIResourceBundle and uses them
* to specify colors and fonts for the Metal look-and-feel. It also
* demonstrates an undocumented feature for turning
Swing notification sounds
* on and off.
**/
public class ThemeManager {
JFrame frame; // The frame which themes are applied to
GUIResourceBundle resources; // Properties describing the themes
/**
* Build a ThemeManager for the frame and resource bundle. If there
* is a default theme specified, apply it to the frame
**/
public ThemeManager(JFrame frame, GUIResourceBundle resources) {
this.frame = frame;
this.resources = resources;
String defaultName = getDefaultThemeName( );
if (defaultName != null) setTheme(defaultName);
}
/** Look up the named theme, and apply it to the frame */
public void setTheme(String themeName) {
// Look up the theme in the resource bundle
Theme theme = new Theme(resources, themeName);
// Make it the current theme
MetalLookAndFeel.setCurrentTheme(theme);
// Reapply the Metal look-and-feel to install new theme
try { UIManager.setLookAndFeel(new MetalLookAndFeel( )); }
catch(UnsupportedLookAndFeelException e) { }
// If the theme has an audio playlist, then set it
if (theme.playlist != null)
UIManager.put("AuditoryCues.playList", theme.playlist);
// Propagate the new l&f across the entire component tree of the frame
SwingUtilities.updateComponentTreeUI(frame);
}
/** Get the "display name" or label of the named theme */
public String getDisplayName(String themeName) {
return resources.getString(themeName + ".name", null);
}
/** Get the name of the default theme, or null */
public String getDefaultThemeName( ) {
return resources.getString("defaultTheme", null);
}
/**
* Get the list of all known theme names. The returned values are
* theme property names, not theme display names.
**/
public String[ ] getAllThemeNames( ) {
java.util.List names = resources.getStringList("themelist");
return (String[ ]) names.toArray(new String[names.size( )]);
}
/**
* Get a JMenu that lists all known themes by display name and
* installs any selected theme.
**/
public JMenu getThemeMenu( ) {
String[ ] names = getAllThemeNames( );
String defaultName = getDefaultThemeName( );
JMenu menu = new JMenu("Themes");
ButtonGroup buttongroup = new ButtonGroup( );
for(int i = 0; i < names.length; i++) {
final String themeName = names[i];
String displayName = getDisplayName(themeName);
JMenuItem item = menu.add(new JRadioButtonMenuItem(displayName));
buttongroup.add(item);
if (themeName.equals(defaultName)) item.setSelected(true);
item.addActionListener(new ActionListener( ) {
public void actionPerformed(ActionEvent event) {
setTheme(themeName);
}
});
}
return menu;
}
/**
* This class extends the DefaultMetalTheme class to return Color and
* Font values read from a GUIResourceBundle
**/
public static class Theme extends DefaultMetalTheme {
// These fields are the values returned by this Theme
String displayName;
FontUIResource controlFont, menuFont, smallFont;
FontUIResource systemFont, userFont, titleFont;
ColorUIResource primary1, primary2, primary3;
ColorUIResource secondary1, secondary2, secondary3;
Object playlist; // auditory cues
/**
* This constructor reads all the values it needs from the
* GUIResourceBundle. It uses intelligent defaults if properties
* are not specified.
**/
public Theme(GUIResourceBundle resources, String name) {
// Use this theme object to get default font values from
DefaultMetalTheme defaultTheme = new DefaultMetalTheme( );
// Look up the display name of the theme
displayName = resources.getString(name + ".name", null);
// Look up the fonts for the theme
Font control = resources.getFont(name + ".controlFont", null);
Font menu = resources.getFont(name + ".menuFont", null);
Font small = resources.getFont(name + ".smallFont", null);
Font system = resources.getFont(name + ".systemFont", null);
Font user = resources.getFont(name + ".userFont", null);
Font title = resources.getFont(name + ".titleFont", null);
// Convert fonts to FontUIResource, or get defaults
if (control != null) controlFont = new FontUIResource(control);
else controlFont = defaultTheme.getControlTextFont( );
if (menu != null) menuFont = new FontUIResource(menu);
else menuFont = defaultTheme.getMenuTextFont( );
if (small != null) smallFont = new FontUIResource(small);
else smallFont = defaultTheme.getSubTextFont( );
if (system != null) systemFont = new FontUIResource(system);
else systemFont = defaultTheme.getSystemTextFont( );
if (user != null) userFont = new FontUIResource(user);
else userFont = defaultTheme.getUserTextFont( );
if (title != null) titleFont = new FontUIResource(title);
else titleFont = defaultTheme.getWindowTitleFont( );
// Look up primary and secondary colors
Color primary = resources.getColor(name + ".primary", null);
Color secondary = resources.getColor(name + ".secondary", null);
// Derive all six colors from these two, using defaults if needed
if (primary != null) primary1 = new ColorUIResource(primary);
else primary1 = new ColorUIResource(102, 102, 153);
primary2 = new ColorUIResource(primary1.brighter( ));
primary3 = new ColorUIResource(primary2.brighter( ));
if (secondary != null) secondary1 = new ColorUIResource(secondary);
else secondary1 = new ColorUIResource(102, 102, 102);
secondary2 = new ColorUIResource(secondary1.brighter( ));
secondary3 = new ColorUIResource(secondary2.brighter( ));
// Look up what type of sound is desired. This property should
// be one of the strings "all", "none", or "default". These map to
// undocumented UIManager properties. playlist is an array of
// strings, but we keep it as an opaque object.
String sounds = resources.getString(name + ".sounds", ");
if (sounds.equals("all"))
playlist = UIManager.get("AuditoryCues.allAuditoryCues");
else if (sounds.equals("none"))
playlist = UIManager.get("AuditoryCues.noAuditoryCues");
else if (sounds.equals("default"))
playlist = UIManager.get("AuditoryCues.defaultCueList");
}
// These methods override DefaultMetalTheme and return the property
// values we looked up and computed for this theme
public String getName( ) { return displayName; }
public FontUIResource getControlTextFont( ) { return controlFont;}
public FontUIResource getSystemTextFont( ) { return systemFont;}
public FontUIResource getUserTextFont( ) { return userFont;}
public FontUIResource getMenuTextFont( ) { return menuFont;}
public FontUIResource getWindowTitleFont( ) { return titleFont;}
public FontUIResource getSubTextFont( ) { return smallFont;}
protected ColorUIResource getPrimary1( ) { return primary1; }
protected ColorUIResource getPrimary2( ) { return primary2; }
protected ColorUIResource getPrimary3( ) { return primary3; }
protected ColorUIResource getSecondary1( ) { return secondary1; }
protected ColorUIResource getSecondary2( ) { return secondary2; }
protected ColorUIResource getSecondary3( ) { return secondary3; }
}
}


/ 285