Style.java
上传用户:haobig99
上传日期:2022-06-15
资源大小:369k
文件大小:43k
源码类别:

J2ME

开发平台:

Java

  1. /*
  2.  * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
  3.  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4.  *
  5.  * This code is free software; you can redistribute it and/or modify it
  6.  * under the terms of the GNU General Public License version 2 only, as
  7.  * published by the Free Software Foundation.  Sun designates this
  8.  * particular file as subject to the "Classpath" exception as provided
  9.  * by Sun in the LICENSE file that accompanied this code.
  10.  *
  11.  * This code is distributed in the hope that it will be useful, but WITHOUT
  12.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13.  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14.  * version 2 for more details (a copy is included in the LICENSE file that
  15.  * accompanied this code).
  16.  *
  17.  * You should have received a copy of the GNU General Public License version
  18.  * 2 along with this work; if not, write to the Free Software Foundation,
  19.  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20.  *
  21.  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22.  * CA 95054 USA or visit www.sun.com if you need additional information or
  23.  * have any questions.
  24.  */
  25. package com.sun.lwuit.plaf;
  26. import com.sun.lwuit.*;
  27. import com.sun.lwuit.events.StyleListener;
  28. import com.sun.lwuit.util.EventDispatcher;
  29. import java.lang.ref.WeakReference;
  30. import java.util.Vector;
  31. /**
  32.  * Represents the look of a given component: colors, fonts, transparency, margin and padding & images.
  33.  * <p>Each Component contains a Style Object and allows Style modification in Runtime
  34.  * by Using {@code cmp.getStyle()}
  35.  * The style is also used in Themeing, when a Theme is Changed the Styles Objects are been 
  36.  * updated automatically.
  37.  * <p>When changing a theme the elements changed manually in a style will not be updated
  38.  * by the theme change by default. There are two ways to change that behavior:
  39.  * <ol><li>Use the set method that accepts a second boolean argument and set it to true.
  40.  * <li>Create a new style object and pass all the options in the constructor (without invoking setters manually).
  41.  * </ol>
  42.  * <p>
  43.  * The Margin and Padding is inspired by <a href="http://www.w3.org/TR/REC-CSS2/box.html">W3 Box Model</a>
  44.  *  
  45.  *<pre>
  46.  *
  47.  *       **************************
  48.  *       *         Margin         *
  49.  *       *  ********************  *
  50.  *       *  *      Padding     *  *
  51.  *       *  *    ***********   *  *
  52.  *       *  *    * Content *   *  *
  53.  *       *  *    ***********   *  *
  54.  *       *  *      Padding     *  *
  55.  *       *  ********************  *
  56.  *       *         Margin         *
  57.  *       **************************
  58.  *</pre> 
  59.  * @author Chen Fishbein
  60.  */
  61. public class Style {
  62.     /**
  63.      * Indicates a special compatibilty mode for LWUIT allowing easy transition to
  64.      * the new style model
  65.      */
  66.     private static boolean defaultStyleCompatibilityMode = true;
  67.     /**
  68.      * Background color attribute name for the theme hashtable 
  69.      */
  70.     public static final String BG_COLOR = "bgColor";
  71.     /**
  72.      * Foreground color attribute name for the theme hashtable 
  73.      */
  74.     public static final String FG_COLOR = "fgColor";
  75.     /**
  76.      * Background image attribute name for the theme hashtable 
  77.      */
  78.     public static final String BG_IMAGE = "bgImage";
  79.     
  80.     /**
  81.      * Background attribute name for the theme hashtable
  82.      */
  83.     public static final String BACKGROUND_TYPE = "bgType";
  84.     /**
  85.      * Background attribute name for the theme hashtable
  86.      */
  87.     public static final String BACKGROUND_ALIGNMENT = "bgAlign";
  88.     /**
  89.      * Background attribute name for the theme hashtable
  90.      */
  91.     public static final String BACKGROUND_GRADIENT = "bgGradient";
  92.     /**
  93.      * Font attribute name for the theme hashtable 
  94.      */
  95.     public static final String FONT = "font";
  96.     /**
  97.      * Transparency attribute name for the theme hashtable 
  98.      */
  99.     public static final String TRANSPARENCY = "transparency";
  100.     /**
  101.      * Margin attribute name for the theme hashtable 
  102.      */
  103.     public static final String MARGIN = "margin";
  104.     /**
  105.      * Border attribute name for the theme hashtable 
  106.      */
  107.     public static final String BORDER = "border";
  108.     /**
  109.      * Padding attribute name for the theme hashtable 
  110.      */
  111.     public static final String PADDING = "padding";
  112.     /**
  113.      * Indicates the background for the style would use a scaled image
  114.      */
  115.     public static final byte BACKGROUND_IMAGE_SCALED = (byte)1;
  116.     /**
  117.      * Indicates the background for the style would use a tiled image on both axis
  118.      */
  119.     public static final byte BACKGROUND_IMAGE_TILE_BOTH = (byte)2;
  120.     /**
  121.      * Indicates the background for the style would use a vertical tiled image
  122.      */
  123.     public static final byte BACKGROUND_IMAGE_TILE_VERTICAL = (byte)3;
  124.     /**
  125.      * Indicates the background for the style would use a horizontal tiled image
  126.      */
  127.     public static final byte BACKGROUND_IMAGE_TILE_HORIZONTAL = (byte)4;
  128.     /**
  129.      * Indicates the background for the style would use an unscaled image with an alignment
  130.      */
  131.     public static final byte BACKGROUND_IMAGE_ALIGNED = (byte)5;
  132.     /**
  133.      * Indicates the background for the style would use a linear gradient
  134.      */
  135.     public static final byte BACKGROUND_GRADIENT_LINEAR_VERTICAL = (byte)6;
  136.     /**
  137.      * Indicates the background for the style would use a linear gradient
  138.      */
  139.     public static final byte BACKGROUND_GRADIENT_LINEAR_HORIZONTAL = (byte)7;
  140.     /**
  141.      * Indicates the background for the style would use a radial gradient
  142.      */
  143.     public static final byte BACKGROUND_GRADIENT_RADIAL = (byte)8;
  144.     /**
  145.      * Indicates the background alignment for use in tiling or aligned images
  146.      */
  147.     public static final byte BACKGROUND_IMAGE_ALIGN_TOP = (byte)0xa1;
  148.     /**
  149.      * Indicates the background alignment for use in tiling or aligned images
  150.      */
  151.     public static final byte BACKGROUND_IMAGE_ALIGN_BOTTOM = (byte)0xa2;
  152.     /**
  153.      * Indicates the background alignment for use in tiling or aligned images
  154.      */
  155.     public static final byte BACKGROUND_IMAGE_ALIGN_LEFT = (byte)0xa3;
  156.     /**
  157.      * Indicates the background alignment for use in tiling or aligned images
  158.      */
  159.     public static final byte BACKGROUND_IMAGE_ALIGN_RIGHT = (byte)0xa4;
  160.     /**
  161.      * Indicates the background alignment for use in tiling or aligned images
  162.      */
  163.     public static final byte BACKGROUND_IMAGE_ALIGN_CENTER = (byte)0xa5;
  164.     private int fgColor = 0x000000;
  165.     private int bgColor = 0xFFFFFF;
  166.     private Font font = Font.getDefaultFont();
  167.     private Image bgImage;
  168.     private int[] padding = new int[4];
  169.     private int[] margin = new int[4];
  170.     private byte transparency = (byte) 0xFF; //no transparency
  171.     private Painter bgPainter;
  172.     private byte backgroundType = BACKGROUND_IMAGE_SCALED;
  173.     private byte backgroundAlignment = BACKGROUND_IMAGE_ALIGN_TOP;
  174.     private Object[] backgroundGradient;
  175.     private Border border = null;
  176.     /**
  177.      * The modified flag indicates which portions of the style have changed using
  178.      * bitmask values
  179.      */
  180.     private short modifiedFlag;
  181.     /**
  182.      * Used for modified flag
  183.      */
  184.     private static final short FG_COLOR_MODIFIED = 1;
  185.     /**
  186.      * Used for modified flag
  187.      */
  188.     private static final short BG_COLOR_MODIFIED = 2;
  189.     /**
  190.      * Used for modified flag
  191.      */
  192.     private static final short FONT_MODIFIED = 16;
  193.     /**
  194.      * Used for modified flag
  195.      */
  196.     private static final short BG_IMAGE_MODIFIED = 32;
  197.     /**
  198.      * Used for modified flag
  199.      */
  200.     //private static final short SCALE_IMAGE_MODIFIED = 64;
  201.     /**
  202.      * Used for modified flag
  203.      */
  204.     private static final short TRANSPARENCY_MODIFIED = 128;
  205.     /**
  206.      * Used for modified flag
  207.      */
  208.     private static final short PADDING_MODIFIED = 256;
  209.     /**
  210.      * Used for modified flag
  211.      */
  212.     private static final short MARGIN_MODIFIED = 512;
  213.     /**
  214.      * Used for modified flag
  215.      */
  216.     private static final short BORDER_MODIFIED = 1024;
  217.     private static final short BACKGROUND_TYPE_MODIFIED = 2048;
  218.     private static final short BACKGROUND_ALIGNMENT_MODIFIED = 4096;
  219.     private static final short BACKGROUND_GRADIENT_MODIFIED = 8192;
  220.     private EventDispatcher listeners;
  221.     WeakReference roundRectCache;
  222.     /**
  223.      * Each component when it draw itself uses this Object 
  224.      * to determine in what colors it should use.
  225.      * When a Component is generated it construct a default Style Object.
  226.      * The Default values for each Component can be changed by using the UIManager class
  227.      */
  228.     public Style() {
  229.         setPadding(3, 3, 3, 3);
  230.         setMargin(2, 2, 2, 2);
  231.         modifiedFlag = 0;
  232.     }
  233.     /**
  234.      * Creates a full copy of the given style. Notice that if the original style was modified 
  235.      * manually (by invoking setters on it) it would not chnage when changing a theme/look and feel,
  236.      * however this newly created style would change in such a case.
  237.      * 
  238.      * @param style the style to copy
  239.      */
  240.     public Style(Style style) {
  241.         this(style.getFgColor(), style.getBgColor(), 0, 0, style.getFont(), style.getBgTransparency(),
  242.                 style.getBgImage(), true);
  243.         setPadding(style.padding[Component.TOP],
  244.                 style.padding[Component.BOTTOM],
  245.                 style.padding[Component.LEFT],
  246.                 style.padding[Component.RIGHT]);
  247.         setMargin(style.margin[Component.TOP],
  248.                 style.margin[Component.BOTTOM],
  249.                 style.margin[Component.LEFT],
  250.                 style.margin[Component.RIGHT]);
  251.         setBorder(style.getBorder());
  252.         modifiedFlag = 0;
  253.         backgroundType = style.backgroundType;
  254.         backgroundAlignment = style.backgroundAlignment;
  255.         if(style.backgroundGradient != null) {
  256.             backgroundGradient = new Object[style.backgroundGradient.length];
  257.             System.arraycopy(style.backgroundGradient, 0, backgroundGradient, 0, backgroundGradient.length);
  258.         }
  259.     }
  260.     /**
  261.      * Creates a new style with the given attributes
  262.      * 
  263.      * @param fgColor foreground color
  264.      * @param bgColor background color
  265.      * @param fgSelectionColor foreground selection color
  266.      * @param bgSelectionColor background selection color
  267.      * @param f font
  268.      * @param transparency transparency value
  269.      */
  270.     private Style(int fgColor, int bgColor, int fgSelectionColor, int bgSelectionColor, Font f, byte transparency) {
  271.         this(fgColor, bgColor, fgSelectionColor, bgSelectionColor, f, transparency, null, false);
  272.     }
  273.     /**
  274.      * Creates a new style with the given attributes
  275.      *
  276.      * @param fgColor foreground color
  277.      * @param bgColor background color
  278.      * @param f font
  279.      * @param transparency transparency value
  280.      */
  281.     public Style(int fgColor, int bgColor, Font f, byte transparency) {
  282.         this(fgColor, bgColor, f, transparency, null, BACKGROUND_IMAGE_SCALED);
  283.     }
  284.     /**
  285.      * Creates a new style with the given attributes
  286.      * 
  287.      * @param fgColor foreground color
  288.      * @param bgColor background color
  289.      * @param fgSelectionColor foreground selection color
  290.      * @param bgSelectionColor background selection color
  291.      * @param f font
  292.      * @param transparency transparency value
  293.      * @param im background image
  294.      * @param scaledImage whether the image should be scaled or tiled
  295.      */
  296.     private Style(int fgColor, int bgColor, int fgSelectionColor, int bgSelectionColor, Font f, byte transparency, Image im, boolean scaledImage) {
  297.         this();
  298.         this.fgColor = fgColor;
  299.         this.bgColor = bgColor;
  300.         this.font = f;
  301.         this.transparency = transparency;
  302.         this.bgImage = im;        
  303.     }
  304.     /**
  305.      * Creates a new style with the given attributes
  306.      *
  307.      * @param fgColor foreground color
  308.      * @param bgColor background color
  309.      * @param f font
  310.      * @param transparency transparency value
  311.      * @param im background image
  312.      * @param backgroundType one of:
  313.      * BACKGROUND_IMAGE_SCALED, BACKGROUND_IMAGE_TILE_BOTH,
  314.      * BACKGROUND_IMAGE_TILE_VERTICAL, BACKGROUND_IMAGE_TILE_HORIZONTAL,
  315.      * BACKGROUND_IMAGE_ALIGNED, BACKGROUND_GRADIENT_LINEAR_HORIZONTAL,
  316.      * BACKGROUND_GRADIENT_LINEAR_VERTICAL, BACKGROUND_GRADIENT_RADIAL 
  317.      */
  318.     public Style(int fgColor, int bgColor, Font f, byte transparency, Image im, byte backgroundType) {
  319.         this();
  320.         this.fgColor = fgColor;
  321.         this.bgColor = bgColor;
  322.         this.font = f;
  323.         this.transparency = transparency;
  324.         this.backgroundType = backgroundType;
  325.         this.bgImage = im;
  326.     }
  327.     /**
  328.      * Merges the new style with the current style without changing the elements that
  329.      * were modified.
  330.      * 
  331.      * @param style new values of styles from the current theme
  332.      */
  333.     public void merge(Style style) {
  334.         short tmp = modifiedFlag;
  335.         if ((modifiedFlag & FG_COLOR_MODIFIED) == 0) {
  336.             setFgColor(style.getFgColor());
  337.         }
  338.         if ((modifiedFlag & BG_COLOR_MODIFIED) == 0) {
  339.             setBgColor(style.getBgColor());
  340.         }
  341.         if ((modifiedFlag & BG_IMAGE_MODIFIED) == 0) {
  342.             setBgImage(style.getBgImage());
  343.         }
  344.         if ((modifiedFlag & BACKGROUND_TYPE_MODIFIED) == 0) {
  345.             setBackgroundType(style.getBackgroundType());
  346.         }
  347.         if ((modifiedFlag & BACKGROUND_ALIGNMENT_MODIFIED) == 0) {
  348.             setBackgroundAlignment(style.getBackgroundAlignment());
  349.         }
  350.         if ((modifiedFlag & BACKGROUND_GRADIENT_MODIFIED) == 0) {
  351.             setBackgroundGradientStartColor(style.getBackgroundGradientStartColor());
  352.             setBackgroundGradientEndColor(style.getBackgroundGradientEndColor());
  353.             setBackgroundGradientRelativeX(style.getBackgroundGradientRelativeX());
  354.             setBackgroundGradientRelativeY(style.getBackgroundGradientRelativeY());
  355.             setBackgroundGradientRelativeSize(style.getBackgroundGradientRelativeSize());
  356.         }
  357.         if ((modifiedFlag & FONT_MODIFIED) == 0) {
  358.             setFont(style.getFont());
  359.         }
  360.         if ((modifiedFlag & TRANSPARENCY_MODIFIED) == 0) {
  361.             setBgTransparency(style.getBgTransparency());
  362.         }
  363.         if ((modifiedFlag & PADDING_MODIFIED) == 0) {
  364.             setPadding(style.padding[Component.TOP],
  365.                     style.padding[Component.BOTTOM],
  366.                     style.padding[Component.LEFT],
  367.                     style.padding[Component.RIGHT]);
  368.         }
  369.         if ((modifiedFlag & MARGIN_MODIFIED) == 0) {
  370.             setMargin(style.margin[Component.TOP],
  371.                     style.margin[Component.BOTTOM],
  372.                     style.margin[Component.LEFT],
  373.                     style.margin[Component.RIGHT]);
  374.         }
  375.         
  376.         if ((modifiedFlag & BORDER_MODIFIED) == 0) {
  377.             setBorder(style.getBorder());
  378.         }
  379.         modifiedFlag = tmp;
  380.     }
  381.     /**
  382.      * Returns true if the style was modified manually after it was created by the
  383.      * look and feel. If the style was modified manually (by one of the set methods)
  384.      * then it should be merged rather than overwritten.
  385.      * 
  386.      * @return true if the style was modified
  387.      */
  388.     public boolean isModified() {
  389.         return modifiedFlag != 0;
  390.     }
  391.     /**
  392.      * Background color for the component
  393.      *
  394.      * @return the background color for the component
  395.      */
  396.     public int getBgColor() {
  397.         return bgColor;
  398.     }
  399.     /**
  400.      * Background image for the component
  401.      *
  402.      * @return the background image for the component
  403.      */
  404.     public Image getBgImage() {
  405.         return bgImage;
  406.     }
  407.     /**
  408.      * The type of the background defaults to BACKGROUND_IMAGE_SCALED
  409.      * 
  410.      * @return one of: 
  411.      * BACKGROUND_IMAGE_SCALED, BACKGROUND_IMAGE_TILE_BOTH, 
  412.      * BACKGROUND_IMAGE_TILE_VERTICAL, BACKGROUND_IMAGE_TILE_HORIZONTAL, 
  413.      * BACKGROUND_IMAGE_ALIGNED, BACKGROUND_GRADIENT_LINEAR_HORIZONTAL, 
  414.      * BACKGROUND_GRADIENT_LINEAR_VERTICAL, BACKGROUND_GRADIENT_RADIAL 
  415.      */
  416.     public byte getBackgroundType() {
  417.         return backgroundType;
  418.     }
  419.     /**
  420.      * Return the alignment for the image or tiled image
  421.      *
  422.      * @return one of:
  423.      * BACKGROUND_IMAGE_ALIGN_TOP, BACKGROUND_IMAGE_ALIGN_BOTTOM,
  424.      * BACKGROUND_IMAGE_ALIGN_LEFT, BACKGROUND_IMAGE_ALIGN_RIGHT,
  425.      * BACKGROUND_IMAGE_ALIGN_CENTER
  426.      */
  427.     public byte getBackgroundAlignment() {
  428.         return backgroundAlignment;
  429.     }
  430.     /**
  431.      * Start color for the radial/linear gradient
  432.      *
  433.      * @return the start color for the radial/linear gradient
  434.      */
  435.     public int getBackgroundGradientStartColor() {
  436.         if(backgroundGradient != null && backgroundGradient.length > 1) {
  437.             return ((Integer)backgroundGradient[0]).intValue();
  438.         }
  439.         return 0xffffff;
  440.     }
  441.     /**
  442.      * End color for the radial/linear gradient
  443.      *
  444.      * @return the end color for the radial/linear gradient
  445.      */
  446.     public int getBackgroundGradientEndColor() {
  447.         if(backgroundGradient != null && backgroundGradient.length > 1) {
  448.             return ((Integer)backgroundGradient[1]).intValue();
  449.         }
  450.         return 0;
  451.     }
  452.     /**
  453.      * Background radial gradient relative center position X
  454.      *
  455.      * @return value between 0 and 1 with 0.5 representing the center of the component
  456.      */
  457.     public float getBackgroundGradientRelativeX() {
  458.         if(backgroundGradient != null && backgroundGradient.length > 2) {
  459.             return ((Float)backgroundGradient[2]).floatValue();
  460.         }
  461.         return 0.5f;
  462.     }
  463.     /**
  464.      * Background radial gradient relative center position Y
  465.      *
  466.      * @return value between 0 and 1 with 0.5 representing the center of the component
  467.      */
  468.     public float getBackgroundGradientRelativeY() {
  469.         if(backgroundGradient != null && backgroundGradient.length > 3) {
  470.             return ((Float)backgroundGradient[3]).floatValue();
  471.         }
  472.         return 0.5f;
  473.     }
  474.     /**
  475.      * Background radial gradient relative size
  476.      *
  477.      * @return value representing the relative size of the gradient
  478.      */
  479.     public float getBackgroundGradientRelativeSize() {
  480.         if(backgroundGradient != null && backgroundGradient.length > 4) {
  481.             return ((Float)backgroundGradient[4]).floatValue();
  482.         }
  483.         return 1f;
  484.     }
  485.     /**
  486.      * Foreground color for the component
  487.      *
  488.      * @return the foreground color for the component
  489.      */
  490.     public int getFgColor() {
  491.         return fgColor;
  492.     }
  493.     /**
  494.      * Font for the component
  495.      *
  496.      * @return the font for the component
  497.      */
  498.     public Font getFont() {
  499.         return font;
  500.     }
  501.     /**
  502.      * Sets the background color for the component
  503.      * 
  504.      * @param bgColor RRGGBB color that ignors the alpha component
  505.      */
  506.     public void setBgColor(int bgColor) {
  507.         setBgColor(bgColor, false);
  508.     }
  509.     /**
  510.      * Sets the background image for the component
  511.      * 
  512.      * @param bgImage background image
  513.      */
  514.     public void setBgImage(Image bgImage) {
  515.         setBgImage(bgImage, false);
  516.     }
  517.     /**
  518.      * Sets the background type for the component
  519.      *
  520.      * @param backgroundType one of BACKGROUND_IMAGE_SCALED, BACKGROUND_IMAGE_TILE_BOTH,
  521.      * BACKGROUND_IMAGE_TILE_VERTICAL, BACKGROUND_IMAGE_TILE_HORIZONTAL,
  522.      * BACKGROUND_IMAGE_ALIGNED, BACKGROUND_GRADIENT_LINEAR_HORIZONTAL,
  523.      * BACKGROUND_GRADIENT_LINEAR_VERTICAL, BACKGROUND_GRADIENT_RADIAL
  524.      */
  525.     public void setBackgroundType(byte backgroundType) {
  526.         setBackgroundType(backgroundType, false);
  527.     }
  528.     /**
  529.      * Sets the background alignment for the component
  530.      *
  531.      * @param backgroundAlignment one of:
  532.      * BACKGROUND_IMAGE_ALIGN_TOP, BACKGROUND_IMAGE_ALIGN_BOTTOM,
  533.      * BACKGROUND_IMAGE_ALIGN_LEFT, BACKGROUND_IMAGE_ALIGN_RIGHT,
  534.      * BACKGROUND_IMAGE_ALIGN_CENTER
  535.      */
  536.     public void setBackgroundAlignment(byte backgroundAlignment) {
  537.         setBackgroundAlignment(backgroundAlignment, false);
  538.     }
  539.     /**
  540.      * Sets the background color for the component
  541.      *
  542.      * @param backgroundGradientStartColor start color for the linear/radial gradient
  543.      */
  544.     public void setBackgroundGradientStartColor(int backgroundGradientStartColor) {
  545.         setBackgroundGradientStartColor(backgroundGradientStartColor, false);
  546.     }
  547.     /**
  548.      * Sets the background color for the component
  549.      *
  550.      * @param backgroundGradientEndColor end color for the linear/radial gradient
  551.      */
  552.     public void setBackgroundGradientEndColor(int backgroundGradientEndColor) {
  553.         setBackgroundGradientEndColor(backgroundGradientEndColor, false);
  554.     }
  555.     /**
  556.      * Background radial gradient relative center position X
  557.      *
  558.      * @param backgroundGradientRelativeX x position of the radial gradient center
  559.      */
  560.     public void setBackgroundGradientRelativeX(float backgroundGradientRelativeX) {
  561.         setBackgroundGradientRelativeX(backgroundGradientRelativeX, false);
  562.     }
  563.     /**
  564.      * Background radial gradient relative center position Y
  565.      *
  566.      * @param backgroundGradientRelativeY y position of the radial gradient center
  567.      */
  568.     public void setBackgroundGradientRelativeY(float backgroundGradientRelativeY) {
  569.         setBackgroundGradientRelativeY(backgroundGradientRelativeY, false);
  570.     }
  571.     /**
  572.      * Background radial gradient relative size
  573.      *
  574.      * @param backgroundGradientRelativeSize the size of the radial gradient
  575.      */
  576.     public void setBackgroundGradientRelativeSize(float backgroundGradientRelativeSize) {
  577.         setBackgroundGradientRelativeSize(backgroundGradientRelativeSize, false);
  578.     }
  579.     /**
  580.      * Sets the foreground color for the component
  581.      * 
  582.      * @param fgColor foreground color
  583.      */
  584.     public void setFgColor(int fgColor) {
  585.         setFgColor(fgColor, false);
  586.     }
  587.     /**
  588.      * Sets the font for the component
  589.      * 
  590.      * @param font the font
  591.      */
  592.     public void setFont(Font font) {
  593.         setFont(font, false);
  594.     }
  595.     private Style getSelectedStyle() {
  596.         if(listeners != null) {
  597.             Vector l = listeners.getListenerVector();
  598.             int size = l.size();
  599.             if(size > 0) {
  600.                 Object o = l.elementAt(0);
  601.                 if(o instanceof Component) {
  602.                     return ((Component)o).getSelectedStyle();
  603.                 }
  604.             }
  605.         }
  606.         return null;
  607.     }
  608.     /**
  609.      * Returns the transparency (opacity) level of the Component, zero indicates fully
  610.      * transparent and FF indicates fully opaque. 
  611.      * 
  612.      * @return  the transparency level of the Component
  613.      */
  614.     public byte getBgTransparency() {
  615.         if(bgImage != null && (bgImage.isAnimation() || bgImage.isOpaque())) {
  616.             return (byte)0xff;
  617.         }
  618.         return transparency;
  619.     }
  620.     /**
  621.      * Sets the Component transparency (opacity) level of the Component, zero indicates fully
  622.      * transparent and FF indicates fully opaque. 
  623.      * 
  624.      * @param transparency transparency level as byte
  625.      */
  626.     public void setBgTransparency(byte transparency) {
  627.         setBgTransparency(transparency & 0xFF, false);
  628.     }
  629.     /**
  630.      * Sets the Component transparency level. Valid values should be a 
  631.      * number between 0-255
  632.      * @param transparency int value between 0-255
  633.      */
  634.     public void setBgTransparency(int transparency) {
  635.         setBgTransparency(transparency, false);
  636.     }
  637.     /**
  638.      * Sets the Style Padding
  639.      *  
  640.      * @param top number of pixels to padd
  641.      * @param bottom number of pixels to padd
  642.      * @param left number of pixels to padd
  643.      * @param right number of pixels to padd
  644.      */
  645.     public void setPadding(int top, int bottom, int left, int right) {
  646.         if (top < 0 || left < 0 || right < 0 || bottom < 0) {
  647.             throw new IllegalArgumentException("padding cannot be negative");
  648.         }
  649.         if (padding[Component.TOP] != top ||
  650.                 padding[Component.BOTTOM] != bottom ||
  651.                 padding[Component.LEFT] != left ||
  652.                 padding[Component.RIGHT] != right) {
  653.             padding[Component.TOP] = top;
  654.             padding[Component.BOTTOM] = bottom;
  655.             padding[Component.LEFT] = left;
  656.             padding[Component.RIGHT] = right;
  657.             modifiedFlag |= PADDING_MODIFIED;
  658.             firePropertyChanged(PADDING);
  659.         }
  660.     }
  661.     /**
  662.      * Sets the Style Padding
  663.      * 
  664.      * @param orientation one of: Component.TOP, Component.BOTTOM, Component.LEFT, Component.RIGHT
  665.      * @param gap number of pixels to padd
  666.      */
  667.     public void setPadding(int orientation, int gap) {
  668.         setPadding(orientation, gap, false);
  669.     }
  670.     /**
  671.      * Sets the Style Margin
  672.      *  
  673.      * @param top number of margin pixels
  674.      * @param bottom number of margin pixels
  675.      * @param left number of margin pixels
  676.      * @param right number of margin pixels
  677.      */
  678.     public void setMargin(int top, int bottom, int left, int right) {
  679.         if (top < 0 || left < 0 || right < 0 || bottom < 0) {
  680.             throw new IllegalArgumentException("margin cannot be negative");
  681.         }
  682.         if (margin[Component.TOP] != top ||
  683.                 margin[Component.BOTTOM] != bottom ||
  684.                 margin[Component.LEFT] != left ||
  685.                 margin[Component.RIGHT] != right) {
  686.             margin[Component.TOP] = top;
  687.             margin[Component.BOTTOM] = bottom;
  688.             margin[Component.LEFT] = left;
  689.             margin[Component.RIGHT] = right;
  690.             modifiedFlag |= MARGIN_MODIFIED;
  691.             firePropertyChanged(MARGIN);
  692.         }
  693.     }
  694.     /**
  695.      * Sets the Style Margin
  696.      * 
  697.      * @param orientation one of: Component.TOP, Component.BOTTOM, Component.LEFT, Component.RIGHT
  698.      * @param gap number of margin pixels
  699.      */
  700.     public void setMargin(int orientation, int gap) {
  701.         setMargin(orientation, gap, false);
  702.     }
  703.     /**
  704.      * Returns the Padding
  705.      *
  706.      * @param rtl flag indicating whether the padding is for an RTL bidi component
  707.      * @param orientation one of: Component.TOP, Component.BOTTOM, Component.LEFT, Component.RIGHT
  708.      * @return number of padding pixels in the givven orientation
  709.      */
  710.     public int getPadding(boolean rtl, int orientation) {
  711.         if (orientation < Component.TOP || orientation > Component.RIGHT) {
  712.             throw new IllegalArgumentException("wrong orientation " + orientation);
  713.         }
  714.         if (rtl) {
  715.          switch(orientation) {
  716.                 case Component.LEFT:
  717.                     orientation = Component.RIGHT;
  718.                     break;
  719.                 case Component.RIGHT:
  720.                     orientation = Component.LEFT;
  721.                     break;
  722.             }
  723.         }
  724.         return padding[orientation];
  725.     }
  726.     /**
  727.      * Returns the Padding
  728.      *
  729.      * @param orientation one of: Component.TOP, Component.BOTTOM, Component.LEFT, Component.RIGHT
  730.      * @return number of padding pixels in the givven orientation
  731.      */
  732.     public int getPadding(int orientation) {
  733.         return getPadding(UIManager.getInstance().getLookAndFeel().isRTL(), orientation);
  734.     }
  735.     /**
  736.      * Returns the Margin
  737.      *
  738.      * @param orientation one of: Component.TOP, Component.BOTTOM, Component.LEFT, Component.RIGHT
  739.      * @return number of margin pixels in the givven orientation
  740.      */
  741.     public int getMargin(int orientation) {
  742.         return getMargin(UIManager.getInstance().getLookAndFeel().isRTL(), orientation);
  743.     }
  744.     /**
  745.      * Returns the Margin
  746.      * 
  747.      * @param rtl flag indicating whether the padding is for an RTL bidi component
  748.      * @param orientation one of: Component.TOP, Component.BOTTOM, Component.LEFT, Component.RIGHT
  749.      * @return number of margin pixels in the givven orientation
  750.      */
  751.     public int getMargin(boolean rtl, int orientation) {
  752.         if (orientation < Component.TOP || orientation > Component.RIGHT) {
  753.             throw new IllegalArgumentException("wrong orientation " + orientation);
  754.         }
  755.         if (rtl) {
  756.          switch(orientation) {
  757.                 case Component.LEFT:
  758.                     orientation = Component.RIGHT;
  759.                     break;
  760.                 case Component.RIGHT:
  761.                     orientation = Component.LEFT;
  762.                     break;
  763.             }
  764.         }
  765.         return margin[orientation];
  766.     }
  767.     /**
  768.      * Sets the background color for the component
  769.      * 
  770.      * @param bgColor RRGGBB color that ignors the alpha component
  771.      * @param override If set to true allows the look and feel/theme to override 
  772.      * the value in this attribute when changing a theme/look and feel
  773.      */
  774.     public void setBgColor(int bgColor, boolean override) {
  775.         if (this.bgColor != bgColor) {
  776.             this.bgColor = bgColor;
  777.             if (!override) {
  778.                 modifiedFlag |= BG_COLOR_MODIFIED;
  779.             }
  780.             firePropertyChanged(BG_COLOR);
  781.         }
  782.     }
  783.     /**
  784.      * Sets the background image for the component
  785.      * 
  786.      * @param bgImage background image
  787.      * @param override If set to true allows the look and feel/theme to override 
  788.      * the value in this attribute when changing a theme/look and feel
  789.      */
  790.     public void setBgImage(Image bgImage, boolean override) {
  791.         if (this.bgImage != bgImage) {
  792.             this.bgImage = bgImage;
  793.             if(!override){
  794.                 modifiedFlag |= BG_IMAGE_MODIFIED;
  795.             }
  796.             firePropertyChanged(BG_IMAGE);
  797.         }
  798.     }
  799.     /**
  800.      * Sets the background type for the component
  801.      *
  802.      * @param backgroundType one of BACKGROUND_IMAGE_SCALED, BACKGROUND_IMAGE_TILE_BOTH,
  803.      * BACKGROUND_IMAGE_TILE_VERTICAL, BACKGROUND_IMAGE_TILE_HORIZONTAL,
  804.      * BACKGROUND_IMAGE_ALIGNED, BACKGROUND_GRADIENT_LINEAR_HORIZONTAL,
  805.      * BACKGROUND_GRADIENT_LINEAR_VERTICAL, BACKGROUND_GRADIENT_RADIAL
  806.      * @param override If set to true allows the look and feel/theme to override
  807.      * the value in this attribute when changing a theme/look and feel
  808.      */
  809.     public void setBackgroundType(byte backgroundType, boolean override) {
  810.         if (this.backgroundType != backgroundType) {
  811.             this.backgroundType = backgroundType;
  812.             if(!override){
  813.                 modifiedFlag |= BACKGROUND_TYPE_MODIFIED;
  814.             }
  815.             firePropertyChanged(BACKGROUND_TYPE);
  816.         }
  817.     }
  818.     /**
  819.      * Sets the background alignment for the component
  820.      *
  821.      * @param backgroundAlignment one of:
  822.      * BACKGROUND_IMAGE_ALIGN_TOP, BACKGROUND_IMAGE_ALIGN_BOTTOM,
  823.      * BACKGROUND_IMAGE_ALIGN_LEFT, BACKGROUND_IMAGE_ALIGN_RIGHT,
  824.      * BACKGROUND_IMAGE_ALIGN_CENTER
  825.      * @param override If set to true allows the look and feel/theme to override
  826.      * the value in this attribute when changing a theme/look and feel
  827.      */
  828.     public void setBackgroundAlignment(byte backgroundAlignment, boolean override) {
  829.         if (this.backgroundAlignment != backgroundAlignment) {
  830.             this.backgroundAlignment = backgroundAlignment;
  831.             if(!override){
  832.                 modifiedFlag |= BACKGROUND_ALIGNMENT_MODIFIED;
  833.             }
  834.             firePropertyChanged(BACKGROUND_ALIGNMENT);
  835.         }
  836.     }
  837.     /**
  838.      * Returns the background gradient array which includes the start/end color  
  839.      * and optionally the x/y relative anchor for the radial gradient
  840.      * 
  841.      * @return the background gradient array which includes the start/end color  
  842.      * and optionally the x/y relative anchor for the radial gradient
  843.      */
  844.     Object[] getBackgroundGradient() {
  845.         if(backgroundGradient == null) {
  846.             Float c = new Float(0.5f);
  847.             backgroundGradient = new Object[] {new Integer(0xffffff), new Integer(0), c, c, new Float(1)};
  848.         }
  849.         return backgroundGradient;
  850.     }
  851.     /**
  852.      * Internal use background gradient setter
  853.      */
  854.     void setBackgroundGradient(Object[] backgroundGradient) {
  855.         this.backgroundGradient = backgroundGradient;
  856.     }
  857.     /**
  858.      * Sets the background color for the component
  859.      *
  860.      * @param backgroundGradientStartColor start color for the linear/radial gradient
  861.      * @param override If set to true allows the look and feel/theme to override
  862.      * the value in this attribute when changing a theme/look and feel
  863.      */
  864.     public void setBackgroundGradientStartColor(int backgroundGradientStartColor, boolean override) {
  865.         if (((Integer) getBackgroundGradient()[0]).intValue() != backgroundGradientStartColor) {
  866.             getBackgroundGradient()[0] = new Integer(backgroundGradientStartColor);
  867.             if (!override) {
  868.                 modifiedFlag |= BACKGROUND_GRADIENT_MODIFIED;
  869.             }
  870.             firePropertyChanged(BACKGROUND_GRADIENT);
  871.         }
  872.     }
  873.     /**
  874.      * Sets the background color for the component
  875.      *
  876.      * @param backgroundGradientEndColor end color for the linear/radial gradient
  877.      * @param override If set to true allows the look and feel/theme to override
  878.      * the value in this attribute when changing a theme/look and feel
  879.      */
  880.     public void setBackgroundGradientEndColor(int backgroundGradientEndColor, boolean override) {
  881.         if (((Integer) getBackgroundGradient()[1]).intValue() != backgroundGradientEndColor) {
  882.             getBackgroundGradient()[1] = new Integer(backgroundGradientEndColor);
  883.             if (!override) {
  884.                 modifiedFlag |= BACKGROUND_GRADIENT_MODIFIED;
  885.             }
  886.             firePropertyChanged(BACKGROUND_GRADIENT);
  887.         }
  888.     }
  889.     /**
  890.      * Background radial gradient relative center position X
  891.      *
  892.      * @param backgroundGradientRelativeX x position of the radial gradient center
  893.      * @param override If set to true allows the look and feel/theme to override
  894.      * the value in this attribute when changing a theme/look and feel
  895.      */
  896.     public void setBackgroundGradientRelativeX(float backgroundGradientRelativeX, boolean override) {
  897.         if (((Float) getBackgroundGradient()[2]).floatValue() != backgroundGradientRelativeX) {
  898.             getBackgroundGradient()[2] = new Float(backgroundGradientRelativeX);
  899.             if (!override) {
  900.                 modifiedFlag |= BACKGROUND_GRADIENT_MODIFIED;
  901.             }
  902.             firePropertyChanged(BACKGROUND_GRADIENT);
  903.         }
  904.     }
  905.     /**
  906.      * Background radial gradient relative center position Y
  907.      *
  908.      * @param backgroundGradientRelativeY y position of the radial gradient center
  909.      * @param override If set to true allows the look and feel/theme to override
  910.      * the value in this attribute when changing a theme/look and feel
  911.      */
  912.     public void setBackgroundGradientRelativeY(float backgroundGradientRelativeY, boolean override) {
  913.         if (((Float) getBackgroundGradient()[3]).floatValue() != backgroundGradientRelativeY) {
  914.             getBackgroundGradient()[3] = new Float(backgroundGradientRelativeY);
  915.             if (!override) {
  916.                 modifiedFlag |= BACKGROUND_GRADIENT_MODIFIED;
  917.             }
  918.             firePropertyChanged(BACKGROUND_GRADIENT);
  919.         }
  920.     }
  921.     /**
  922.      * Background radial gradient relative size
  923.      *
  924.      * @param backgroundGradientRelativeSize the size of the radial gradient relative to the screens
  925.      * larger dimension
  926.      * @param override If set to true allows the look and feel/theme to override
  927.      * the value in this attribute when changing a theme/look and feel
  928.      */
  929.     public void setBackgroundGradientRelativeSize(float backgroundGradientRelativeSize, boolean override) {
  930.         if (((Float) getBackgroundGradient()[4]).floatValue() != backgroundGradientRelativeSize) {
  931.             getBackgroundGradient()[4] = new Float(backgroundGradientRelativeSize);
  932.             if (!override) {
  933.                 modifiedFlag |= BACKGROUND_GRADIENT_MODIFIED;
  934.             }
  935.             firePropertyChanged(BACKGROUND_GRADIENT);
  936.         }
  937.     }
  938.     /**
  939.      * Sets the foreground color for the component
  940.      * 
  941.      * @param fgColor foreground color
  942.      * @param override If set to true allows the look and feel/theme to override 
  943.      * the value in this attribute when changing a theme/look and feel
  944.      */
  945.     public void setFgColor(int fgColor, boolean override) {
  946.         if (this.fgColor != fgColor) {
  947.             this.fgColor = fgColor;
  948.             if (!override) {
  949.                 modifiedFlag |= FG_COLOR_MODIFIED;
  950.             }
  951.             firePropertyChanged(FG_COLOR);
  952.         }
  953.     }
  954.     /**
  955.      * Sets the font for the component
  956.      * 
  957.      * @param font the font
  958.      * @param override If set to true allows the look and feel/theme to override 
  959.      * the value in this attribute when changing a theme/look and feel
  960.      */
  961.     public void setFont(Font font, boolean override) {
  962.         if (this.font == null && font != null ||
  963.                 (this.font != null && !this.font.equals(font))) {
  964.             this.font = font;
  965.             if (!override) {
  966.                 modifiedFlag |= FONT_MODIFIED;
  967.             }
  968.             firePropertyChanged(FONT);
  969.         }
  970.     }
  971.     /**
  972.      * Sets the Component transparency level. Valid values should be a 
  973.      * number between 0-255
  974.      * 
  975.      * @param transparency int value between 0-255
  976.      * @param override If set to true allows the look and feel/theme to override 
  977.      * the value in this attribute when changing a theme/look and feel
  978.      */
  979.     public void setBgTransparency(int transparency, boolean override) {
  980.         if (transparency < 0 || transparency > 255) {
  981.             throw new IllegalArgumentException("valid values are between 0-255");
  982.         }
  983.         if (this.transparency != (byte) transparency) {
  984.             this.transparency = (byte) transparency;
  985.             if (!override) {
  986.                 modifiedFlag |= TRANSPARENCY_MODIFIED;
  987.             }
  988.             firePropertyChanged(TRANSPARENCY);
  989.         }
  990.     }
  991.     /**
  992.      * Sets the Style Padding
  993.      * 
  994.      * @param orientation one of: Component.TOP, Component.BOTTOM, Component.LEFT, Component.RIGHT
  995.      * @param gap number of pixels to padd
  996.      * @param override If set to true allows the look and feel/theme to override 
  997.      * the value in this attribute when changing a theme/look and feel
  998.      */
  999.     public void setPadding(int orientation, int gap,boolean override) {
  1000.         if (orientation < Component.TOP || orientation > Component.RIGHT) {
  1001.             throw new IllegalArgumentException("wrong orientation " + orientation);
  1002.         }
  1003.         if (gap < 0) {
  1004.             throw new IllegalArgumentException("padding cannot be negative");
  1005.         }
  1006.         if (padding[orientation] != gap) {
  1007.             padding[orientation] = gap;
  1008.             if (!override) {
  1009.                 modifiedFlag |= PADDING_MODIFIED;
  1010.             }
  1011.             firePropertyChanged(PADDING);
  1012.         }
  1013.     }
  1014.     /**
  1015.      * Sets the Style Margin
  1016.      * 
  1017.      * @param orientation one of: Component.TOP, Component.BOTTOM, Component.LEFT, Component.RIGHT
  1018.      * @param gap number of margin pixels
  1019.      * @param override If set to true allows the look and feel/theme to override 
  1020.      * the value in this attribute when changing a theme/look and feel
  1021.      */
  1022.     public void setMargin(int orientation, int gap, boolean override) {
  1023.         if (orientation < Component.TOP || orientation > Component.RIGHT) {
  1024.             throw new IllegalArgumentException("wrong orientation " + orientation);
  1025.         }
  1026.         if (gap < 0) {
  1027.             throw new IllegalArgumentException("margin cannot be negative");
  1028.         }
  1029.         if (margin[orientation] != gap) {
  1030.             margin[orientation] = gap;
  1031.             if (!override) {
  1032.                 modifiedFlag |= MARGIN_MODIFIED;
  1033.             }
  1034.             firePropertyChanged(MARGIN);
  1035.         }
  1036.     }
  1037.     
  1038.     private void firePropertyChanged(String propertName) {
  1039.         roundRectCache = null;
  1040.         if (listeners == null) {
  1041.             return;
  1042.         }
  1043.         listeners.fireStyleChangeEvent(propertName, this);
  1044.     }
  1045.     /**
  1046.      * Adds a Style Listener to the Style Object.
  1047.      * 
  1048.      * @param l a style listener
  1049.      */
  1050.     public void addStyleListener(StyleListener l) {
  1051.         if (listeners == null) {
  1052.             listeners = new EventDispatcher();
  1053.         }
  1054.         listeners.addListener(l);
  1055.     }
  1056.     /**
  1057.      * Removes a Style Listener from the Style Object.
  1058.      * 
  1059.      * @param l a style listener
  1060.      */
  1061.     public void removeStyleListener(StyleListener l) {
  1062.         if (listeners != null) {
  1063.             listeners.removeListener(l);
  1064.         }
  1065.     }
  1066.     void resetModifiedFlag() {
  1067.         modifiedFlag = 0;
  1068.     }
  1069.     /**
  1070.      * Sets the border for the style
  1071.      * 
  1072.      * @param border new border object for the component
  1073.      */
  1074.     public void setBorder(Border border) {
  1075.         setBorder(border, false);
  1076.     }
  1077.     /**
  1078.      * Sets the border for the style
  1079.      * 
  1080.      * @param border new border object for the component
  1081.      * @param override If set to true allows the look and feel/theme to override 
  1082.      * the value in this attribute when changing a theme/look and feel
  1083.      */
  1084.     public void setBorder(Border border, boolean override) {
  1085.         if ((this.border == null && border != null) ||
  1086.                 (this.border != null && !this.border.equals(border))) {
  1087.             this.border = border;
  1088.             if (!override) {
  1089.                 modifiedFlag |= BORDER_MODIFIED;
  1090.             }
  1091.             firePropertyChanged(BORDER);
  1092.         }
  1093.     }
  1094.     
  1095.     /**
  1096.      * Returns the border for the style
  1097.      * 
  1098.      * @return the border
  1099.      */
  1100.     public Border getBorder() {
  1101.         return border;
  1102.     }
  1103.     
  1104.     /**
  1105.      * Return the background painter for this style, normally this would be 
  1106.      * the internal image/color painter but can be user defined 
  1107.      * 
  1108.      * @return the background painter
  1109.      */
  1110.     public Painter getBgPainter() {
  1111.         return bgPainter;
  1112.     }
  1113.     /**
  1114.      * Defines the background painter for this style, normally this would be 
  1115.      * the internal image/color painter but can be user defined 
  1116.      * 
  1117.      * @param bgPainter new painter to install into the style
  1118.      */
  1119.     public void setBgPainter(Painter bgPainter) {
  1120.         this.bgPainter = bgPainter;
  1121.     }
  1122. }