nimbusstyle.java
来自「Mobile 应用程序使用 Java Micro Edition (Java M」· Java 代码 · 共 1,243 行 · 第 1/4 页
JAVA
1,243 行
/* * @(#)NimbusStyle.java 1.9 08/05/29 * * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package com.sun.java.swing.plaf.nimbus;import com.sun.java.swing.Painter;import java.beans.PropertyChangeEvent;import javax.swing.JComponent;import javax.swing.UIDefaults;import javax.swing.UIManager;import javax.swing.plaf.ColorUIResource;import javax.swing.plaf.synth.ColorType;import static javax.swing.plaf.synth.SynthConstants.*;import javax.swing.plaf.synth.SynthContext;import javax.swing.plaf.synth.SynthPainter;import javax.swing.plaf.synth.SynthStyle;import java.awt.Color;import java.awt.Font;import java.awt.Insets;import java.beans.PropertyChangeListener;import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import java.util.HashMap;import java.util.HashSet;import java.util.List;import java.util.Map;import java.util.TreeMap;import sun.awt.AppContext;/** * <p>A SynthStyle implementation used by Nimbus. Each Region that has been * registered with the NimbusLookAndFeel will have an associated NimbusStyle. * Third party components that are registered with the NimbusLookAndFeel will * therefore be handed a NimbusStyle from the look and feel from the * #getStyle(JComponent, Region) method.</p> * * <p>This class properly reads and retrieves values placed in the UIDefaults * according to the standard Nimbus naming conventions. It will create and * retrieve painters, fonts, colors, and other data stored there.</p> * * <p>NimbusStyle also supports the ability to override settings on a per * component basis. NimbusStyle checks the component's client property map for * "Nimbus.Overrides". If the value associated with this key is an instance of * UIDefaults, then the values in that defaults table will override the standard * Nimbus defaults in UIManager, but for that component instance only.</p> * * <p>Optionally, you may specify the client property * "Nimbus.Overrides.InheritDefaults". If true, this client property indicates * that the defaults located in UIManager should first be read, and then * replaced with defaults located in the component client properties. If false, * then only the defaults located in the component client property map will * be used. If not specified, it is assumed to be true.</p> * * <p>You must specify "Nimbus.Overrides" for "Nimbus.Overrides.InheritDefaults" * to have any effect. "Nimbus.Overrides" indicates whether there are any * overrides, while "Nimbus.Overrides.InheritDefaults" indicates whether those * overrides should first be initialized with the defaults from UIManager.</p> * * <p>The NimbusStyle is reloaded whenever a property change event is fired * for a component for "Nimbus.Overrides" or "Nimbus.Overrides.InheritDefaults". * So for example, setting a new UIDefaults on a component would cause the * style to be reloaded.</p> * * <p>The values are only read out of UIManager once, and then cached. If * you need to read the values again (for example, if the UI is being reloaded), * then discard this NimbusStyle and read a new one from NimbusLookAndFeel * using NimbusLookAndFeel.getStyle.</p> * * <p>The primary API of interest in this class for 3rd party component authors * are the three methods which retrieve painters: #getBackgroundPainter, * #getForegroundPainter, and #getBorderPainter.</p> * * <p>NimbusStyle allows you to specify custom states, or modify the order of * states. Synth (and thus Nimbus) has the concept of a "state". For example, * a JButton might be in the "MOUSE_OVER" state, or the "ENABLED" state, or the * "DISABLED" state. These are all "standard" states which are defined in synth, * and which apply to all synth Regions.</p> * * <p>Sometimes, however, you need to have a custom state. For example, you * want JButton to render differently if it's parent is a JToolbar. In Nimbus, * you specify these custom states by including a special key in UIDefaults. * The following UIDefaults entries define three states for this button:</p> * * <pre><code> * JButton.States = Enabled, Disabled, Toolbar * JButton[Enabled].backgroundPainter = somePainter * JButton[Disabled].background = BLUE * JButton[Toolbar].backgroundPainter = someOtherPaint * </code></pre> * * <p>As you can see, the <code>JButton.States</code> entry lists the states * that the JButton style will support. You then specify the settings for * each state. If you do not specify the <code>JButton.States</code> entry, * then the standard Synth states will be assumed. If you specify the entry * but the list of states is empty or null, then the standard synth states * will be assumed.</p> * * @author Richard Bair * @author Jasper Potts */public final class NimbusStyle extends SynthStyle { /* Keys and scales for large/small/mini components, based on Apples sizes */ public static final String LARGE_KEY = "large"; public static final String SMALL_KEY = "small"; public static final String MINI_KEY = "mini"; public static final double LARGE_SCALE = 1.15; public static final double SMALL_SCALE = 0.857; public static final double MINI_SCALE = 0.714; /** * Special constant used for performance reasons during the get() method. * If get() runs through all of the search locations and determines that * there is no value, then NULL will be placed into the values map. This way * on subsequent lookups it will simply extract NULL, see it, and return * null rather than continuing the lookup procedure. */ private static final Object NULL = '\0'; /** * <p>The Color to return from getColorForState if it would otherwise have * returned null.</p> * * <p>Returning null from getColorForState is a very bad thing, as it causes * the AWT peer for the component to install a SystemColor, which is not a * UIResource. As a result, if <code>null</code> is returned from * getColorForState, then thereafter the color is not updated for other * states or on LAF changes or updates. This DEFAULT_COLOR is used to * ensure that a ColorUIResource is always returned from * getColorForState.</p> */ private static final Color DEFAULT_COLOR = new ColorUIResource(Color.BLACK); /** * Simple Comparator for ordering the RuntimeStates according to their * rank. */ private static final Comparator<RuntimeState> STATE_COMPARATOR = new Comparator<RuntimeState>() { @Override public int compare(RuntimeState a, RuntimeState b) { return a.state - b.state; } }; /** * The prefix for the component or region that this NimbusStyle * represents. This prefix is used to lookup state in the UIManager. * It should be something like Button or Slider.Thumb or "MyButton" or * ComboBox."ComboBox.arrowButton" or "MyComboBox"."ComboBox.arrowButton" */ private String prefix; /** * The SynthPainter that will be returned from this NimbusStyle. The * SynthPainter returned will be a SynthPainterImpl, which will in turn * delegate back to this NimbusStyle for the proper Painter (not * SynthPainter) to use for painting the foreground, background, or border. */ private SynthPainter painter; /** * Data structure containing all of the defaults, insets, states, and other * values associated with this style. This instance refers to default * values, and are used when no overrides are discovered in the client * properties of a component. These values are lazily created on first * access. */ private Values values; /** * A temporary CacheKey used to perform lookups. This pattern avoids * creating useless garbage keys, or concatenating strings, etc. */ private CacheKey tmpKey = new CacheKey("", 0); /** * Some NimbusStyles are created for a specific component only. In Nimbus, * this happens whenever the component has as a client property a * UIDefaults which overrides (or supplements) those defaults found in * UIManager. */ private JComponent component; /** * Create a new NimbusStyle. Only the prefix must be supplied. At the * appropriate time, installDefaults will be called. At that point, all of * the state information will be pulled from UIManager and stored locally * within this style. * * @param prefix Something like Button or Slider.Thumb or * org.jdesktop.swingx.JXStatusBar or ComboBox."ComboBox.arrowButton" * @param c an optional reference to a component that this NimbusStyle * should be associated with. This is only used when the component * has Nimbus overrides registered in its client properties and * should be null otherwise. */ NimbusStyle(String prefix, JComponent c) { this.component = c; this.prefix = prefix; this.painter = new SynthPainterImpl(this); } /** * @InheritDoc * * Overridden to cause this style to populate itself with data from * UIDefaults, if necessary. */ @Override public void installDefaults(SynthContext ctx) { validate(); //delegate to the superclass to install defaults such as background, //foreground, font, and opaque onto the swing component. super.installDefaults(ctx); } static String parsePrefix(String key) { if (key == null) return null; boolean inquotes = false; for (int i=0; i<key.length(); i++) { char c = key.charAt(i); if (c == '"') { inquotes = !inquotes; } else if ((c == '[' || c == '.') && !inquotes) { return key.substring(0, i); } } return null; } /** * Called by NimbusLookAndFeel when the look and feel is being uninstalled. * Performs general cleanup of any app-context specific data. */ static void uninitialize() { // get the appcontext that we've stored data in AppContext ctx = AppContext.getAppContext(); // get the pcl stored in app context PropertyChangeListener pcl = (PropertyChangeListener) ctx.get("NimbusStyle.defaults.pcl"); // if the pcl exists, uninstall it from the UIDefaults tables if (pcl != null) { UIManager.getDefaults().removePropertyChangeListener(pcl); UIManager.getLookAndFeelDefaults().removePropertyChangeListener(pcl); } // clear out the compiled defaults ctx.put("NimbusStyle.defaults", null); } /** * Pulls data out of UIDefaults, if it has not done so already, and sets * up the internal state. */ private void validate() { // a non-null values object is the flag we use to determine whether // to reparse from UIManager. if (values != null) return; // reconstruct this NimbusStyle based on the entries in the UIManager // and possibly based on any overrides within the component's // client properties (assuming such a component exists and contains // any Nimbus.Overrides) values = new Values(); // the profiler revealed that a great deal of CPU time and useless // garbage was being produced by this method and the init method. One // culprit was the creation and reparsing of the entire UIDefaults // map on each call to this method where "values" was null. It turns // out this was happening a lot. // To remove this bottleneck, we store the compiled TreeMaps of defaults // in the appContext for reuse. It is nulled whenever the UIDefaults // changes and recomputed when necessary. final AppContext ctx = AppContext.getAppContext(); // fetch the defaults from the app context. If null, then create and // store the compiled defaults Map<String, TreeMap<String, Object>> compiledDefaults = (Map<String, TreeMap<String, Object>>) ctx.get("NimbusStyle.defaults"); if (compiledDefaults == null) { // the entire UIDefaults tables are parsed and compiled into // this map of maps. The key of the compiledDefaults is the // prefix for each style, while the value is a map of // keys->values for that prefix. compiledDefaults = new HashMap<String, TreeMap<String, Object>>(); // get all the defaults from UIManager.getDefaults() and put them // into the compiledDefaults compileDefaults(compiledDefaults, UIManager.getDefaults()); // This second statement pulls defaults from the laf defaults UIDefaults lafDefaults = UIManager.getLookAndFeelDefaults(); compileDefaults(compiledDefaults, lafDefaults); // if it has not already been done, add a listener to both // UIManager.getDefaults() and UIManager.getLookAndFeelDefaults(). PropertyChangeListener pcl = (PropertyChangeListener) ctx.get("NimbusStyle.defaults.pcl"); // if pcl is null, then it has not yet been registered with // the UIManager defaults for this app context if (pcl == null) { // create a PCL which will simply clear out the compiled // defaults from the app context, causing it to be recomputed // on subsequent passes pcl = new DefaultsListener(); // add the PCL to both defaults tables that we pay attention
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?