nimbusstyle.java
来自「Mobile 应用程序使用 Java Micro Edition (Java M」· Java 代码 · 共 1,243 行 · 第 1/4 页
JAVA
1,243 行
// to, so that if the UIDefaults are updated, then the // precompiled defaults will be cleared from the app context // and recomputed on subsequent passes UIManager.getDefaults().addPropertyChangeListener(pcl); UIManager.getLookAndFeelDefaults().addPropertyChangeListener(pcl); // save the PCL to the app context as a marker indicating // that the PCL has been registered so we don't end up adding // more than one listener to the UIDefaults tables. ctx.put("NimbusStyle.defaults.pcl", pcl); } // store the defaults for reuse ctx.put("NimbusStyle.defaults", compiledDefaults); } TreeMap<String, Object> defaults = compiledDefaults.get(prefix); // inspect the client properties for the key "Nimbus.Overrides". If the // value is an instance of UIDefaults, then these defaults are used // in place of, or in addition to, the defaults in UIManager. if (component != null) { Object o = component.getClientProperty("Nimbus.Overrides"); if (o instanceof UIDefaults) { Object i = component.getClientProperty( "Nimbus.Overrides.InheritDefaults"); boolean inherit = i instanceof Boolean ? (Boolean)i : true; UIDefaults d = (UIDefaults)o; TreeMap<String, Object> map = new TreeMap<String, Object>(); for (Object obj : d.keySet()) { if (obj instanceof String) { String key = (String)obj; if (key.startsWith(prefix)) { map.put(key, d.get(key)); } } } if (inherit) { defaults.putAll(map); } else { defaults = map; } } } // Now that I've accumulated all the defaults pertaining to this // style, call init which will read these defaults and configure // the default "values". init(values, defaults); } /** * Iterates over all the keys in the specified UIDefaults and compiles * those keys into the comiledDefaults data structure. It relies on * parsing the "prefix" out of the key. If the key is not a String or is * null then it is ignored. In all other cases a prefix is parsed out * (even if that prefix is the empty String or is a "fake" prefix. That * is, suppose you had a key Foo~~MySpecial.KeyThing~~. In this case this * is not a Nimbus formatted key, but we don't care, we treat it as if it * is. This doesn't pose any harm, it will simply never be used). * * @param compiledDefaults * @param d */ private void compileDefaults( Map<String, TreeMap<String,Object>> compiledDefaults, UIDefaults d) { for (Object obj : new HashSet(d.keySet())) { if (obj instanceof String) { String key = (String)obj; String kp = parsePrefix(key); if (kp == null) continue; TreeMap<String,Object> map = compiledDefaults.get(kp); if (map == null) { map = new TreeMap<String,Object>(); compiledDefaults.put(kp, map); } map.put(key, d.get(key)); } } } /** * Initializes the given <code>Values</code> object with the defaults * contained in the given TreeMap. * * @param v The Values object to be initialized * @param myDefaults a map of UIDefaults to use in initializing the Values. * This map must contain only keys associated with this Style. */ private void init(Values v, TreeMap<String, Object> myDefaults) { //a list of the different types of states used by this style. This //list may contain only "standard" states (those defined by Synth), //or it may contain custom states, or it may contain only "standard" //states but list them in a non-standard order. List<State> states = new ArrayList<State>(); //a map of state name to code Map<String,Integer> stateCodes = new HashMap<String,Integer>(); //This is a list of runtime "state" context objects. These contain //the values associated with each state. List<RuntimeState> runtimeStates = new ArrayList<RuntimeState>(); //determine whether there are any custom states, or custom state //order. If so, then read all those custom states and define the //"values" stateTypes to be a non-null array. //Otherwise, let the "values" stateTypes be null to indicate that //there are no custom states or custom state ordering String statesString = (String)myDefaults.get(prefix + ".States"); if (statesString != null) { String s[] = statesString.split(","); for (int i=0; i<s.length; i++) { s[i] = s[i].trim(); if (!State.isStandardStateName(s[i])) { //this is a non-standard state name, so look for the //custom state associated with it String stateName = prefix + "." + s[i]; State customState = (State)myDefaults.get(stateName); if (customState != null) { states.add(customState); } } else { states.add(State.getStandardState(s[i])); } } //if there were any states defined, then set the stateTypes array //to be non-null. Otherwise, leave it null (meaning, use the //standard synth states). if (states.size() > 0) { v.stateTypes = states.toArray(new State[states.size()]); } //assign codes for each of the state types int code = 1; for (State state : states) { stateCodes.put(state.getName(), code); code <<= 1; } } else { //since there were no custom states defined, setup the list of //standard synth states. Note that the "v.stateTypes" is not //being set here, indicating that at runtime the state selection //routines should use standard synth states instead of custom //states. I do need to popuplate this temp list now though, so that //the remainder of this method will function as expected. states.add(State.Enabled); states.add(State.MouseOver); states.add(State.Pressed); states.add(State.Disabled); states.add(State.Focused); states.add(State.Selected); states.add(State.Default); //assign codes for the states stateCodes.put("Enabled", ENABLED); stateCodes.put("MouseOver", MOUSE_OVER); stateCodes.put("Pressed", PRESSED); stateCodes.put("Disabled", DISABLED); stateCodes.put("Focused", FOCUSED); stateCodes.put("Selected", SELECTED); stateCodes.put("Default", DEFAULT); } //Now iterate over all the keys in the defaults table for (String key : myDefaults.keySet()) { //The key is something like JButton.Enabled.backgroundPainter, //or JButton.States, or JButton.background. //Remove the "JButton." portion of the key String temp = key.substring(prefix.length()); //if there is a " or : then we skip it because it is a subregion //of some kind if (temp.indexOf('"') != -1 || temp.indexOf(':') != -1) continue; //remove the separator temp = temp.substring(1); //At this point, temp may be any of the following: //background //[Enabled].background //[Enabled+MouseOver].background //property.foo //parse out the states and the property String stateString = null; String property = null; int bracketIndex = temp.indexOf(']'); if (bracketIndex < 0) { //there is not a state string, so property = temp property = temp; } else { stateString = temp.substring(0, bracketIndex); property = temp.substring(bracketIndex + 2); } //now that I have the state (if any) and the property, get the //value for this property and install it where it belongs if (stateString == null) { //there was no state, just a property. Check for the custom //"contentMargins" property (which is handled specially by //Synth/Nimbus). Also check for the property being "States", //in which case it is not a real property and should be ignored. //otherwise, assume it is a property and install it on the //values object if ("contentMargins".equals(property)) { v.contentMargins = (Insets)myDefaults.get(key); } else if ("States".equals(property)) { //ignore } else { v.defaults.put(property, myDefaults.get(key)); } } else { //it is possible that the developer has a malformed UIDefaults //entry, such that something was specified in the place of //the State portion of the key but it wasn't a state. In this //case, skip will be set to true boolean skip = false; //this variable keeps track of the int value associated with //the state. See SynthState for details. int componentState = 0; //Multiple states may be specified in the string, such as //Enabled+MouseOver String[] stateParts = stateString.split("\\+"); //For each state, we need to find the State object associated //with it, or skip it if it cannot be found. for (String s : stateParts) { if (stateCodes.containsKey(s)) { componentState |= stateCodes.get(s); } else { //Was not a state. Maybe it was a subregion or something //skip it. skip = true; break; } } if (skip) continue; //find the RuntimeState for this State RuntimeState rs = null; for (RuntimeState s : runtimeStates) { if (s.state == componentState) { rs = s; break; } } //couldn't find the runtime state, so create a new one if (rs == null) { rs = new RuntimeState(componentState, stateString); runtimeStates.add(rs); } //check for a couple special properties, such as for the //painters. If these are found, then set the specially on //the runtime state. Else, it is just a normal property, //so put it in the UIDefaults associated with that runtime //state if ("backgroundPainter".equals(property)) { rs.backgroundPainter = (Painter)myDefaults.get(key); } else if ("foregroundPainter".equals(property)) { rs.foregroundPainter = (Painter) myDefaults.get(key); } else if ("borderPainter".equals(property)) { rs.borderPainter = (Painter) myDefaults.get(key); } else { rs.defaults.put(property, myDefaults.get(key)); } } } //now that I've collected all the runtime states, I'll sort them based //on their integer "state" (see SynthState for how this works). Collections.sort(runtimeStates, STATE_COMPARATOR); //finally, set the array of runtime states on the values object v.states = runtimeStates.toArray(new RuntimeState[runtimeStates.size()]); } /** * @InheritDoc * * Overridden to cause this style to populate itself with data from * UIDefaults, if necessary. */ @Override public Insets getInsets(SynthContext ctx, Insets in) { if (in == null) { in = new Insets(0, 0, 0, 0); } Values v = getValues(ctx); if (v.contentMargins == null) { in.bottom = in.top = in.left = in.right = 0; return in; } else { in.bottom = v.contentMargins.bottom; in.top = v.contentMargins.top; in.left = v.contentMargins.left; in.right = v.contentMargins.right; // Account for scale // The key "JComponent.sizeVariant" is used to match Apple's LAF String scaleKey = (String)ctx.getComponent().getClientProperty( "JComponent.sizeVariant"); if (scaleKey != null){ if (LARGE_KEY.equals(scaleKey)){ in.bottom *= LARGE_SCALE; in.top *= LARGE_SCALE; in.left *= LARGE_SCALE; in.right *= LARGE_SCALE; } else if (SMALL_KEY.equals(scaleKey)){ in.bottom *= SMALL_SCALE; in.top *= SMALL_SCALE; in.left *= SMALL_SCALE; in.right *= SMALL_SCALE; } else if (MINI_KEY.equals(scaleKey)){
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?