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 + -
显示快捷键?