001: /*
002: * Copyright (c) 2005-2008 Substance Kirill Grouchnikov. All Rights Reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * o Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * o Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * o Neither the name of Substance Kirill Grouchnikov nor the names of
015: * its contributors may be used to endorse or promote products derived
016: * from this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030: package org.jvnet.substance;
031:
032: import java.awt.*;
033: import java.awt.geom.Line2D;
034: import java.awt.geom.Rectangle2D;
035:
036: import javax.swing.border.Border;
037:
038: import org.jvnet.lafwidget.utils.RenderingUtils;
039: import org.jvnet.substance.color.ColorScheme;
040: import org.jvnet.substance.theme.SubstanceTheme;
041: import org.jvnet.substance.utils.*;
042:
043: /**
044: * Custom implementation of etched border.
045: *
046: * @author Kirill Grouchnikov
047: */
048: public class SubstanceEtchedBorder implements Border {
049: /**
050: * Returns the highlight color for the specified component.
051: *
052: * @param c
053: * Component.
054: * @return Matching highlight color.
055: */
056: public Color getHighlightColor(Component c) {
057: SubstanceTheme theme = SubstanceThemeUtilities.getTheme(c);
058: boolean isDark = SubstanceCoreUtilities.isThemeDark(theme
059: .getActiveTheme());
060: ColorScheme colorScheme = isDark ? theme.getActiveTheme()
061: .getColorScheme() : theme.getDefaultTheme()
062: .getColorScheme();
063:
064: Color foreDark = isDark ? colorScheme.getExtraLightColor()
065: : SubstanceColorUtilities.getInterpolatedColor(
066: colorScheme.getMidColor(), colorScheme
067: .getDarkColor(), 0.4);
068:
069: return SubstanceColorUtilities.getAlphaColor(foreDark, 196);
070: }
071:
072: /**
073: * Returns the shadow color for the specified component.
074: *
075: * @param c
076: * Component.
077: * @return Matching shadow color.
078: */
079: public Color getShadowColor(Component c) {
080: SubstanceTheme theme = SubstanceThemeUtilities.getTheme(c);
081: boolean isDark = SubstanceCoreUtilities.isThemeDark(theme
082: .getActiveTheme());
083: ColorScheme colorScheme = isDark ? theme.getActiveTheme()
084: .getColorScheme() : theme.getDefaultTheme()
085: .getColorScheme();
086:
087: Color back = isDark ? colorScheme.getDarkColor() : colorScheme
088: .getUltraLightColor();
089:
090: return SubstanceColorUtilities.getAlphaColor(back, 196);
091: }
092:
093: public boolean isBorderOpaque() {
094: return false;
095: }
096:
097: public void paintBorder(Component c, Graphics g, int x, int y,
098: int width, int height) {
099: int w = width;
100: int h = height;
101:
102: Graphics2D g2d = (Graphics2D) g.create();
103: float strokeWidth = SubstanceSizeUtils
104: .getBorderStrokeWidth(SubstanceSizeUtils
105: .getComponentFontSize(c));
106: g2d.setStroke(new BasicStroke(strokeWidth,
107: BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND));
108: g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
109: RenderingHints.VALUE_ANTIALIAS_ON);
110:
111: g2d.translate(x, y);
112:
113: g2d.setColor(getShadowColor(c));
114:
115: // this is to prevent clipping of thick outer borders.
116: int delta = (int) Math.floor(strokeWidth / 2.0);
117:
118: g2d.draw(new Rectangle2D.Float(delta, delta, w - delta - 2
119: * strokeWidth, h - delta - 2 * strokeWidth));
120: // g2d.drawRect(0, 0, w - 2, h - 2);
121:
122: g2d.setColor(getHighlightColor(c));
123: g2d.draw(new Line2D.Float(strokeWidth, h - 3 * strokeWidth,
124: strokeWidth, strokeWidth));
125: // g2d.drawLine(1, h - 3, 1, 1);
126: g2d.draw(new Line2D.Float(delta + strokeWidth, delta
127: + strokeWidth, w - delta - 3 * strokeWidth, delta
128: + strokeWidth));
129: // g2d.drawLine(1, 1, w - 3, 1);
130:
131: g2d.draw(new Line2D.Float(delta, h - delta - strokeWidth, w
132: - delta - strokeWidth, h - delta - strokeWidth));
133: // g2d.drawLine(0, h - 1, w - 1, h - 1);
134: g2d.draw(new Line2D.Float(w - delta - strokeWidth, h - delta
135: - strokeWidth, w - delta - strokeWidth, delta));
136: // g2d.drawLine(w - 1, h - 1, w - 1, 0);
137:
138: g2d.dispose();
139:
140: // this is a fix for defect 248 - in order to paint the TitledBorder
141: // text respecting the AA settings of the display, we have to
142: // set rendering hints on the passed Graphics object.
143: RenderingUtils.installDesktopHints((Graphics2D) g);
144: }
145:
146: /*
147: * (non-Javadoc)
148: *
149: * @see javax.swing.border.Border#getBorderInsets(java.awt.Component)
150: */
151: public Insets getBorderInsets(Component c) {
152: float borderStrokeWidth = SubstanceSizeUtils
153: .getBorderStrokeWidth(SubstanceSizeUtils
154: .getComponentFontSize(c));
155: int prefSize = (int) (Math.ceil(2.0 * borderStrokeWidth));
156: return new Insets(prefSize, prefSize, prefSize, prefSize);
157: }
158: }
|