< prev index next >

src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/XPStyle.java

Print this page




   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 /*
  27  * <p>These classes are designed to be used while the
  28  * corresponding <code>LookAndFeel</code> class has been installed
  29  * (<code>UIManager.setLookAndFeel(new <i>XXX</i>LookAndFeel())</code>).
  30  * Using them while a different <code>LookAndFeel</code> is installed
  31  * may produce unexpected results, including exceptions.
  32  * Additionally, changing the <code>LookAndFeel</code>
  33  * maintained by the <code>UIManager</code> without updating the
  34  * corresponding <code>ComponentUI</code> of any
  35  * <code>JComponent</code>s may also produce unexpected results,
  36  * such as the wrong colors showing up, and is generally not
  37  * encouraged.
  38  *
  39  */
  40 
  41 package com.sun.java.swing.plaf.windows;
  42 
  43 import java.awt.*;
  44 import java.awt.image.*;
  45 import java.security.AccessController;
  46 import java.util.*;
  47 
  48 import javax.swing.*;
  49 import javax.swing.border.*;
  50 import javax.swing.plaf.*;
  51 import javax.swing.text.JTextComponent;
  52 
  53 import sun.awt.image.SunWritableRaster;
  54 import sun.awt.windows.ThemeReader;
  55 import sun.security.action.GetPropertyAction;


 106             if (themeActive.booleanValue()) {
 107                 GetPropertyAction propertyAction =
 108                     new GetPropertyAction("swing.noxp");
 109                 if (AccessController.doPrivileged(propertyAction) == null &&
 110                     ThemeReader.isThemed() &&
 111                     !(UIManager.getLookAndFeel()
 112                       instanceof WindowsClassicLookAndFeel)) {
 113 
 114                     xp = new XPStyle();
 115                 }
 116             }
 117         }
 118         return ThemeReader.isXPStyleEnabled() ? xp : null;
 119     }
 120 
 121     static boolean isVista() {
 122         XPStyle xp = XPStyle.getXP();
 123         return (xp != null && xp.isSkinDefined(null, Part.CP_DROPDOWNBUTTONRIGHT));
 124     }
 125 
 126     /** Get a named <code>String</code> value from the current style
 127      *
 128      * @param part a <code>Part</code>
 129      * @param state a <code>String</code>
 130      * @param attributeKey a <code>String</code>
 131      * @return a <code>String</code> or null if key is not found
 132      *    in the current style
 133      *
 134      * This is currently only used by WindowsInternalFrameTitlePane for painting
 135      * title foregound and can be removed when no longer needed
 136      */
 137     String getString(Component c, Part part, State state, Prop prop) {
 138         return getTypeEnumName(c, part, state, prop);
 139     }
 140 
 141     TypeEnum getTypeEnum(Component c, Part part, State state, Prop prop) {
 142         int enumValue = ThemeReader.getEnum(part.getControlName(c), part.getValue(),
 143                                             State.getValue(part, state),
 144                                             prop.getValue());
 145         return TypeEnum.getTypeEnum(prop, enumValue);
 146     }
 147 
 148     private static String getTypeEnumName(Component c, Part part, State state, Prop prop) {
 149         int enumValue = ThemeReader.getEnum(part.getControlName(c), part.getValue(),
 150                                             State.getValue(part, state),
 151                                             prop.getValue());
 152         if (enumValue == -1) {
 153             return null;
 154         }
 155         return TypeEnum.getTypeEnum(prop, enumValue).getName();
 156     }
 157 
 158 
 159 
 160 
 161     /** Get a named <code>int</code> value from the current style
 162      *
 163      * @param part a <code>Part</code>
 164      * @return an <code>int</code> or null if key is not found
 165      *    in the current style
 166      */
 167     int getInt(Component c, Part part, State state, Prop prop, int fallback) {
 168         return ThemeReader.getInt(part.getControlName(c), part.getValue(),
 169                                   State.getValue(part, state),
 170                                   prop.getValue());
 171     }
 172 
 173     /** Get a named <code>Dimension</code> value from the current style
 174      *
 175      * @param key a <code>String</code>
 176      * @return a <code>Dimension</code> or null if key is not found
 177      *    in the current style
 178      *
 179      * This is currently only used by WindowsProgressBarUI and the value
 180      * should probably be cached there instead of here.
 181      */
 182     Dimension getDimension(Component c, Part part, State state, Prop prop) {
 183         Dimension d = ThemeReader.getPosition(part.getControlName(c), part.getValue(),
 184                                               State.getValue(part, state),
 185                                               prop.getValue());
 186         return (d != null) ? d : new Dimension();
 187     }
 188 
 189     /** Get a named <code>Point</code> (e.g. a location or an offset) value
 190      *  from the current style
 191      *
 192      * @param key a <code>String</code>
 193      * @return a <code>Point</code> or null if key is not found
 194      *    in the current style
 195      *
 196      * This is currently only used by WindowsInternalFrameTitlePane for painting
 197      * title foregound and can be removed when no longer needed
 198      */
 199     Point getPoint(Component c, Part part, State state, Prop prop) {
 200         Dimension d = ThemeReader.getPosition(part.getControlName(c), part.getValue(),
 201                                               State.getValue(part, state),
 202                                               prop.getValue());
 203         return (d != null) ? new Point(d.width, d.height) : new Point();
 204     }
 205 
 206     /** Get a named <code>Insets</code> value from the current style
 207      *
 208      * @param key a <code>String</code>
 209      * @return an <code>Insets</code> object or null if key is not found
 210      *    in the current style
 211      *
 212      * This is currently only used to create borders and by
 213      * WindowsInternalFrameTitlePane for painting title foregound.
 214      * The return value is already cached in those places.
 215      */
 216     Insets getMargin(Component c, Part part, State state, Prop prop) {
 217         Insets insets = ThemeReader.getThemeMargins(part.getControlName(c), part.getValue(),
 218                                                     State.getValue(part, state),
 219                                                     prop.getValue());
 220         return (insets != null) ? insets : new Insets(0, 0, 0, 0);
 221     }
 222 
 223 
 224     /** Get a named <code>Color</code> value from the current style
 225      *
 226      * @param part a <code>Part</code>
 227      * @return a <code>Color</code> or null if key is not found
 228      *    in the current style
 229      */
 230     synchronized Color getColor(Skin skin, Prop prop, Color fallback) {
 231         String key = skin.toString() + "." + prop.name();
 232         Part part = skin.part;
 233         Color color = colorMap.get(key);
 234         if (color == null) {
 235             color = ThemeReader.getColor(part.getControlName(null), part.getValue(),
 236                                          State.getValue(part, skin.state),
 237                                          prop.getValue());
 238             if (color != null) {
 239                 color = new ColorUIResource(color);
 240                 colorMap.put(key, color);
 241             }
 242         }
 243         return (color != null) ? color : fallback;
 244     }
 245 
 246     Color getColor(Component c, Part part, State state, Prop prop, Color fallback) {
 247         return getColor(new Skin(c, part, state), prop, fallback);
 248     }
 249 
 250 
 251 
 252     /** Get a named <code>Border</code> value from the current style
 253      *
 254      * @param part a <code>Part</code>
 255      * @return a <code>Border</code> or null if key is not found
 256      *    in the current style or if the style for the particular
 257      *    part is not defined as "borderfill".
 258      */
 259     synchronized Border getBorder(Component c, Part part) {
 260         if (part == Part.MENU) {
 261             // Special case because XP has no skin for menus
 262             if (flatMenus) {
 263                 // TODO: The classic border uses this color, but we should
 264                 // create a new UI property called "PopupMenu.borderColor"
 265                 // instead.
 266                 return new XPFillBorder(UIManager.getColor("InternalFrame.borderShadow"),
 267                                         1);
 268             } else {
 269                 return null;    // Will cause L&F to use classic border
 270             }
 271         }
 272         Skin skin = new Skin(c, part, null);
 273         Border border = borderMap.get(skin.string);
 274         if (border == null) {
 275             String bgType = getTypeEnumName(c, part, null, Prop.BGTYPE);


 429                 margin = ((JToolBar)c).getMargin();
 430             } else if (c instanceof JTextComponent) {
 431                 margin = ((JTextComponent)c).getMargin();
 432             }
 433             if (margin != null) {
 434                 insets.top    = margin.top + 2;
 435                 insets.left   = margin.left + 2;
 436                 insets.bottom = margin.bottom + 2;
 437                 insets.right  = margin.right + 2;
 438             }
 439             return insets;
 440         }
 441     }
 442     boolean isSkinDefined(Component c, Part part) {
 443         return (part.getValue() == 0)
 444             || ThemeReader.isThemePartDefined(
 445                    part.getControlName(c), part.getValue(), 0);
 446     }
 447 
 448 
 449     /** Get a <code>Skin</code> object from the current style
 450      * for a named part (component type)
 451      *
 452      * @param part a <code>Part</code>
 453      * @return a <code>Skin</code> object
 454      */
 455     synchronized Skin getSkin(Component c, Part part) {
 456         assert isSkinDefined(c, part) : "part " + part + " is not defined";
 457         return new Skin(c, part, null);
 458     }
 459 
 460 
 461     long getThemeTransitionDuration(Component c, Part part, State stateFrom,
 462                                     State stateTo, Prop prop) {
 463          return ThemeReader.getThemeTransitionDuration(part.getControlName(c),
 464                                           part.getValue(),
 465                                           State.getValue(part, stateFrom),
 466                                           State.getValue(part, stateTo),
 467                                           (prop != null) ? prop.getValue() : 0);
 468     }
 469 
 470 
 471     /** A class which encapsulates attributes for a given part
 472      * (component type) and which provides methods for painting backgrounds
 473      * and glyphs


 547             return string.hashCode();
 548         }
 549 
 550         /** Paint a skin at x, y.
 551          *
 552          * @param g   the graphics context to use for painting
 553          * @param dx  the destination <i>x</i> coordinate
 554          * @param dy  the destination <i>y</i> coordinate
 555          * @param state which state to paint
 556          */
 557         void paintSkin(Graphics g, int dx, int dy, State state) {
 558             if (state == null) {
 559                 state = this.state;
 560             }
 561             paintSkin(g, dx, dy, getWidth(state), getHeight(state), state);
 562         }
 563 
 564         /** Paint a skin in an area defined by a rectangle.
 565          *
 566          * @param g the graphics context to use for painting
 567          * @param r     a <code>Rectangle</code> defining the area to fill,
 568          *                     may cause the image to be stretched or tiled
 569          * @param state which state to paint
 570          */
 571         void paintSkin(Graphics g, Rectangle r, State state) {
 572             paintSkin(g, r.x, r.y, r.width, r.height, state);
 573         }
 574 
 575         /** Paint a skin at a defined position and size
 576          *  This method supports animation.
 577          *
 578          * @param g   the graphics context to use for painting
 579          * @param dx  the destination <i>x</i> coordinate
 580          * @param dy  the destination <i>y</i> coordinate
 581          * @param dw  the width of the area to fill, may cause
 582          *                  the image to be stretched or tiled
 583          * @param dh  the height of the area to fill, may cause
 584          *                  the image to be stretched or tiled
 585          * @param state which state to paint
 586          */
 587         void paintSkin(Graphics g, int dx, int dy, int dw, int dh, State state) {




   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 /*
  27  * <p>These classes are designed to be used while the
  28  * corresponding {@code LookAndFeel} class has been installed
  29  * (<code>UIManager.setLookAndFeel(new <i>XXX</i>LookAndFeel())</code>).
  30  * Using them while a different {@code LookAndFeel} is installed
  31  * may produce unexpected results, including exceptions.
  32  * Additionally, changing the {@code LookAndFeel}
  33  * maintained by the {@code UIManager} without updating the
  34  * corresponding {@code ComponentUI} of any
  35  * {@code JComponent}s may also produce unexpected results,
  36  * such as the wrong colors showing up, and is generally not
  37  * encouraged.
  38  *
  39  */
  40 
  41 package com.sun.java.swing.plaf.windows;
  42 
  43 import java.awt.*;
  44 import java.awt.image.*;
  45 import java.security.AccessController;
  46 import java.util.*;
  47 
  48 import javax.swing.*;
  49 import javax.swing.border.*;
  50 import javax.swing.plaf.*;
  51 import javax.swing.text.JTextComponent;
  52 
  53 import sun.awt.image.SunWritableRaster;
  54 import sun.awt.windows.ThemeReader;
  55 import sun.security.action.GetPropertyAction;


 106             if (themeActive.booleanValue()) {
 107                 GetPropertyAction propertyAction =
 108                     new GetPropertyAction("swing.noxp");
 109                 if (AccessController.doPrivileged(propertyAction) == null &&
 110                     ThemeReader.isThemed() &&
 111                     !(UIManager.getLookAndFeel()
 112                       instanceof WindowsClassicLookAndFeel)) {
 113 
 114                     xp = new XPStyle();
 115                 }
 116             }
 117         }
 118         return ThemeReader.isXPStyleEnabled() ? xp : null;
 119     }
 120 
 121     static boolean isVista() {
 122         XPStyle xp = XPStyle.getXP();
 123         return (xp != null && xp.isSkinDefined(null, Part.CP_DROPDOWNBUTTONRIGHT));
 124     }
 125 
 126     /** Get a named {@code String} value from the current style
 127      *
 128      * @param part a {@code Part}
 129      * @param state a {@code String}
 130      * @param attributeKey a {@code String}
 131      * @return a {@code String} or null if key is not found
 132      *    in the current style
 133      *
 134      * This is currently only used by WindowsInternalFrameTitlePane for painting
 135      * title foregound and can be removed when no longer needed
 136      */
 137     String getString(Component c, Part part, State state, Prop prop) {
 138         return getTypeEnumName(c, part, state, prop);
 139     }
 140 
 141     TypeEnum getTypeEnum(Component c, Part part, State state, Prop prop) {
 142         int enumValue = ThemeReader.getEnum(part.getControlName(c), part.getValue(),
 143                                             State.getValue(part, state),
 144                                             prop.getValue());
 145         return TypeEnum.getTypeEnum(prop, enumValue);
 146     }
 147 
 148     private static String getTypeEnumName(Component c, Part part, State state, Prop prop) {
 149         int enumValue = ThemeReader.getEnum(part.getControlName(c), part.getValue(),
 150                                             State.getValue(part, state),
 151                                             prop.getValue());
 152         if (enumValue == -1) {
 153             return null;
 154         }
 155         return TypeEnum.getTypeEnum(prop, enumValue).getName();
 156     }
 157 
 158 
 159 
 160 
 161     /** Get a named {@code int} value from the current style
 162      *
 163      * @param part a {@code Part}
 164      * @return an {@code int} or null if key is not found
 165      *    in the current style
 166      */
 167     int getInt(Component c, Part part, State state, Prop prop, int fallback) {
 168         return ThemeReader.getInt(part.getControlName(c), part.getValue(),
 169                                   State.getValue(part, state),
 170                                   prop.getValue());
 171     }
 172 
 173     /** Get a named {@code Dimension} value from the current style
 174      *
 175      * @param key a {@code String}
 176      * @return a {@code Dimension} or null if key is not found
 177      *    in the current style
 178      *
 179      * This is currently only used by WindowsProgressBarUI and the value
 180      * should probably be cached there instead of here.
 181      */
 182     Dimension getDimension(Component c, Part part, State state, Prop prop) {
 183         Dimension d = ThemeReader.getPosition(part.getControlName(c), part.getValue(),
 184                                               State.getValue(part, state),
 185                                               prop.getValue());
 186         return (d != null) ? d : new Dimension();
 187     }
 188 
 189     /** Get a named {@code Point} (e.g. a location or an offset) value
 190      *  from the current style
 191      *
 192      * @param key a {@code String}
 193      * @return a {@code Point} or null if key is not found
 194      *    in the current style
 195      *
 196      * This is currently only used by WindowsInternalFrameTitlePane for painting
 197      * title foregound and can be removed when no longer needed
 198      */
 199     Point getPoint(Component c, Part part, State state, Prop prop) {
 200         Dimension d = ThemeReader.getPosition(part.getControlName(c), part.getValue(),
 201                                               State.getValue(part, state),
 202                                               prop.getValue());
 203         return (d != null) ? new Point(d.width, d.height) : new Point();
 204     }
 205 
 206     /** Get a named {@code Insets} value from the current style
 207      *
 208      * @param key a {@code String}
 209      * @return an {@code Insets} object or null if key is not found
 210      *    in the current style
 211      *
 212      * This is currently only used to create borders and by
 213      * WindowsInternalFrameTitlePane for painting title foregound.
 214      * The return value is already cached in those places.
 215      */
 216     Insets getMargin(Component c, Part part, State state, Prop prop) {
 217         Insets insets = ThemeReader.getThemeMargins(part.getControlName(c), part.getValue(),
 218                                                     State.getValue(part, state),
 219                                                     prop.getValue());
 220         return (insets != null) ? insets : new Insets(0, 0, 0, 0);
 221     }
 222 
 223 
 224     /** Get a named {@code Color} value from the current style
 225      *
 226      * @param part a {@code Part}
 227      * @return a {@code Color} or null if key is not found
 228      *    in the current style
 229      */
 230     synchronized Color getColor(Skin skin, Prop prop, Color fallback) {
 231         String key = skin.toString() + "." + prop.name();
 232         Part part = skin.part;
 233         Color color = colorMap.get(key);
 234         if (color == null) {
 235             color = ThemeReader.getColor(part.getControlName(null), part.getValue(),
 236                                          State.getValue(part, skin.state),
 237                                          prop.getValue());
 238             if (color != null) {
 239                 color = new ColorUIResource(color);
 240                 colorMap.put(key, color);
 241             }
 242         }
 243         return (color != null) ? color : fallback;
 244     }
 245 
 246     Color getColor(Component c, Part part, State state, Prop prop, Color fallback) {
 247         return getColor(new Skin(c, part, state), prop, fallback);
 248     }
 249 
 250 
 251 
 252     /** Get a named {@code Border} value from the current style
 253      *
 254      * @param part a {@code Part}
 255      * @return a {@code Border} or null if key is not found
 256      *    in the current style or if the style for the particular
 257      *    part is not defined as "borderfill".
 258      */
 259     synchronized Border getBorder(Component c, Part part) {
 260         if (part == Part.MENU) {
 261             // Special case because XP has no skin for menus
 262             if (flatMenus) {
 263                 // TODO: The classic border uses this color, but we should
 264                 // create a new UI property called "PopupMenu.borderColor"
 265                 // instead.
 266                 return new XPFillBorder(UIManager.getColor("InternalFrame.borderShadow"),
 267                                         1);
 268             } else {
 269                 return null;    // Will cause L&F to use classic border
 270             }
 271         }
 272         Skin skin = new Skin(c, part, null);
 273         Border border = borderMap.get(skin.string);
 274         if (border == null) {
 275             String bgType = getTypeEnumName(c, part, null, Prop.BGTYPE);


 429                 margin = ((JToolBar)c).getMargin();
 430             } else if (c instanceof JTextComponent) {
 431                 margin = ((JTextComponent)c).getMargin();
 432             }
 433             if (margin != null) {
 434                 insets.top    = margin.top + 2;
 435                 insets.left   = margin.left + 2;
 436                 insets.bottom = margin.bottom + 2;
 437                 insets.right  = margin.right + 2;
 438             }
 439             return insets;
 440         }
 441     }
 442     boolean isSkinDefined(Component c, Part part) {
 443         return (part.getValue() == 0)
 444             || ThemeReader.isThemePartDefined(
 445                    part.getControlName(c), part.getValue(), 0);
 446     }
 447 
 448 
 449     /** Get a {@code Skin} object from the current style
 450      * for a named part (component type)
 451      *
 452      * @param part a {@code Part}
 453      * @return a {@code Skin} object
 454      */
 455     synchronized Skin getSkin(Component c, Part part) {
 456         assert isSkinDefined(c, part) : "part " + part + " is not defined";
 457         return new Skin(c, part, null);
 458     }
 459 
 460 
 461     long getThemeTransitionDuration(Component c, Part part, State stateFrom,
 462                                     State stateTo, Prop prop) {
 463          return ThemeReader.getThemeTransitionDuration(part.getControlName(c),
 464                                           part.getValue(),
 465                                           State.getValue(part, stateFrom),
 466                                           State.getValue(part, stateTo),
 467                                           (prop != null) ? prop.getValue() : 0);
 468     }
 469 
 470 
 471     /** A class which encapsulates attributes for a given part
 472      * (component type) and which provides methods for painting backgrounds
 473      * and glyphs


 547             return string.hashCode();
 548         }
 549 
 550         /** Paint a skin at x, y.
 551          *
 552          * @param g   the graphics context to use for painting
 553          * @param dx  the destination <i>x</i> coordinate
 554          * @param dy  the destination <i>y</i> coordinate
 555          * @param state which state to paint
 556          */
 557         void paintSkin(Graphics g, int dx, int dy, State state) {
 558             if (state == null) {
 559                 state = this.state;
 560             }
 561             paintSkin(g, dx, dy, getWidth(state), getHeight(state), state);
 562         }
 563 
 564         /** Paint a skin in an area defined by a rectangle.
 565          *
 566          * @param g the graphics context to use for painting
 567          * @param r     a {@code Rectangle} defining the area to fill,
 568          *                     may cause the image to be stretched or tiled
 569          * @param state which state to paint
 570          */
 571         void paintSkin(Graphics g, Rectangle r, State state) {
 572             paintSkin(g, r.x, r.y, r.width, r.height, state);
 573         }
 574 
 575         /** Paint a skin at a defined position and size
 576          *  This method supports animation.
 577          *
 578          * @param g   the graphics context to use for painting
 579          * @param dx  the destination <i>x</i> coordinate
 580          * @param dy  the destination <i>y</i> coordinate
 581          * @param dw  the width of the area to fill, may cause
 582          *                  the image to be stretched or tiled
 583          * @param dh  the height of the area to fill, may cause
 584          *                  the image to be stretched or tiled
 585          * @param state which state to paint
 586          */
 587         void paintSkin(Graphics g, int dx, int dy, int dw, int dh, State state) {


< prev index next >