xpstyle.java

来自「JAVA的一些源码 JAVA2 STANDARD EDITION DEVELO」· Java 代码 · 共 656 行 · 第 1/2 页

JAVA
656
字号
/* * @(#)XPStyle.java	1.28 07/01/09 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. *//* * <p>These classes are designed to be used while the * corresponding <code>LookAndFeel</code> class has been installed * (<code>UIManager.setLookAndFeel(new <i>XXX</i>LookAndFeel())</code>). * Using them while a different <code>LookAndFeel</code> is installed * may produce unexpected results, including exceptions. * Additionally, changing the <code>LookAndFeel</code> * maintained by the <code>UIManager</code> without updating the * corresponding <code>ComponentUI</code> of any * <code>JComponent</code>s may also produce unexpected results, * such as the wrong colors showing up, and is generally not * encouraged. *  */package com.sun.java.swing.plaf.windows;import java.awt.*;import java.awt.image.*;import java.io.*;import java.security.AccessController;import java.util.*;import java.util.prefs.*;import javax.swing.*;import javax.swing.border.*;import javax.swing.plaf.*;import javax.swing.text.JTextComponent;import sun.awt.windows.ThemeReader;import sun.security.action.GetPropertyAction;import sun.swing.CachedPainter;import com.sun.java.swing.plaf.windows.TMSchema.*;/** * Implements Windows XP Styles for the Windows Look and Feel. * * @version 1.28 01/09/07 * @author Leif Samuelsson */class XPStyle {    // Singleton instance of this class    private static XPStyle xp;    // Singleton instance of SkinPainter    private static SkinPainter skinPainter = new SkinPainter();    private static Boolean themeActive = null;    private HashMap<String, Border> borderMap;    private HashMap<String, Color>  colorMap;    private boolean flatMenus;    static {        invalidateStyle();    }    /** Static method for clearing the hashmap and loading the     * current XP style and theme     */    static synchronized void invalidateStyle() {        xp = null;        themeActive = null;    }    /** Get the singleton instance of this class     *     * @return the singleton instance of this class or null if XP styles     * are not active or if this is not Windows XP     */    static synchronized XPStyle getXP() {        if (themeActive == null) {            Toolkit toolkit = Toolkit.getDefaultToolkit();            themeActive =                (Boolean)toolkit.getDesktopProperty("win.xpstyle.themeActive");            if (themeActive == null) {                themeActive = Boolean.FALSE;            }            if (themeActive.booleanValue()) {                GetPropertyAction propertyAction =                    new GetPropertyAction("swing.noxp");                if (AccessController.doPrivileged(propertyAction) == null &&                    ThemeReader.isThemed() &&                    !(UIManager.getLookAndFeel()                      instanceof WindowsClassicLookAndFeel)) {                    xp = new XPStyle();                }            }        }        return xp;    }    /** Get a named <code>String</code> value from the current style     *     * @param part a <code>Part</code>     * @param state a <code>String</code>     * @param attributeKey a <code>String</code>     * @return a <code>String</code> or null if key is not found     *    in the current style     *     * This is currently only used by WindowsInternalFrameTitlePane for painting     * title foregound and can be removed when no longer needed     */    String getString(Component c, Part part, State state, Prop prop) {        return getTypeEnumName(c, part, state, prop);    }    private static String getTypeEnumName(Component c, Part part, State state, Prop prop) {        int enumValue = ThemeReader.getEnum(part.getControlName(c), part.getValue(),                                            State.getValue(part, state),                                            prop.getValue());        if (enumValue == -1) {            return null;        }        return TypeEnum.getTypeEnum(prop, enumValue).getName();    }    /** Get a named <code>int</code> value from the current style     *     * @param part a <code>Part</code>     * @return an <code>int</code> or null if key is not found     *    in the current style     */    int getInt(Component c, Part part, State state, Prop prop, int fallback) {        return ThemeReader.getInt(part.getControlName(c), part.getValue(),                                  State.getValue(part, state),                                  prop.getValue());    }    /** Get a named <code>Dimension</code> value from the current style     *     * @param key a <code>String</code>     * @return a <code>Dimension</code> or null if key is not found     *    in the current style     *     * This is currently only used by WindowsProgressBarUI and the value     * should probably be cached there instead of here.     */    Dimension getDimension(Component c, Part part, State state, Prop prop) {        return ThemeReader.getPosition(part.getControlName(c), part.getValue(),                                       State.getValue(part, state),                                       prop.getValue());    }    /** Get a named <code>Point</code> (e.g. a location or an offset) value     *  from the current style     *     * @param key a <code>String</code>     * @return a <code>Point</code> or null if key is not found     *    in the current style     *     * This is currently only used by WindowsInternalFrameTitlePane for painting     * title foregound and can be removed when no longer needed     */    Point getPoint(Component c, Part part, State state, Prop prop) {        Dimension d = ThemeReader.getPosition(part.getControlName(c), part.getValue(),                                              State.getValue(part, state),                                              prop.getValue());        if (d != null) {            return new Point(d.width, d.height);        } else {            return null;        }    }    /** Get a named <code>Insets</code> value from the current style     *     * @param key a <code>String</code>     * @return an <code>Insets</code> object or null if key is not found     *    in the current style     *     * This is currently only used to create borders and by     * WindowsInternalFrameTitlePane for painting title foregound.     * The return value is already cached in those places.     */    Insets getMargin(Component c, Part part, State state, Prop prop) {        return ThemeReader.getThemeMargins(part.getControlName(c), part.getValue(),                                           State.getValue(part, state),                                           prop.getValue());    }    /** Get a named <code>Color</code> value from the current style     *     * @param part a <code>Part</code>     * @return a <code>Color</code> or null if key is not found     *    in the current style     */    synchronized Color getColor(Skin skin, Prop prop, Color fallback) {        String key = skin.toString() + "." + prop.name();        Part part = skin.part;        Color color = colorMap.get(key);        if (color == null) {            color = ThemeReader.getColor(part.getControlName(null), part.getValue(),                                         State.getValue(part, skin.state),                                         prop.getValue());            if (color != null) {                color = new ColorUIResource(color);                colorMap.put(key, color);            }        }        return (color != null) ? color : fallback;    }    Color getColor(Component c, Part part, State state, Prop prop, Color fallback) {        return getColor(new Skin(c, part, state), prop, fallback);    }    /** Get a named <code>Border</code> value from the current style     *     * @param part a <code>Part</code>     * @return a <code>Border</code> or null if key is not found     *    in the current style or if the style for the particular     *    part is not defined as "borderfill".     */    synchronized Border getBorder(Component c, Part part) {        if (part == Part.MENU) {            // Special case because XP has no skin for menus            if (flatMenus) {                // TODO: The classic border uses this color, but we should                // create a new UI property called "PopupMenu.borderColor"                // instead.                return new XPFillBorder(UIManager.getColor("InternalFrame.borderShadow"),                                        1);            } else {                return null;    // Will cause L&F to use classic border            }        }        Skin skin = new Skin(c, part, null);        Border border = borderMap.get(skin.string);        if (border == null) {            String bgType = getTypeEnumName(c, part, null, Prop.BGTYPE);            if ("borderfill".equalsIgnoreCase(bgType)) {                int thickness = getInt(c, part, null, Prop.BORDERSIZE, 1);                Color color = getColor(skin, Prop.BORDERCOLOR, Color.black);                border = new XPFillBorder(color, thickness);            } else if ("imagefile".equalsIgnoreCase(bgType)) {                Insets m = getMargin(c, part, null, Prop.SIZINGMARGINS);                if (m != null) {                    if (getBoolean(c, part, null, Prop.BORDERONLY)) {                        border = new XPImageBorder(c, part);                    } else {                        if(part == Part.TP_BUTTON) {                            border = new XPEmptyBorder(new Insets(3,3,3,3));                        } else {                            border = new XPEmptyBorder(m);                        }                    }                }            }            if (border != null) {                borderMap.put(skin.string, border);            }        }        return border;    }    private class XPFillBorder extends LineBorder implements UIResource {        XPFillBorder(Color color, int thickness) {            super(color, thickness);        }        public Insets getBorderInsets(Component c)       {            return getBorderInsets(c, new Insets(0,0,0,0));        }        public Insets getBorderInsets(Component c, Insets insets)       {            Insets margin = null;            //            // Ideally we'd have an interface defined for classes which            // support margins (to avoid this hackery), but we've            // decided against it for simplicity            //           if (c instanceof AbstractButton) {               margin = ((AbstractButton)c).getMargin();           } else if (c instanceof JToolBar) {               margin = ((JToolBar)c).getMargin();           } else if (c instanceof JTextComponent) {               margin = ((JTextComponent)c).getMargin();           }           insets.top    = (margin != null? margin.top : 0)    + thickness;           insets.left   = (margin != null? margin.left : 0)   + thickness;           insets.bottom = (margin != null? margin.bottom : 0) + thickness;           insets.right =  (margin != null? margin.right : 0)  + thickness;                          return insets;        }    }    private class XPImageBorder extends AbstractBorder implements UIResource {        Skin skin;        XPImageBorder(Component c, Part part) {            this.skin = getSkin(c, part);        }        public void paintBorder(Component c, Graphics g,                                int x, int y, int width, int height) {            skin.paintSkin(g, x, y, width, height, null);        }        public Insets getBorderInsets(Component c)       {            return getBorderInsets(c, new Insets(0,0,0,0));        }        public Insets getBorderInsets(Component c, Insets insets)       {            Insets margin = null;            Insets borderInsets = skin.getContentMargin();            //            // Ideally we'd have an interface defined for classes which            // support margins (to avoid this hackery), but we've

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?