SynthLookAndFeel.javaAPI DocJava SE 5 API22401Fri Aug 26 14:58:12 BST 2005javax.swing.plaf.synth


public class SynthLookAndFeel extends BasicLookAndFeel
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 package summary for an example of loading a file, and {@link javax.swing.plaf.synth.SynthStyleFactory} for an example of providing your own SynthStyleFactory to setStyleFactory.

Warning: 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}.

1.45, 05/07/04
Scott Violet

Fields Summary
static final Insets
Used in a handful of places where we need an empty Insets.
private static final Object
AppContext key to get the current SynthStyleFactory.
private static SynthStyleFactory
The last SynthStyleFactory that was asked for from AppContext lastContext.
private static boolean
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 lastContext before returning it.
private static AppContext
AppContext lastLAF came from.
static ComponentUI
static int
private SynthStyleFactory
SynthStyleFactory for the this SynthLookAndFeel.
private Map
Map of defaults table entries. This is populated via the load method.
Constructors Summary
public SynthLookAndFeel()
Creates a SynthLookAndFeel.

For the returned SynthLookAndFeel to be useful you need to invoke load to specify the set of SynthStyles, or invoke setStyleFactory.


        factory = new DefaultSynthStyleFactory();
Methods Summary
private static void_updateStyles(java.awt.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();
            if (name != null) {
        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++) {
public static javax.swing.plaf.ComponentUIcreateUI(javax.swing.JComponent c)
Creates the Synth look and feel ComponentUI for the passed in JComponent.

c JComponent to create the ComponentUI for
ComponentUI to use for 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);
        else if (key == "TextPaneUI") {
            return SynthTextPaneUI.createUI(c);
        else if (key == "ToggleButtonUI") {
            return SynthToggleButtonUI.createUI(c);
        else if (key == "ToolBarSeparatorUI") {
            return SynthSeparatorUI.createUI(c);
        else if (key == "ToolBarUI") {
            return SynthToolBarUI.createUI(c);
        else if (key == "ToolTipUI") {
            return SynthToolTipUI.createUI(c);
        else if (key == "TreeUI") {
            return SynthTreeUI.createUI(c);
        else if (key == "ViewportUI") {
            return SynthViewportUI.createUI(c);
        return null;
static intgetComponentState(java.awt.Component c)
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.

        if (c.isEnabled()) {
            if (c.isFocusOwner()) {
                return SynthUI.ENABLED | SynthUI.FOCUSED;
            return SynthUI.ENABLED;
        return SynthUI.DISABLED;
public javax.swing.UIDefaultsgetDefaults()
Returns the defaults for this SynthLookAndFeel.

Defaults able.

	UIDefaults table = new UIDefaults();
              "com.sun.swing.internal.plaf.basic.resources.basic" );

        // These need to be defined for JColorChooser to work.
                  new Dimension(10, 10));
        table.put("ColorChooser.swatchesDefaultRecentColor", Color.RED);
        table.put("ColorChooser.swatchesSwatchSize", new Dimension(10, 10));

        // These are needed for PopupMenu.
        table.put("PopupMenu.selectedWindowInputMapBindings", new Object[] {
		  "ESCAPE", "cancel",
                    "DOWN", "selectNext",
		 "KP_DOWN", "selectNext",
		      "UP", "selectPrevious",
		   "KP_UP", "selectPrevious",
		    "LEFT", "selectParent",
		 "KP_LEFT", "selectParent",
		   "RIGHT", "selectChild",
		"KP_RIGHT", "selectChild",
		   "ENTER", "return",
		   "SPACE", "return"
                  new Object[] {
		    "LEFT", "selectChild",
		 "KP_LEFT", "selectChild",
		   "RIGHT", "selectParent",
		"KP_RIGHT", "selectParent",

        if (defaultsMap != null) {
        return table;
public java.lang.StringgetDescription()
Returns a textual description of SynthLookAndFeel.

textual description of synth.

        return "Synth look and feel";
public java.lang.StringgetID()
Return a string that identifies this look and feel.

a short string identifying this look and feel.

        return "Synth";
public java.lang.StringgetName()
Return a short string that identifies this look and feel.

a short string identifying this look and feel.

        return "Synth look and feel";
static java.awt.InsetsgetPaintingInsets(javax.swing.plaf.synth.SynthContext state, java.awt.Insets insets)
A convenience method to return where the foreground should be painted for the Component identified by the passed in AbstractSynthContext.

        if (state.isSubregion()) {
            insets = state.getStyle().getInsets(state, insets);
        else {
            insets = state.getComponent().getInsets(insets);
        return insets;
public static javax.swing.plaf.synth.RegiongetRegion(javax.swing.JComponent c)
Returns the Region for the JComponent c.

c JComponent to fetch the Region for
Region corresponding to c

        return Region.getRegion(c);
public static javax.swing.plaf.synth.SynthStylegetStyle(javax.swing.JComponent c, javax.swing.plaf.synth.Region region)
Gets a SynthStyle for the specified region of the specified component. This is not for general consumption, only custom UIs should call this method.

c JComponent to get the SynthStyle for
region Identifies the region of the specified component
SynthStyle to use.

        return getStyleFactory().getStyle(c, region);
public static javax.swing.plaf.synth.SynthStyleFactorygetStyleFactory()
Returns the current SynthStyleFactory.


        synchronized(SynthLookAndFeel.class) {
            if (!multipleApps) {
                return lastFactory;
            AppContext context = AppContext.getAppContext();

            if (lastContext == context) {
                return lastFactory;
            lastContext = context;
            lastFactory = (SynthStyleFactory)AppContext.getAppContext().get
            return lastFactory;
static java.lang.ObjectgetUIOfType(javax.swing.plaf.ComponentUI ui, java.lang.Class klass)
Returns the ui that is of type klass, or null if one can not be found.

        if (klass.isInstance(ui)) {
            return ui;
        return null;
public voidinitialize()
Called by UIManager when this look and feel is installed.

        DefaultLookup.setDefaultLookup(new SynthDefaultLookup());
static booleanisLeftToRight(java.awt.Component c)

        return c.getComponentOrientation().isLeftToRight();
public booleanisNativeLookAndFeel()
Returns false, SynthLookAndFeel is not a native look and feel.


        return false;
public booleanisSupportedLookAndFeel()
Returns true, SynthLookAndFeel is always supported.


        return true;
public voidload( input, java.lang.Class resourceBase)
Loads the set of SynthStyles that will be used by this SynthLookAndFeel. resourceBase is used to resolve any path based resources, for example an Image would be resolved by resourceBase.getResource(path). Refer to Synth File Format for more information.

input InputStream to load from
resourceBase Used to resolve any images or other resources
ParseException If there is an error in parsing
IllegalArgumentException if input or resourceBase is null

        if (defaultsMap == null) {
            defaultsMap = new HashMap();
        new SynthParser().parse(input, (DefaultSynthStyleFactory)factory,
                                resourceBase, defaultsMap);
private static voidpaintRegion(javax.swing.plaf.synth.SynthContext state, java.awt.Graphics g, java.awt.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 voidresetSelectedUI()
Clears out the selected UI that was last set in setSelectedUI.

        selectedUI = null;
static voidsetSelectedUI(javax.swing.plaf.ComponentUI uix, boolean selected, boolean focused, boolean enabled)
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 selectedUI (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.

        selectedUI = uix;
        selectedUIState = 0;
        if (selected) {
            selectedUIState = SynthConstants.SELECTED;
            if (focused) {
                selectedUIState |= SynthConstants.FOCUSED;
        else {
            selectedUIState = SynthConstants.FOCUSED;
            if (enabled) {
                selectedUIState |= SynthConstants.ENABLED;
            else {
                selectedUIState |= SynthConstants.DISABLED;
public static voidsetStyleFactory(javax.swing.plaf.synth.SynthStyleFactory cache)
Sets the SynthStyleFactory that the UI classes provided by synth will use to obtain a SynthStyle.

cache SynthStyleFactory the UIs should use.

        // 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);
static booleanshouldUpdateStyle(java.beans.PropertyChangeEvent event)
Returns true if the Style should be updated in response to the specified PropertyChangeEvent. This forwards to shouldUpdateStyleOnAncestorChanged as necessary.

        String eName = event.getPropertyName();
        if ("name" == eName) {
            // Always update on a name change
            return true;
        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 &&
        return false;
public booleanshouldUpdateStyleOnAncestorChanged()
Returns whether or not the UIs should update their SynthStyles from the SynthStyleFactory when the ancestor of the JComponent changes. A subclass that provided a SynthStyleFactory that based the return value from getStyle off the containment hierarchy would override this method to return true.

whether or not the UIs should update their SynthStyles from the SynthStyleFactory when the ancestor changed.

        return false;
public voiduninitialize()
Called by UIManager when this look and feel is uninstalled.

        // We should uninstall the StyleFactory here, but unfortunately
        // there are a handful of things that retain references to the
        // LookAndFeel and expect things to work
static voidupdate(javax.swing.plaf.synth.SynthContext state, java.awt.Graphics g)
A convenience method that handles painting of the background. All SynthUI implementations should override update and invoke this method.

        paintRegion(state, g, null);
static javax.swing.plaf.synth.SynthStyleupdateStyle(javax.swing.plaf.synth.SynthContext context, javax.swing.plaf.synth.SynthUI ui)
A convience method that will reset the Style of StyleContext if necessary.


        SynthStyle newStyle = getStyle(context.getComponent(),
        SynthStyle oldStyle = context.getStyle();

        if (newStyle != oldStyle) {
            if (oldStyle != null) {
            newStyle.installDefaults(context, ui);
        return newStyle;
public static voidupdateStyles(java.awt.Component c)
Updates the style associated with c, and all its children. This is a lighter version of SwingUtilities.updateComponentTreeUI.

c Component to update style for.

static voidupdateSubregion(javax.swing.plaf.synth.SynthContext state, java.awt.Graphics g, java.awt.Rectangle bounds)
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.

        paintRegion(state, g, bounds);
private voidwriteObject( out)

        throw new NotSerializableException(this.getClass().getName());