977 lines · 32.9 KB · Java
RawDownload
/* * Copyright (c) 2002, 2010, 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 javax.swing.plaf.synth; import java.awt.*;import java.beans.*;import java.io.*;import java.lang.ref.*;import java.net.*;import java.security.*;import java.text.*;import java.util.*;import javax.swing.*;import javax.swing.plaf.*;import javax.swing.plaf.basic.*; import sun.awt.*;import sun.security.action.*;import sun.swing.*;import sun.swing.plaf.synth.*; /** * SynthLookAndFeel provides the basis for creating a customized look and * feel. SynthLookAndFeel does not directly provide a look, all painting is * delegated. * You need to either provide a configuration file, by way of the * {@link #load} method, or provide your own {@link SynthStyleFactory} * to {@link #setStyleFactory}. Refer to the * <a href="package-summary.html">package summary</a> for an example of * loading a file, and {@link javax.swing.plaf.synth.SynthStyleFactory} for * an example of providing your own <code>SynthStyleFactory</code> to * <code>setStyleFactory</code>. * <p> * <strong>Warning:</strong> * This class implements {@link Serializable} as a side effect of it * extending {@link BasicLookAndFeel}. It is not intended to be serialized. * An attempt to serialize it will * result in {@link NotSerializableException}. * * @serial exclude * @since 1.5 * @author Scott Violet */public class SynthLookAndFeel extends BasicLookAndFeel {    /**     * Used in a handful of places where we need an empty Insets.     */    static final Insets EMPTY_UIRESOURCE_INSETS = new InsetsUIResource(                                                            0, 0, 0, 0);     /**     * AppContext key to get the current SynthStyleFactory.     */    private static final Object STYLE_FACTORY_KEY =                  new StringBuffer("com.sun.java.swing.plaf.gtk.StyleCache");     /**     * The last SynthStyleFactory that was asked for from AppContext     * <code>lastContext</code>.     */    private static SynthStyleFactory lastFactory;    /**     * If this is true it indicates there is more than one AppContext active     * and that we need to make sure in getStyleCache the requesting     * AppContext matches that of <code>lastContext</code> before returning     * it.     */    private static boolean multipleApps;    /**     * AppContext lastLAF came from.     */    private static AppContext lastContext;     // Refer to setSelectedUI    static ComponentUI selectedUI;    // Refer to setSelectedUI    static int selectedUIState;     /**     * SynthStyleFactory for the this SynthLookAndFeel.     */    private SynthStyleFactory factory;     /**     * Map of defaults table entries. This is populated via the load     * method.     */    private Map<String, Object> defaultsMap;     private Handler _handler;     /**     * Used by the renderers. For the most part the renderers are implemented     * as Labels, which is problematic in so far as they are never selected.     * To accomodate this SynthLabelUI checks if the current     * UI matches that of <code>selectedUI</code> (which this methods sets), if     * it does, then a state as set by this method is returned. This provides     * a way for labels to have a state other than selected.     */    static void setSelectedUI(ComponentUI uix, boolean selected,                              boolean focused, boolean enabled,                              boolean rollover) {        selectedUI = uix;        selectedUIState = 0;        if (selected) {            selectedUIState = SynthConstants.SELECTED;            if (focused) {                selectedUIState |= SynthConstants.FOCUSED;            }        }        else if (rollover && enabled) {            selectedUIState |=                    SynthConstants.MOUSE_OVER | SynthConstants.ENABLED;            if (focused) {                selectedUIState |= SynthConstants.FOCUSED;            }        }        else {            if (enabled) {                selectedUIState |= SynthConstants.ENABLED;                selectedUIState = SynthConstants.FOCUSED;            }            else {                selectedUIState |= SynthConstants.DISABLED;            }        }    }     /**     * Clears out the selected UI that was last set in setSelectedUI.     */    static void resetSelectedUI() {        selectedUI = null;    }      /**     * Sets the SynthStyleFactory that the UI classes provided by     * synth will use to obtain a SynthStyle.     *     * @param cache SynthStyleFactory the UIs should use.     */    public static void setStyleFactory(SynthStyleFactory cache) {        // We assume the setter is called BEFORE the getter has been invoked        // for a particular AppContext.        synchronized(SynthLookAndFeel.class) {            AppContext context = AppContext.getAppContext();            if (!multipleApps && context != lastContext &&                                 lastContext != null) {                multipleApps = true;            }            lastFactory = cache;            lastContext = context;            context.put(STYLE_FACTORY_KEY, cache);        }    }     /**     * Returns the current SynthStyleFactory.     *     * @return SynthStyleFactory     */    public static SynthStyleFactory getStyleFactory() {        synchronized(SynthLookAndFeel.class) {            if (!multipleApps) {                return lastFactory;            }            AppContext context = AppContext.getAppContext();             if (lastContext == context) {                return lastFactory;            }            lastContext = context;            lastFactory = (SynthStyleFactory)AppContext.getAppContext().get                                           (STYLE_FACTORY_KEY);            return lastFactory;        }    }     /**     * Returns the component state for the specified component. This should     * only be used for Components that don't have any special state beyond     * that of ENABLED, DISABLED or FOCUSED. For example, buttons shouldn't     * call into this method.     */    static int getComponentState(Component c) {        if (c.isEnabled()) {            if (c.isFocusOwner()) {                return SynthUI.ENABLED | SynthUI.FOCUSED;            }            return SynthUI.ENABLED;        }        return SynthUI.DISABLED;    }     /**     * Gets a SynthStyle for the specified region of the specified component.     * This is not for general consumption, only custom UIs should call this     * method.     *     * @param c JComponent to get the SynthStyle for     * @param region Identifies the region of the specified component     * @return SynthStyle to use.     */    public static SynthStyle getStyle(JComponent c, Region region) {        return getStyleFactory().getStyle(c, region);    }     /**     * Returns true if the Style should be updated in response to the     * specified PropertyChangeEvent. This forwards to     * <code>shouldUpdateStyleOnAncestorChanged</code> as necessary.     */    static boolean shouldUpdateStyle(PropertyChangeEvent event) {        LookAndFeel laf = UIManager.getLookAndFeel();        return (laf instanceof SynthLookAndFeel &&                ((SynthLookAndFeel) laf).shouldUpdateStyleOnEvent(event));    }     /**     * A convience method that will reset the Style of StyleContext if     * necessary.     *     * @return newStyle     */    static SynthStyle updateStyle(SynthContext context, SynthUI ui) {        SynthStyle newStyle = getStyle(context.getComponent(),                                       context.getRegion());        SynthStyle oldStyle = context.getStyle();         if (newStyle != oldStyle) {            if (oldStyle != null) {                oldStyle.uninstallDefaults(context);            }            context.setStyle(newStyle);            newStyle.installDefaults(context, ui);        }        return newStyle;    }     /**     * Updates the style associated with <code>c</code>, and all its children.     * This is a lighter version of     * <code>SwingUtilities.updateComponentTreeUI</code>.     *     * @param c Component to update style for.     */    public static void updateStyles(Component c) {        if (c instanceof JComponent) {            // Yes, this is hacky. A better solution is to get the UI            // and cast, but JComponent doesn't expose a getter for the UI            // (each of the UIs do), making that approach impractical.            String name = c.getName();            c.setName(null);            if (name != null) {                c.setName(name);            }            ((JComponent)c).revalidate();        }        Component[] children = null;        if (c instanceof JMenu) {            children = ((JMenu)c).getMenuComponents();        }        else if (c instanceof Container) {            children = ((Container)c).getComponents();        }        if (children != null) {            for (Component child : children) {                updateStyles(child);            }        }        c.repaint();    }     /**     * Returns the Region for the JComponent <code>c</code>.     *     * @param c JComponent to fetch the Region for     * @return Region corresponding to <code>c</code>     */    public static Region getRegion(JComponent c) {        return Region.getRegion(c);    }     /**     * A convenience method to return where the foreground should be     * painted for the Component identified by the passed in     * AbstractSynthContext.     */    static Insets getPaintingInsets(SynthContext state, Insets insets) {        if (state.isSubregion()) {            insets = state.getStyle().getInsets(state, insets);        }        else {            insets = state.getComponent().getInsets(insets);        }        return insets;    }     /**     * A convenience method that handles painting of the background.     * All SynthUI implementations should override update and invoke     * this method.     */    static void update(SynthContext state, Graphics g) {        paintRegion(state, g, null);    }     /**     * A convenience method that handles painting of the background for     * subregions. All SynthUI's that have subregions should invoke     * this method, than paint the foreground.     */    static void updateSubregion(SynthContext state, Graphics g,                                Rectangle bounds) {        paintRegion(state, g, bounds);    }     private static void paintRegion(SynthContext state, Graphics g,                                    Rectangle bounds) {        JComponent c = state.getComponent();        SynthStyle style = state.getStyle();        int x, y, width, height;         if (bounds == null) {            x = 0;            y = 0;            width = c.getWidth();            height = c.getHeight();        }        else {            x = bounds.x;            y = bounds.y;            width = bounds.width;            height = bounds.height;        }         // Fill in the background, if necessary.        boolean subregion = state.isSubregion();        if ((subregion && style.isOpaque(state)) ||                          (!subregion && c.isOpaque())) {            g.setColor(style.getColor(state, ColorType.BACKGROUND));            g.fillRect(x, y, width, height);        }    }     static boolean isLeftToRight(Component c) {        return c.getComponentOrientation().isLeftToRight();    }     /**     * Returns the ui that is of type <code>klass</code>, or null if     * one can not be found.     */    static Object getUIOfType(ComponentUI ui, Class klass) {        if (klass.isInstance(ui)) {            return ui;        }        return null;    }     /**     * Creates the Synth look and feel <code>ComponentUI</code> for     * the passed in <code>JComponent</code>.     *     * @param c JComponent to create the <code>ComponentUI</code> for     * @return ComponentUI to use for <code>c</code>     */    public static ComponentUI createUI(JComponent c) {        String key = c.getUIClassID().intern();         if (key == "ButtonUI") {            return SynthButtonUI.createUI(c);        }        else if (key == "CheckBoxUI") {            return SynthCheckBoxUI.createUI(c);        }        else if (key == "CheckBoxMenuItemUI") {            return SynthCheckBoxMenuItemUI.createUI(c);        }        else if (key == "ColorChooserUI") {            return SynthColorChooserUI.createUI(c);        }        else if (key == "ComboBoxUI") {            return SynthComboBoxUI.createUI(c);        }        else if (key == "DesktopPaneUI") {            return SynthDesktopPaneUI.createUI(c);        }        else if (key == "DesktopIconUI") {            return SynthDesktopIconUI.createUI(c);        }        else if (key == "EditorPaneUI") {            return SynthEditorPaneUI.createUI(c);        }        else if (key == "FileChooserUI") {            return SynthFileChooserUI.createUI(c);        }        else if (key == "FormattedTextFieldUI") {            return SynthFormattedTextFieldUI.createUI(c);        }        else if (key == "InternalFrameUI") {            return SynthInternalFrameUI.createUI(c);        }        else if (key == "LabelUI") {            return SynthLabelUI.createUI(c);        }        else if (key == "ListUI") {            return SynthListUI.createUI(c);        }        else if (key == "MenuBarUI") {            return SynthMenuBarUI.createUI(c);        }        else if (key == "MenuUI") {            return SynthMenuUI.createUI(c);        }        else if (key == "MenuItemUI") {            return SynthMenuItemUI.createUI(c);        }        else if (key == "OptionPaneUI") {            return SynthOptionPaneUI.createUI(c);        }        else if (key == "PanelUI") {            return SynthPanelUI.createUI(c);        }        else if (key == "PasswordFieldUI") {            return SynthPasswordFieldUI.createUI(c);        }        else if (key == "PopupMenuSeparatorUI") {            return SynthSeparatorUI.createUI(c);        }        else if (key == "PopupMenuUI") {            return SynthPopupMenuUI.createUI(c);        }        else if (key == "ProgressBarUI") {            return SynthProgressBarUI.createUI(c);        }        else if (key == "RadioButtonUI") {            return SynthRadioButtonUI.createUI(c);        }        else if (key == "RadioButtonMenuItemUI") {            return SynthRadioButtonMenuItemUI.createUI(c);        }        else if (key == "RootPaneUI") {            return SynthRootPaneUI.createUI(c);        }        else if (key == "ScrollBarUI") {            return SynthScrollBarUI.createUI(c);        }        else if (key == "ScrollPaneUI") {            return SynthScrollPaneUI.createUI(c);        }        else if (key == "SeparatorUI") {            return SynthSeparatorUI.createUI(c);        }        else if (key == "SliderUI") {            return SynthSliderUI.createUI(c);        }        else if (key == "SpinnerUI") {            return SynthSpinnerUI.createUI(c);        }        else if (key == "SplitPaneUI") {            return SynthSplitPaneUI.createUI(c);        }        else if (key == "TabbedPaneUI") {            return SynthTabbedPaneUI.createUI(c);        }        else if (key == "TableUI") {            return SynthTableUI.createUI(c);        }        else if (key == "TableHeaderUI") {            return SynthTableHeaderUI.createUI(c);        }        else if (key == "TextAreaUI") {            return SynthTextAreaUI.createUI(c);        }        else if (key == "TextFieldUI") {            return SynthTextFieldUI.createUI(c);

Lines 1–500 of 977.