/*
* 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: SeaGlassStyleWrapper.java 1595 2011-08-09 20:33:48Z rosstauscher@gmx.de $
*/
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);
}
}
}