/* * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */package sun.swing.plaf.synth; import javax.swing.plaf.synth.*;import java.awt.*;import java.util.*;import javax.swing.*;import javax.swing.border.Border;import javax.swing.plaf.*; /** * Default implementation of SynthStyle. Has setters for the various * SynthStyle methods. Many of the properties can be specified for all states, * using SynthStyle directly, or a specific state using one of the StateInfo * methods. * <p> * Beyond the constructor a subclass should override the <code>addTo</code> * and <code>clone</code> methods, these are used when the Styles are being * merged into a resulting style. * * @author Scott Violet */public class DefaultSynthStyle extends SynthStyle implements Cloneable { private static final String PENDING = "Pending"; /** * Should the component be opaque? */ private boolean opaque; /** * Insets. */ private Insets insets; /** * Information specific to ComponentState. */ private StateInfo[] states; /** * User specific data. */ private Map data; /** * Font to use if there is no matching StateInfo, or the StateInfo doesn't * define one. */ private Font font; /** * SynthGraphics, may be null. */ private SynthGraphicsUtils synthGraphics; /** * Painter to use if the StateInfo doesn't have one. */ private SynthPainter painter; /** * Nullary constructor, intended for subclassers. */ public DefaultSynthStyle() { } /** * Creates a new DefaultSynthStyle that is a copy of the passed in * style. Any StateInfo's of the passed in style are clonsed as well. * * @param style Style to duplicate */ public DefaultSynthStyle(DefaultSynthStyle style) { opaque = style.opaque; if (style.insets != null) { insets = new Insets(style.insets.top, style.insets.left, style.insets.bottom, style.insets.right); } if (style.states != null) { states = new StateInfo[style.states.length]; for (int counter = style.states.length - 1; counter >= 0; counter--) { states[counter] = (StateInfo)style.states[counter].clone(); } } if (style.data != null) { data = new HashMap(); data.putAll(style.data); } font = style.font; synthGraphics = style.synthGraphics; painter = style.painter; } /** * Creates a new DefaultSynthStyle. * * @param insets Insets for the Style * @param opaque Whether or not the background is completely painted in * an opaque color * @param states StateInfos describing properties per state * @param data Style specific data. */ public DefaultSynthStyle(Insets insets, boolean opaque, StateInfo[] states, Map data) { this.insets = insets; this.opaque = opaque; this.states = states; this.data = data; } public Color getColor(SynthContext context, ColorType type) { return getColor(context.getComponent(), context.getRegion(), context.getComponentState(), type); } public Color getColor(JComponent c, Region id, int state, ColorType type) { // For the enabled state, prefer the widget's colors if (!id.isSubregion() && state == SynthConstants.ENABLED) { if (type == ColorType.BACKGROUND) { return c.getBackground(); } else if (type == ColorType.FOREGROUND) { return c.getForeground(); } else if (type == ColorType.TEXT_FOREGROUND) { // If getForeground returns a non-UIResource it means the // developer has explicitly set the foreground, use it over // that of TEXT_FOREGROUND as that is typically the expected // behavior. Color color = c.getForeground(); if (!(color instanceof UIResource)) { return color; } } } // Then use what we've locally defined Color color = getColorForState(c, id, state, type); if (color == null) { // No color, fallback to that of the widget. if (type == ColorType.BACKGROUND || type == ColorType.TEXT_BACKGROUND) { return c.getBackground(); } else if (type == ColorType.FOREGROUND || type == ColorType.TEXT_FOREGROUND) { return c.getForeground(); } } return color; } protected Color getColorForState(SynthContext context, ColorType type) { return getColorForState(context.getComponent(), context.getRegion(), context.getComponentState(), type); } /** * Returns the color for the specified state. * * @param c JComponent the style is associated with * @param id Region identifier * @param state State of the region. * @param type Type of color being requested. * @return Color to render with */ protected Color getColorForState(JComponent c, Region id, int state, ColorType type) { // Use the best state. StateInfo si = getStateInfo(state); Color color; if (si != null && (color = si.getColor(type)) != null) { return color; } if (si == null || si.getComponentState() != 0) { si = getStateInfo(0); if (si != null) { return si.getColor(type); } } return null; } /** * Sets the font that is used if there is no matching StateInfo, or * it does not define a font. * * @param font Font to use for rendering */ public void setFont(Font font) { this.font = font; } public Font getFont(SynthContext state) { return getFont(state.getComponent(), state.getRegion(), state.getComponentState()); } public Font getFont(JComponent c, Region id, int state) { if (!id.isSubregion() && state == SynthConstants.ENABLED) { return c.getFont(); } Font cFont = c.getFont(); if (cFont != null && !(cFont instanceof UIResource)) { return cFont; } return getFontForState(c, id, state); } /** * Returns the font for the specified state. This should NOT callback * to the JComponent. * * @param c JComponent the style is associated with * @param id Region identifier * @param state State of the region. * @return Font to render with */ protected Font getFontForState(JComponent c, Region id, int state) { if (c == null) { return this.font; } // First pass, look for the best match StateInfo si = getStateInfo(state); Font font; if (si != null && (font = si.getFont()) != null) { return font; } if (si == null || si.getComponentState() != 0) { si = getStateInfo(0); if (si != null && (font = si.getFont()) != null) { return font; } } // Fallback font. return this.font; } protected Font getFontForState(SynthContext context) { return getFontForState(context.getComponent(), context.getRegion(), context.getComponentState()); } /** * Sets the SynthGraphicsUtils that will be used for rendering. * * @param graphics SynthGraphics */ public void setGraphicsUtils(SynthGraphicsUtils graphics) { this.synthGraphics = graphics; } /** * Returns a SynthGraphicsUtils. * * @param context SynthContext indentifying requestor * @return SynthGraphicsUtils */ public SynthGraphicsUtils getGraphicsUtils(SynthContext context) { if (synthGraphics == null) { return super.getGraphicsUtils(context); } return synthGraphics; } /** * Sets the insets. * * @param Insets. */ public void setInsets(Insets insets) { this.insets = insets; } /** * Returns the Insets. If <code>to</code> is non-null the resulting * insets will be placed in it, otherwise a new Insets object will be * created and returned. * * @param context SynthContext indentifying requestor * @param to Where to place Insets * @return Insets. */ public Insets getInsets(SynthContext state, Insets to) { if (to == null) { to = new Insets(0, 0, 0, 0); } if (insets != null) { to.left = insets.left; to.right = insets.right; to.top = insets.top; to.bottom = insets.bottom; } else { to.left = to.right = to.top = to.bottom = 0; } return to; } /** * Sets the Painter to use for the border. * * @param painter Painter for the Border. */ public void setPainter(SynthPainter painter) { this.painter = painter; } /** * Returns the Painter for the passed in Component. This may return null. * * @param ss SynthContext indentifying requestor * @return Painter for the border */ public SynthPainter getPainter(SynthContext ss) { return painter; } /** * Sets whether or not the JComponent should be opaque. * * @param opaque Whether or not the JComponent should be opaque. */ public void setOpaque(boolean opaque) { this.opaque = opaque; } /** * Returns the value to initialize the opacity property of the Component * to. A Style should NOT assume the opacity will remain this value, the * developer may reset it or override it. * * @param ss SynthContext indentifying requestor * @return opaque Whether or not the JComponent is opaque. */ public boolean isOpaque(SynthContext ss) { return opaque; } /** * Sets style specific values. This does NOT copy the data, it * assigns it directly to this Style. * * @param data Style specific values */ public void setData(Map data) { this.data = data; } /** * Returns the style specific data. * * @return Style specific data. */ public Map getData() { return data; } /** * Getter for a region specific style property. * * @param state SynthContext indentifying requestor * @param key Property being requested. * @return Value of the named property */ public Object get(SynthContext state, Object key) { // Look for the best match StateInfo si = getStateInfo(state.getComponentState()); if (si != null && si.getData() != null && getKeyFromData(si.getData(), key) != null) { return getKeyFromData(si.getData(), key); } si = getStateInfo(0); if (si != null && si.getData() != null && getKeyFromData(si.getData(), key) != null) { return getKeyFromData(si.getData(), key); } if(getKeyFromData(data, key) != null) return getKeyFromData(data, key); return getDefaultValue(state, key); } private Object getKeyFromData(Map stateData, Object key) { Object value = null; if (stateData != null) { synchronized(stateData) { value = stateData.get(key); } while (value == PENDING) { synchronized(stateData) { try { stateData.wait(); } catch (InterruptedException ie) {} value = stateData.get(key); } } if (value instanceof UIDefaults.LazyValue) { synchronized(stateData) { stateData.put(key, PENDING); } value = ((UIDefaults.LazyValue)value).createValue(null); synchronized(stateData) { stateData.put(key, value); stateData.notifyAll(); } } } return value; } /** * Returns the default value for a particular property. This is only * invoked if this style doesn't define a property for <code>key</code>. * * @param state SynthContext indentifying requestor * @param key Property being requested. * @return Value of the named property */ public Object getDefaultValue(SynthContext context, Object key) { return super.get(context, key); } /** * Creates a clone of this style. * * @return Clone of this style */ public Object clone() { DefaultSynthStyle style; try { style = (DefaultSynthStyle)super.clone(); } catch (CloneNotSupportedException cnse) { return null; } if (states != null) { style.states = new StateInfo[states.length]; for (int counter = states.length - 1; counter >= 0; counter--) { style.states[counter] = (StateInfo)states[counter].clone(); } } if (data != null) { style.data = new HashMap(); style.data.putAll(data); } return style; } /** * Merges the contents of this Style with that of the passed in Style, * returning the resulting merged syle. Properties of this * <code>DefaultSynthStyle</code> will take precedence over those of the * passed in <code>DefaultSynthStyle</code>. For example, if this * style specifics a non-null font, the returned style will have its * font so to that regardless of the <code>style</code>'s font. * * @param style Style to add our styles to * @return Merged style. */ public DefaultSynthStyle addTo(DefaultSynthStyle style) { if (insets != null) { style.insets = this.insets; } if (font != null) { style.font = this.font; } if (painter != null) { style.painter = this.painter; } if (synthGraphics != null) { style.synthGraphics = this.synthGraphics; } style.opaque = opaque; if (states != null) { if (style.states == null) { style.states = new StateInfo[states.length]; for (int counter = states.length - 1; counter >= 0; counter--){ if (states[counter] != null) {Lines 1–500 of 927. Load more
/* * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.swing.plaf.synth; import javax.swing.plaf.synth.*; import java.awt.*; import java.util.*; import javax.swing.*; import javax.swing.border.Border; import javax.swing.plaf.*; /** * Default implementation of SynthStyle. Has setters for the various * SynthStyle methods. Many of the properties can be specified for all states, * using SynthStyle directly, or a specific state using one of the StateInfo * methods. * <p> * Beyond the constructor a subclass should override the <code>addTo</code> * and <code>clone</code> methods, these are used when the Styles are being * merged into a resulting style. * * @author Scott Violet */ public class DefaultSynthStyle extends SynthStyle implements Cloneable { private static final String PENDING = "Pending"; /** * Should the component be opaque? */ private boolean opaque; /** * Insets. */ private Insets insets; /** * Information specific to ComponentState. */ private StateInfo[] states; /** * User specific data. */ private Map data; /** * Font to use if there is no matching StateInfo, or the StateInfo doesn't * define one. */ private Font font; /** * SynthGraphics, may be null. */ private SynthGraphicsUtils synthGraphics; /** * Painter to use if the StateInfo doesn't have one. */ private SynthPainter painter; /** * Nullary constructor, intended for subclassers. */ public DefaultSynthStyle() { } /** * Creates a new DefaultSynthStyle that is a copy of the passed in * style. Any StateInfo's of the passed in style are clonsed as well. * * @param style Style to duplicate */ public DefaultSynthStyle(DefaultSynthStyle style) { opaque = style.opaque; if (style.insets != null) { insets = new Insets(style.insets.top, style.insets.left, style.insets.bottom, style.insets.right); } if (style.states != null) { states = new StateInfo[style.states.length]; for (int counter = style.states.length - 1; counter >= 0; counter--) { states[counter] = (StateInfo)style.states[counter].clone(); } } if (style.data != null) { data = new HashMap(); data.putAll(style.data); } font = style.font; synthGraphics = style.synthGraphics; painter = style.painter; } /** * Creates a new DefaultSynthStyle. * * @param insets Insets for the Style * @param opaque Whether or not the background is completely painted in * an opaque color * @param states StateInfos describing properties per state * @param data Style specific data. */ public DefaultSynthStyle(Insets insets, boolean opaque, StateInfo[] states, Map data) { this.insets = insets; this.opaque = opaque; this.states = states; this.data = data; } public Color getColor(SynthContext context, ColorType type) { return getColor(context.getComponent(), context.getRegion(), context.getComponentState(), type); } public Color getColor(JComponent c, Region id, int state, ColorType type) { // For the enabled state, prefer the widget's colors if (!id.isSubregion() && state == SynthConstants.ENABLED) { if (type == ColorType.BACKGROUND) { return c.getBackground(); } else if (type == ColorType.FOREGROUND) { return c.getForeground(); } else if (type == ColorType.TEXT_FOREGROUND) { // If getForeground returns a non-UIResource it means the // developer has explicitly set the foreground, use it over // that of TEXT_FOREGROUND as that is typically the expected // behavior. Color color = c.getForeground(); if (!(color instanceof UIResource)) { return color; } } } // Then use what we've locally defined Color color = getColorForState(c, id, state, type); if (color == null) { // No color, fallback to that of the widget. if (type == ColorType.BACKGROUND || type == ColorType.TEXT_BACKGROUND) { return c.getBackground(); } else if (type == ColorType.FOREGROUND || type == ColorType.TEXT_FOREGROUND) { return c.getForeground(); } } return color; } protected Color getColorForState(SynthContext context, ColorType type) { return getColorForState(context.getComponent(), context.getRegion(), context.getComponentState(), type); } /** * Returns the color for the specified state. * * @param c JComponent the style is associated with * @param id Region identifier * @param state State of the region. * @param type Type of color being requested. * @return Color to render with */ protected Color getColorForState(JComponent c, Region id, int state, ColorType type) { // Use the best state. StateInfo si = getStateInfo(state); Color color; if (si != null && (color = si.getColor(type)) != null) { return color; } if (si == null || si.getComponentState() != 0) { si = getStateInfo(0); if (si != null) { return si.getColor(type); } } return null; } /** * Sets the font that is used if there is no matching StateInfo, or * it does not define a font. * * @param font Font to use for rendering */ public void setFont(Font font) { this.font = font; } public Font getFont(SynthContext state) { return getFont(state.getComponent(), state.getRegion(), state.getComponentState()); } public Font getFont(JComponent c, Region id, int state) { if (!id.isSubregion() && state == SynthConstants.ENABLED) { return c.getFont(); } Font cFont = c.getFont(); if (cFont != null && !(cFont instanceof UIResource)) { return cFont; } return getFontForState(c, id, state); } /** * Returns the font for the specified state. This should NOT callback * to the JComponent. * * @param c JComponent the style is associated with * @param id Region identifier * @param state State of the region. * @return Font to render with */ protected Font getFontForState(JComponent c, Region id, int state) { if (c == null) { return this.font; } // First pass, look for the best match StateInfo si = getStateInfo(state); Font font; if (si != null && (font = si.getFont()) != null) { return font; } if (si == null || si.getComponentState() != 0) { si = getStateInfo(0); if (si != null && (font = si.getFont()) != null) { return font; } } // Fallback font. return this.font; } protected Font getFontForState(SynthContext context) { return getFontForState(context.getComponent(), context.getRegion(), context.getComponentState()); } /** * Sets the SynthGraphicsUtils that will be used for rendering. * * @param graphics SynthGraphics */ public void setGraphicsUtils(SynthGraphicsUtils graphics) { this.synthGraphics = graphics; } /** * Returns a SynthGraphicsUtils. * * @param context SynthContext indentifying requestor * @return SynthGraphicsUtils */ public SynthGraphicsUtils getGraphicsUtils(SynthContext context) { if (synthGraphics == null) { return super.getGraphicsUtils(context); } return synthGraphics; } /** * Sets the insets. * * @param Insets. */ public void setInsets(Insets insets) { this.insets = insets; } /** * Returns the Insets. If <code>to</code> is non-null the resulting * insets will be placed in it, otherwise a new Insets object will be * created and returned. * * @param context SynthContext indentifying requestor * @param to Where to place Insets * @return Insets. */ public Insets getInsets(SynthContext state, Insets to) { if (to == null) { to = new Insets(0, 0, 0, 0); } if (insets != null) { to.left = insets.left; to.right = insets.right; to.top = insets.top; to.bottom = insets.bottom; } else { to.left = to.right = to.top = to.bottom = 0; } return to; } /** * Sets the Painter to use for the border. * * @param painter Painter for the Border. */ public void setPainter(SynthPainter painter) { this.painter = painter; } /** * Returns the Painter for the passed in Component. This may return null. * * @param ss SynthContext indentifying requestor * @return Painter for the border */ public SynthPainter getPainter(SynthContext ss) { return painter; } /** * Sets whether or not the JComponent should be opaque. * * @param opaque Whether or not the JComponent should be opaque. */ public void setOpaque(boolean opaque) { this.opaque = opaque; } /** * Returns the value to initialize the opacity property of the Component * to. A Style should NOT assume the opacity will remain this value, the * developer may reset it or override it. * * @param ss SynthContext indentifying requestor * @return opaque Whether or not the JComponent is opaque. */ public boolean isOpaque(SynthContext ss) { return opaque; } /** * Sets style specific values. This does NOT copy the data, it * assigns it directly to this Style. * * @param data Style specific values */ public void setData(Map data) { this.data = data; } /** * Returns the style specific data. * * @return Style specific data. */ public Map getData() { return data; } /** * Getter for a region specific style property. * * @param state SynthContext indentifying requestor * @param key Property being requested. * @return Value of the named property */ public Object get(SynthContext state, Object key) { // Look for the best match StateInfo si = getStateInfo(state.getComponentState()); if (si != null && si.getData() != null && getKeyFromData(si.getData(), key) != null) { return getKeyFromData(si.getData(), key); } si = getStateInfo(0); if (si != null && si.getData() != null && getKeyFromData(si.getData(), key) != null) { return getKeyFromData(si.getData(), key); } if(getKeyFromData(data, key) != null) return getKeyFromData(data, key); return getDefaultValue(state, key); } private Object getKeyFromData(Map stateData, Object key) { Object value = null; if (stateData != null) { synchronized(stateData) { value = stateData.get(key); } while (value == PENDING) { synchronized(stateData) { try { stateData.wait(); } catch (InterruptedException ie) {} value = stateData.get(key); } } if (value instanceof UIDefaults.LazyValue) { synchronized(stateData) { stateData.put(key, PENDING); } value = ((UIDefaults.LazyValue)value).createValue(null); synchronized(stateData) { stateData.put(key, value); stateData.notifyAll(); } } } return value; } /** * Returns the default value for a particular property. This is only * invoked if this style doesn't define a property for <code>key</code>. * * @param state SynthContext indentifying requestor * @param key Property being requested. * @return Value of the named property */ public Object getDefaultValue(SynthContext context, Object key) { return super.get(context, key); } /** * Creates a clone of this style. * * @return Clone of this style */ public Object clone() { DefaultSynthStyle style; try { style = (DefaultSynthStyle)super.clone(); } catch (CloneNotSupportedException cnse) { return null; } if (states != null) { style.states = new StateInfo[states.length]; for (int counter = states.length - 1; counter >= 0; counter--) { style.states[counter] = (StateInfo)states[counter].clone(); } } if (data != null) { style.data = new HashMap(); style.data.putAll(data); } return style; } /** * Merges the contents of this Style with that of the passed in Style, * returning the resulting merged syle. Properties of this * <code>DefaultSynthStyle</code> will take precedence over those of the * passed in <code>DefaultSynthStyle</code>. For example, if this * style specifics a non-null font, the returned style will have its * font so to that regardless of the <code>style</code>'s font. * * @param style Style to add our styles to * @return Merged style. */ public DefaultSynthStyle addTo(DefaultSynthStyle style) { if (insets != null) { style.insets = this.insets; } if (font != null) { style.font = this.font; } if (painter != null) { style.painter = this.painter; } if (synthGraphics != null) { style.synthGraphics = this.synthGraphics; } style.opaque = opaque; if (states != null) { if (style.states == null) { style.states = new StateInfo[states.length]; for (int counter = states.length - 1; counter >= 0; counter--){ if (states[counter] != null) {