/* * Copyright (c) 2009 Kathryn Huxtable and Kenneth Orr. * * This file is part of the SeaGlass Pluggable Look and Feel. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * $Id$ */ package com.seaglasslookandfeel; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.Insets; import javax.swing.JComponent; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.plaf.UIResource; import javax.swing.plaf.synth.ColorType; import javax.swing.plaf.synth.SynthContext; import javax.swing.plaf.synth.SynthGraphicsUtils; import javax.swing.plaf.synth.SynthPainter; import javax.swing.plaf.synth.SynthStyle; import com.seaglasslookandfeel.component.SeaGlassBorder; import com.seaglasslookandfeel.painter.SeaGlassPainter; import com.seaglasslookandfeel.ui.SeaglassUI; import com.seaglasslookandfeel.util.SeaGlassGraphicsUtils; /** * A SynthStyle implementation used by SeaGlass. This just wraps a SynthStyle * with a SeaGlass style in order to get at some SynthStyle methods that are * package local. * * @see javax.swing.plaf.synth.SynthStyle */ public final class SeaGlassStyleWrapper extends SeaGlassStyle { /** Shared SynthGraphics. */ private static final SynthGraphicsUtils SEAGLASS_GRAPHICS = new SeaGlassGraphicsUtils(); /** * The SynthPainter that will be returned from this SeaGlassStyle. The * SynthPainter returned will be a SeaGlassSynthPainterImpl, which will in * turn delegate back to this SeaGlassStyle for the proper Painter (not * SynthPainter) to use for painting the foreground, background, or border. */ private SynthPainter painter; private SynthStyle style; /** * Create a new SeaGlassStyle. Only the prefix must be supplied. At the * appropriate time, installDefaults will be called. At that point, all of * the state information will be pulled from UIManager and stored locally * within this style. * * @param style Something like Button or Slider.Thumb or * org.jdesktop.swingx.JXStatusBar or * ComboBox."ComboBox.arrowButton" */ SeaGlassStyleWrapper(SynthStyle style) { super(null, null); this.style = style; this.painter = new SeaGlassSynthPainterImpl(this); } /** * Returns the <code>SynthGraphicUtils</code> for the specified context. * * @param context SynthContext identifying requester * * @return SynthGraphicsUtils */ public SynthGraphicsUtils getGraphicsUtils(SynthContext context) { return SEAGLASS_GRAPHICS; } /** * Re-implements SynthStyle.installDefaults(SynthContext, SynthUI) because * it's package local. * * @param context the context. * @param ui the UI delegate. */ public void installDefaults(SeaGlassContext context, SeaglassUI ui) { // Special case the Border as this will likely change when the LAF // can have more control over this. if (!context.isSubregion()) { JComponent c = context.getComponent(); Border border = c.getBorder(); if (border == null || border instanceof UIResource) { c.setBorder(new SeaGlassBorder(ui, getInsets(context, null))); } } installDefaults(context); } /** * {@inheritDoc} */ @Override public void installDefaults(SynthContext ctx) { // delegate to the superclass to install defaults such as background, // foreground, font, and opaque onto the swing component. style.installDefaults(ctx); } /** * {@inheritDoc} */ @Override public Insets getInsets(SynthContext ctx, Insets in) { return style.getInsets(ctx, in); } /** * {@inheritDoc} */ @Override public Color getColorForState(SynthContext ctx, ColorType type) { return style.getColor(ctx, type); } /** * {@inheritDoc} */ @Override protected Font getFontForState(SynthContext ctx) { Font f = (Font) get(ctx, "font"); if (f == null) f = UIManager.getFont("defaultFont"); // Account for scale // The key "JComponent.sizeVariant" is used to match Apple's LAF String scaleKey = SeaGlassStyle.getSizeVariant(ctx.getComponent()); if (scaleKey != null) { if (LARGE_KEY.equals(scaleKey)) { f = f.deriveFont(Math.round(f.getSize2D() * LARGE_SCALE)); } else if (SMALL_KEY.equals(scaleKey)) { f = f.deriveFont(Math.round(f.getSize2D() * SMALL_SCALE)); } else if (MINI_KEY.equals(scaleKey)) { f = f.deriveFont(Math.round(f.getSize2D() * MINI_SCALE)); } } return f; } /** * {@inheritDoc} */ @Override public SynthPainter getPainter(SynthContext ctx) { return painter; } /** * {@inheritDoc} */ @Override public boolean isOpaque(SynthContext ctx) { return style.isOpaque(ctx); } /** * {@inheritDoc} */ @Override public Object get(SynthContext ctx, Object key) { return style.get(ctx, key); } /** * Gets the appropriate background Painter, if there is one, for the state * specified in the given SynthContext. This method does appropriate * fallback searching, as described in #get. * * @param ctx The SynthContext. Must not be null. * * @return The background painter associated for the given state, or null if * none could be found. */ @SuppressWarnings("unchecked") public SeaGlassPainter getBackgroundPainter(SynthContext ctx) { if (!(style instanceof SeaGlassStyle)) { return null; } return new PainterWrapper(((SeaGlassStyle) style).getBackgroundPainter(ctx)); } /** * Gets the appropriate foreground Painter, if there is one, for the state * specified in the given SynthContext. This method does appropriate * fallback searching, as described in #get. * * @param ctx The SynthContext. Must not be null. * * @return The foreground painter associated for the given state, or null if * none could be found. */ @SuppressWarnings("unchecked") public SeaGlassPainter getForegroundPainter(SynthContext ctx) { if (!(style instanceof SeaGlassStyle)) { return null; } return new PainterWrapper(((SeaGlassStyle) style).getForegroundPainter(ctx)); } /** * Gets the appropriate border Painter, if there is one, for the state * specified in the given SynthContext. This method does appropriate * fallback searching, as described in #get. * * @param ctx The SynthContext. Must not be null. * * @return The border painter associated for the given state, or null if * none could be found. */ @SuppressWarnings("unchecked") public SeaGlassPainter getBorderPainter(SynthContext ctx) { if (!(style instanceof SeaGlassStyle)) { return null; } return new PainterWrapper(((SeaGlassStyle) style).getBorderPainter(ctx)); } /** * Wrap the sun Painter class with our own. */ public class PainterWrapper implements SeaGlassPainter { private SeaGlassPainter<Object> painter; /** * Creates a new PainterWrapper object. * * @param painter the painter to be wrapped. */ public PainterWrapper(SeaGlassPainter<Object> painter) { this.painter = painter; } /** * @see com.seaglasslookandfeel.painter.SeaGlassPainter#paint(java.awt.Graphics2D, * java.lang.Object, int, int) */ public void paint(Graphics2D g, Object object, int width, int height) { painter.paint(g, object, width, height); } } }