📄 synthlookandfeel.java
字号:
/* * @(#)SynthLookAndFeel.java 1.48 05/05/24 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */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 * @version 1.48, 05/24/05 * @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 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) { String eName = event.getPropertyName(); if ("name" == eName) { // Always update on a name change return true; } else if ("componentOrientation" == eName) { // Always update on a component orientation change return true; } else if ("ancestor" == eName && event.getNewValue() != null) { // Only update on an ancestor change when getting a valid // parent and the LookAndFeel wants this. LookAndFeel laf = UIManager.getLookAndFeel(); return (laf instanceof SynthLookAndFeel && ((SynthLookAndFeel)laf). shouldUpdateStyleOnAncestorChanged()); } // Note: The following two nimbus based overrides should be refactored // to be in the Nimbus LAF. Due to constraints in an update release, // we couldn't actually provide the public API necessary to allow // NimbusLookAndFeel (a subclass of SynthLookAndFeel) to provide its // own rules for shouldUpdateStyle. else if ("Nimbus.Overrides" == eName) { // Always update when the Nimbus.Overrides client property has // been changed return true; } else if ("Nimbus.Overrides.InheritDefaults" == eName) { // Always update when the Nimbus.Overrides.InheritDefaults // client property has changed return true; } else if ("JComponent.sizeVariant" == eName) { // Always update when the JComponent.sizeVariant // client property has changed return true; } return false; } /** * 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) { _updateStyles(c); c.repaint(); } // Implementation for updateStyles private 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(int i = 0; i < children.length; i++) { updateStyles(children[i]); } } } /** * Returns the Region for the JComponent <code>c</code>. * * @param c JComponent to fetch the Region for * @return Region corresponding to <code>c</code>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -