3261N/A * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 1173N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1173N/A * This code is free software; you can redistribute it and/or modify it 1173N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 1173N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 1173N/A * This code is distributed in the hope that it will be useful, but WITHOUT 1173N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1173N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1173N/A * version 2 for more details (a copy is included in the LICENSE file that 1173N/A * You should have received a copy of the GNU General Public License version 1173N/A * 2 along with this work; if not, write to the Free Software Foundation, 1173N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 1173N/A * <p>A SynthStyle implementation used by Nimbus. Each Region that has been 1173N/A * registered with the NimbusLookAndFeel will have an associated NimbusStyle. 1173N/A * Third party components that are registered with the NimbusLookAndFeel will 1173N/A * therefore be handed a NimbusStyle from the look and feel from the 1173N/A * #getStyle(JComponent, Region) method.</p> 1173N/A * <p>This class properly reads and retrieves values placed in the UIDefaults 1173N/A * according to the standard Nimbus naming conventions. It will create and 1173N/A * retrieve painters, fonts, colors, and other data stored there.</p> 1173N/A * <p>NimbusStyle also supports the ability to override settings on a per 1173N/A * component basis. NimbusStyle checks the component's client property map for 1173N/A * "Nimbus.Overrides". If the value associated with this key is an instance of 1173N/A * UIDefaults, then the values in that defaults table will override the standard 1173N/A * Nimbus defaults in UIManager, but for that component instance only.</p> 1173N/A * <p>Optionally, you may specify the client property 1173N/A * "Nimbus.Overrides.InheritDefaults". If true, this client property indicates 1173N/A * that the defaults located in UIManager should first be read, and then 1173N/A * replaced with defaults located in the component client properties. If false, 1173N/A * then only the defaults located in the component client property map will 1173N/A * be used. If not specified, it is assumed to be true.</p> 1173N/A * <p>You must specify "Nimbus.Overrides" for "Nimbus.Overrides.InheritDefaults" 1173N/A * to have any effect. "Nimbus.Overrides" indicates whether there are any 1173N/A * overrides, while "Nimbus.Overrides.InheritDefaults" indicates whether those 1173N/A * overrides should first be initialized with the defaults from UIManager.</p> 1173N/A * <p>The NimbusStyle is reloaded whenever a property change event is fired 1173N/A * for a component for "Nimbus.Overrides" or "Nimbus.Overrides.InheritDefaults". 1173N/A * So for example, setting a new UIDefaults on a component would cause the 1173N/A * style to be reloaded.</p> 1173N/A * <p>The values are only read out of UIManager once, and then cached. If 1173N/A * you need to read the values again (for example, if the UI is being reloaded), 1173N/A * then discard this NimbusStyle and read a new one from NimbusLookAndFeel 1173N/A * using NimbusLookAndFeel.getStyle.</p> 1173N/A * <p>The primary API of interest in this class for 3rd party component authors 1173N/A * are the three methods which retrieve painters: #getBackgroundPainter, 1173N/A * #getForegroundPainter, and #getBorderPainter.</p> 1173N/A * <p>NimbusStyle allows you to specify custom states, or modify the order of 1173N/A * states. Synth (and thus Nimbus) has the concept of a "state". For example, 1173N/A * a JButton might be in the "MOUSE_OVER" state, or the "ENABLED" state, or the 1173N/A * "DISABLED" state. These are all "standard" states which are defined in synth, 1173N/A * and which apply to all synth Regions.</p> 1173N/A * <p>Sometimes, however, you need to have a custom state. For example, you 1173N/A * want JButton to render differently if it's parent is a JToolbar. In Nimbus, 1173N/A * you specify these custom states by including a special key in UIDefaults. 1173N/A * The following UIDefaults entries define three states for this button:</p> 1173N/A * JButton.States = Enabled, Disabled, Toolbar 1173N/A * JButton[Enabled].backgroundPainter = somePainter 1173N/A * JButton[Disabled].background = BLUE 1173N/A * JButton[Toolbar].backgroundPainter = someOtherPaint 1173N/A * <p>As you can see, the <code>JButton.States</code> entry lists the states 1173N/A * that the JButton style will support. You then specify the settings for 1173N/A * each state. If you do not specify the <code>JButton.States</code> entry, 1173N/A * then the standard Synth states will be assumed. If you specify the entry 1173N/A * but the list of states is empty or null, then the standard synth states 1173N/A * Special constant used for performance reasons during the get() method. 1173N/A * If get() runs through all of the search locations and determines that 1173N/A * there is no value, then NULL will be placed into the values map. This way 1173N/A * on subsequent lookups it will simply extract NULL, see it, and return 1173N/A * null rather than continuing the lookup procedure. 1173N/A * <p>The Color to return from getColorForState if it would otherwise have 1173N/A * <p>Returning null from getColorForState is a very bad thing, as it causes 1173N/A * the AWT peer for the component to install a SystemColor, which is not a 1173N/A * UIResource. As a result, if <code>null</code> is returned from 1173N/A * getColorForState, then thereafter the color is not updated for other 1173N/A * states or on LAF changes or updates. This DEFAULT_COLOR is used to 1173N/A * ensure that a ColorUIResource is always returned from 1173N/A * Simple Comparator for ordering the RuntimeStates according to their 1173N/A * The prefix for the component or region that this NimbusStyle 1173N/A * represents. This prefix is used to lookup state in the UIManager. 1173N/A * It should be something like Button or Slider.Thumb or "MyButton" or 1173N/A * ComboBox."ComboBox.arrowButton" or "MyComboBox"."ComboBox.arrowButton" 1173N/A * The SynthPainter that will be returned from this NimbusStyle. The 1173N/A * SynthPainter returned will be a SynthPainterImpl, which will in turn 1173N/A * delegate back to this NimbusStyle for the proper Painter (not 1173N/A * SynthPainter) to use for painting the foreground, background, or border. 1173N/A * Data structure containing all of the defaults, insets, states, and other 1173N/A * values associated with this style. This instance refers to default 1173N/A * values, and are used when no overrides are discovered in the client 1173N/A * properties of a component. These values are lazily created on first 1173N/A * A temporary CacheKey used to perform lookups. This pattern avoids 1173N/A * creating useless garbage keys, or concatenating strings, etc. 1173N/A * Some NimbusStyles are created for a specific component only. In Nimbus, 1173N/A * this happens whenever the component has as a client property a 1173N/A * UIDefaults which overrides (or supplements) those defaults found in 1173N/A * Create a new NimbusStyle. Only the prefix must be supplied. At the 1173N/A * appropriate time, installDefaults will be called. At that point, all of 1173N/A * the state information will be pulled from UIManager and stored locally 1173N/A * @param prefix Something like Button or Slider.Thumb or 1173N/A * org.jdesktop.swingx.JXStatusBar or ComboBox."ComboBox.arrowButton" 1173N/A * @param c an optional reference to a component that this NimbusStyle 1173N/A * should be associated with. This is only used when the component 1173N/A * has Nimbus overrides registered in its client properties and 1173N/A * should be null otherwise. 1173N/A * Overridden to cause this style to populate itself with data from 1173N/A * UIDefaults, if necessary. 1173N/A //delegate to the superclass to install defaults such as background, 1173N/A //foreground, font, and opaque onto the swing component. 1173N/A * Pulls data out of UIDefaults, if it has not done so already, and sets 1173N/A // a non-null values object is the flag we use to determine whether 1173N/A // to reparse from UIManager. 1173N/A // reconstruct this NimbusStyle based on the entries in the UIManager 1173N/A // and possibly based on any overrides within the component's 1173N/A // client properties (assuming such a component exists and contains 1173N/A // inspect the client properties for the key "Nimbus.Overrides". If the 1173N/A // value is an instance of UIDefaults, then these defaults are used 1173N/A // in place of, or in addition to, the defaults in UIManager. 2337N/A // We know component.get() is non-null here, as if the component 2337N/A // were GC'ed, we wouldn't be processing its style. 1173N/A "Nimbus.Overrides.InheritDefaults");
1173N/A //a list of the different types of states used by this style. This 1173N/A //list may contain only "standard" states (those defined by Synth), 1173N/A //or it may contain custom states, or it may contain only "standard" 1173N/A //states but list them in a non-standard order. 1173N/A //a map of state name to code 1173N/A //This is a list of runtime "state" context objects. These contain 1173N/A //the values associated with each state. 1173N/A //determine whether there are any custom states, or custom state 1173N/A //order. If so, then read all those custom states and define the 1173N/A //"values" stateTypes to be a non-null array. 1173N/A //Otherwise, let the "values" stateTypes be null to indicate that 1173N/A //there are no custom states or custom state ordering 1173N/A //this is a non-standard state name, so look for the 1173N/A //custom state associated with it 1173N/A //if there were any states defined, then set the stateTypes array 1173N/A //to be non-null. Otherwise, leave it null (meaning, use the 1173N/A //assign codes for each of the state types 1173N/A //since there were no custom states defined, setup the list of 1173N/A //standard synth states. Note that the "v.stateTypes" is not 1173N/A //being set here, indicating that at runtime the state selection 1173N/A //routines should use standard synth states instead of custom 1173N/A //states. I do need to popuplate this temp list now though, so that 1173N/A //the remainder of this method will function as expected. 1173N/A //assign codes for the states 1173N/A //Now iterate over all the keys in the defaults table 1173N/A //The key is something like JButton.Enabled.backgroundPainter, 1173N/A //or JButton.States, or JButton.background. 1173N/A //Remove the "JButton." portion of the key 1173N/A //if there is a " or : then we skip it because it is a subregion 1173N/A //At this point, temp may be any of the following: 1173N/A //[Enabled+MouseOver].background 1173N/A //parse out the states and the property 1173N/A //there is not a state string, so property = temp 1173N/A //now that I have the state (if any) and the property, get the 1173N/A //value for this property and install it where it belongs 1173N/A //there was no state, just a property. Check for the custom 1173N/A //"contentMargins" property (which is handled specially by 1173N/A //in which case it is not a real property and should be ignored. 1173N/A //otherwise, assume it is a property and install it on the 1173N/A //it is possible that the developer has a malformed UIDefaults 1173N/A //entry, such that something was specified in the place of 1173N/A //the State portion of the key but it wasn't a state. In this 1173N/A //case, skip will be set to true 1173N/A //this variable keeps track of the int value associated with 1173N/A //the state. See SynthState for details. 1173N/A //Multiple states may be specified in the string, such as 1173N/A //For each state, we need to find the State object associated 1173N/A //with it, or skip it if it cannot be found. 1173N/A //Was not a state. Maybe it was a subregion or something 1173N/A //find the RuntimeState for this State 1173N/A //couldn't find the runtime state, so create a new one 1173N/A //check for a couple special properties, such as for the 1173N/A //painters. If these are found, then set the specially on 1173N/A //the runtime state. Else, it is just a normal property, 1173N/A //so put it in the UIDefaults associated with that runtime 1173N/A //now that I've collected all the runtime states, I'll sort them based 1173N/A //on their integer "state" (see SynthState for how this works). 1173N/A //finally, set the array of runtime states on the values object 1173N/A * Overridden to cause this style to populate itself with data from 1173N/A * UIDefaults, if necessary. 1173N/A // The key "JComponent.sizeVariant" is used to match Apple's LAF 1173N/A * <p>Overridden to cause this style to populate itself with data from 1173N/A * UIDefaults, if necessary.</p> 1173N/A * <p>In addition, NimbusStyle handles ColorTypes slightly differently from 1173N/A * <li>ColorType.BACKGROUND will equate to the color stored in UIDefaults 1173N/A * <li>ColorType.TEXT_BACKGROUND will equate to the color stored in 1173N/A * UIDefaults named "textBackground".</li> 1173N/A * <li>ColorType.FOREGROUND will equate to the color stored in UIDefaults 1173N/A * named "textForeground".</li> 1173N/A * <li>ColorType.TEXT_FOREGROUND will equate to the color stored in 1173N/A * UIDefaults named "textForeground".</li> 1173N/A //map FOREGROUND as TEXT_FOREGROUND 1173N/A //if all else fails, return a default color (which is a ColorUIResource) 1173N/A * Overridden to cause this style to populate itself with data from 1173N/A * UIDefaults, if necessary. If a value named "font" is not found in 1173N/A * UIDefaults, then the "defaultFont" font in UIDefaults will be returned 1173N/A // The key "JComponent.sizeVariant" is used to match Apple's LAF 1173N/A * Returns the SynthPainter for this style, which ends up delegating to 1173N/A * the Painters installed in this style. 1173N/A * Overridden to cause this style to populate itself with data from 1173N/A * UIDefaults, if necessary. If opacity is not specified in UI defaults, 1173N/A * then it defaults to being non-opaque. 1173N/A // Force Table CellRenderers to be opaque 1173N/A * <p>Overridden to cause this style to populate itself with data from 1173N/A * UIDefaults, if necessary.</p> 1173N/A * <p>Properties in UIDefaults may be specified in a chained manner. For 1173N/A * Button.Enabled.foreground 1173N/A * Button.Enabled+Selected.background 1173N/A * <p>In this example, suppose you were in the Enabled+Selected state and 1173N/A * searched for "foreground". In this case, we first check for 1173N/A * Button.Enabled+Selected.foreground, but no such color exists. We then 1173N/A * fall back to the next valid state, in this case, 1173N/A * Button.Enabled.foreground, and have a match. So we return it.</p> 1173N/A * <p>Again, if we were in the state Enabled and looked for "background", we 1173N/A * wouldn't find it in Button.Enabled, or in Button, but would at the top 1173N/A * level in UIManager. So we return that value.</p> 1173N/A * <p>One special note: the "key" passed to this method could be of the form 1173N/A * "background" or "Button.background" where "Button" equals the prefix 1173N/A * passed to the NimbusStyle constructor. In either case, it looks for 1173N/A * @param key must not be null 1173N/A // strip off the prefix, if there is one. 1173N/A // Search exact matching states and then lesser matching states 1173N/A // Search UIManager Defaults 1173N/A // Search Synth Defaults for InputMaps 1173N/A // if all we got was a null, store this fact for later use 1173N/A * Gets the appropriate background Painter, if there is one, for the state 1173N/A * specified in the given SynthContext. This method does appropriate 1173N/A * fallback searching, as described in #get. 1173N/A * @param ctx The SynthContext. Must not be null. 1173N/A * @return The background painter associated for the given state, or null if 1173N/A // not in cache, so lookup and store in cache 1173N/A * Gets the appropriate foreground Painter, if there is one, for the state 1173N/A * specified in the given SynthContext. This method does appropriate 1173N/A * fallback searching, as described in #get. 1173N/A * @param ctx The SynthContext. Must not be null. 1173N/A * @return The foreground painter associated for the given state, or null if 1173N/A // not in cache, so lookup and store in cache 1173N/A * Gets the appropriate border Painter, if there is one, for the state 1173N/A * specified in the given SynthContext. This method does appropriate 1173N/A * fallback searching, as described in #get. 1173N/A * @param ctx The SynthContext. Must not be null. 1173N/A * @return The border painter associated for the given state, or null if 1173N/A // not in cache, so lookup and store in cache 1173N/A * Utility method which returns the proper Values based on the given 1173N/A * SynthContext. Ensures that parsing of the values has occurred, or 1173N/A * @param ctx The SynthContext 1173N/A * @return a non-null values reference 1173N/A * Simple utility method that searchs the given array of Strings for the 1173N/A * given string. This method is only called from getExtendedState if 1173N/A * the developer has specified a specific state for the component to be 1173N/A * in (ie, has "wedged" the component in that state) by specifying 1173N/A * they client property "Nimbus.State". 1173N/A * @param names a non-null array of strings 1173N/A * @param name the name to look for in the array 1173N/A * @return true or false based on whether the given name is in the array 1173N/A * <p>Gets the extended state for a given synth context. Nimbus supports the 1173N/A * ability to define custom states. The algorithm used for choosing what 1173N/A * style information to use for a given state requires a single integer 1173N/A * bit string where each bit in the integer represents a different state 1173N/A * that the component is in. This method uses the componentState as 1173N/A * reported in the SynthContext, in addition to custom states, to determine 1173N/A * what this extended state is.</p> 1173N/A * <p>In addition, this method checks the component in the given context 1173N/A * for a client property called "Nimbus.State". If one exists, then it will 1173N/A * decompose the String associated with that property to determine what 1173N/A * state to return. In this way, the developer can force a component to be 1173N/A * in a specific state, regardless of what the "real" state of the component 1173N/A * <p>The string associated with "Nimbus.State" would be of the form: 1173N/A * <pre>Enabled+CustomState+MouseOver</pre></p> 1173N/A //check for the Nimbus.State client property 1173N/A //Performance NOTE: getClientProperty ends up inside a synchronized 1173N/A //block, so there is some potential for performance issues here, however 1173N/A //I'm not certain that there is one on a modern VM. 1173N/A //if there are no custom states defined, then simply return the 1173N/A //state that Synth reported 1173N/A //there are custom states on this values, so I'll have to iterate 1173N/A //over them all and return a custom extended state 1173N/A * <p>Gets the RuntimeState that most closely matches the state in the given 1173N/A * context, but is less specific than the given "lastState". Essentially, 1173N/A * this allows you to search for the next best state.</p> 1173N/A * <p>For example, if you had the following three states: 1173N/A * And you wanted to find the state that best represented 1173N/A * ENABLED+PRESSED+FOCUSED and <code>lastState</code> was null (or an 1173N/A * empty array, or an array with a single int with index == -1), then 1173N/A * Enabled+Pressed would be returned. If you then call this method again but 1173N/A * pass the index of Enabled+Pressed as the "lastState", then 1173N/A * Enabled would be returned. If you call this method a third time and pass 1173N/A * the index of Enabled in as the <code>lastState</code>, then null would be 1173N/A * <p>The actual code path for determining the proper state is the same as 1173N/A * @param lastState a 1 element array, allowing me to do pass-by-reference. 1173N/A // Use the StateInfo with the most bits that matches that of state. 1173N/A // If there are none, then fallback to 1173N/A // the StateInfo with a state of 0, indicating it'll match anything. 1173N/A // Consider if we have 3 StateInfos a, b and c with states: 1173N/A // SELECTED, SELECTED | ENABLED, 0 1173N/A // SELECTED | ENABLED | FOCUSED b 1173N/A //if xstate is 0, then search for the runtime state with component 1173N/A //state of 0. That is, find the exact match and return it. 1173N/A //an exact match couldn't be found, so there was no match. 1173N/A //xstate is some value != 0 1173N/A //determine from which index to start looking. If lastState[0] is -1 1173N/A //then we know to start from the end of the state array. Otherwise, 1173N/A //we start at the lastIndex - 1. 1173N/A // This is key, we need to make sure all bits of the 1173N/A // StateInfo match, otherwise a StateInfo with 1173N/A // SELECTED | ENABLED would match ENABLED, which we 1173N/A // This comes from BigInteger.bitCnt 1173N/A * Contains values such as the UIDefaults and painters asssociated with 1173N/A * a state. Whereas <code>State</code> represents a distinct state that a 1173N/A * component can be in (such as Enabled), this class represents the colors, 1173N/A * fonts, painters, etc associated with some state for this 1173N/A * Essentially a struct of data for a style. A default instance of this 1173N/A * class is used by NimbusStyle. Additional instances exist for each 1173N/A * component that has overrides. 1173N/A * The list of State types. A State represents a type of state, such 1173N/A * as Enabled, Default, WindowFocused, etc. These can be custom states. 1173N/A * The list of actual runtime state representations. These can represent things such 1173N/A * as Enabled + Focused. Thus, they differ from States in that they contain 1173N/A * several states together, and have associated properties, data, etc. 1173N/A * The content margins for this region. 1173N/A * Simple cache. After a value has been looked up, it is stored 1173N/A * in this cache for later retrieval. The key is a concatenation of 1173N/A * the property being looked up, two dollar signs, and the extended 1173N/A * This implementation presupposes that key is never null and that 1173N/A * the two keys being checked for equality are never null