001: /*
002: * Copyright (c) 2001-2007 JGoodies Karsten Lentzsch. 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 JGoodies Karsten Lentzsch 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:
031: package com.jgoodies.looks.plastic;
032:
033: import java.awt.*;
034:
035: import javax.swing.JComponent;
036: import javax.swing.UIManager;
037:
038: /**
039: * Consists exclusively of static methods that provide convenience behavior.
040: *
041: * @author Karsten Lentzsch
042: * @version $Revision: 1.3 $
043: */
044:
045: public final class PlasticUtils {
046:
047: private PlasticUtils() {
048: // Overrides default constructor; prevents instantiation.
049: }
050:
051: static void drawDark3DBorder(Graphics g, int x, int y, int w, int h) {
052: drawFlush3DBorder(g, x, y, w, h);
053: g.setColor(PlasticLookAndFeel.getControl());
054: g.drawLine(x + 1, y + 1, 1, h - 3);
055: g.drawLine(y + 1, y + 1, w - 3, 1);
056: }
057:
058: static void drawDisabledBorder(Graphics g, int x, int y, int w,
059: int h) {
060: g.setColor(PlasticLookAndFeel.getControlShadow());
061: drawRect(g, x, y, w - 1, h - 1);
062: }
063:
064: /*
065: * Unlike <code>MetalUtils</code> we first draw with highlight then dark shadow
066: */
067: static void drawFlush3DBorder(Graphics g, int x, int y, int w, int h) {
068: g.translate(x, y);
069: g.setColor(PlasticLookAndFeel.getControlHighlight());
070: drawRect(g, 1, 1, w - 2, h - 2);
071: g.drawLine(0, h - 1, 0, h - 1);
072: g.drawLine(w - 1, 0, w - 1, 0);
073: g.setColor(PlasticLookAndFeel.getControlDarkShadow());
074: drawRect(g, 0, 0, w - 2, h - 2);
075: g.translate(-x, -y);
076: }
077:
078: /*
079: * Copied from <code>MetalUtils</code>.
080: */
081: static void drawPressed3DBorder(Graphics g, int x, int y, int w,
082: int h) {
083: g.translate(x, y);
084: drawFlush3DBorder(g, 0, 0, w, h);
085: g.setColor(PlasticLookAndFeel.getControlShadow());
086: g.drawLine(1, 1, 1, h - 3);
087: g.drawLine(1, 1, w - 3, 1);
088: g.translate(-x, -y);
089: }
090:
091: /*
092: * Copied from <code>MetalUtils</code>.
093: */
094: static void drawButtonBorder(Graphics g, int x, int y, int w,
095: int h, boolean active) {
096: if (active) {
097: drawActiveButtonBorder(g, x, y, w, h);
098: } else {
099: drawFlush3DBorder(g, x, y, w, h);
100: }
101: }
102:
103: /*
104: * Copied from <code>MetalUtils</code>.
105: */
106: static void drawActiveButtonBorder(Graphics g, int x, int y, int w,
107: int h) {
108: drawFlush3DBorder(g, x, y, w, h);
109: g.setColor(PlasticLookAndFeel.getPrimaryControl());
110: g.drawLine(x + 1, y + 1, x + 1, h - 3);
111: g.drawLine(x + 1, y + 1, w - 3, x + 1);
112: g.setColor(PlasticLookAndFeel.getPrimaryControlDarkShadow());
113: g.drawLine(x + 2, h - 2, w - 2, h - 2);
114: g.drawLine(w - 2, y + 2, w - 2, h - 2);
115: }
116:
117: /*
118: * Modified edges.
119: */
120: static void drawDefaultButtonBorder(Graphics g, int x, int y,
121: int w, int h, boolean active) {
122: drawButtonBorder(g, x + 1, y + 1, w - 1, h - 1, active);
123: g.translate(x, y);
124: g.setColor(PlasticLookAndFeel.getControlDarkShadow());
125: drawRect(g, 0, 0, w - 3, h - 3);
126: g.drawLine(w - 2, 0, w - 2, 0);
127: g.drawLine(0, h - 2, 0, h - 2);
128: g.setColor(PlasticLookAndFeel.getControl());
129: g.drawLine(w - 1, 0, w - 1, 0);
130: g.drawLine(0, h - 1, 0, h - 1);
131: g.translate(-x, -y);
132: }
133:
134: static void drawDefaultButtonPressedBorder(Graphics g, int x,
135: int y, int w, int h) {
136: drawPressed3DBorder(g, x + 1, y + 1, w - 1, h - 1);
137: g.translate(x, y);
138: g.setColor(PlasticLookAndFeel.getControlDarkShadow());
139: drawRect(g, 0, 0, w - 3, h - 3);
140: g.drawLine(w - 2, 0, w - 2, 0);
141: g.drawLine(0, h - 2, 0, h - 2);
142: g.setColor(PlasticLookAndFeel.getControl());
143: g.drawLine(w - 1, 0, w - 1, 0);
144: g.drawLine(0, h - 1, 0, h - 1);
145: g.translate(-x, -y);
146: }
147:
148: static void drawThinFlush3DBorder(Graphics g, int x, int y, int w,
149: int h) {
150: g.translate(x, y);
151: g.setColor(PlasticLookAndFeel.getControlHighlight());
152: g.drawLine(0, 0, w - 2, 0);
153: g.drawLine(0, 0, 0, h - 2);
154: g.setColor(PlasticLookAndFeel.getControlDarkShadow());
155: g.drawLine(w - 1, 0, w - 1, h - 1);
156: g.drawLine(0, h - 1, w - 1, h - 1);
157: g.translate(-x, -y);
158: }
159:
160: static void drawThinPressed3DBorder(Graphics g, int x, int y,
161: int w, int h) {
162: g.translate(x, y);
163: g.setColor(PlasticLookAndFeel.getControlDarkShadow());
164: g.drawLine(0, 0, w - 2, 0);
165: g.drawLine(0, 0, 0, h - 2);
166: g.setColor(PlasticLookAndFeel.getControlHighlight());
167: g.drawLine(w - 1, 0, w - 1, h - 1);
168: g.drawLine(0, h - 1, w - 1, h - 1);
169: g.translate(-x, -y);
170: }
171:
172: /*
173: * Convenience function for determining ComponentOrientation. Helps us
174: * avoid having Munge directives throughout the code.
175: */
176: static boolean isLeftToRight(Component c) {
177: return c.getComponentOrientation().isLeftToRight();
178: }
179:
180: // 3D Effects ***********************************************************************
181:
182: /**
183: * Checks and returns whether the specified component type has 3D effects.
184: *
185: * @param keyPrefix the prefix of the key used to lookup the setting
186: * @return true if the component type shall be rendered with a 3D effect
187: * @see #force3D(JComponent)
188: * @see #forceFlat(JComponent)
189: */
190: static boolean is3D(String keyPrefix) {
191: Object value = UIManager.get(keyPrefix + "is3DEnabled");
192: return Boolean.TRUE.equals(value);
193: }
194:
195: /**
196: * Checks and returns whether we have a custom hint that forces the 3D mode.
197: *
198: * @param c the component to inspect
199: * @return true if the given component has a 3D hint set
200: * @see #forceFlat(JComponent)
201: */
202: static boolean force3D(JComponent c) {
203: Object value = c
204: .getClientProperty(PlasticLookAndFeel.IS_3D_KEY);
205: return Boolean.TRUE.equals(value);
206: }
207:
208: /**
209: * Checks and returns whether we have a custom hint that prevents the 3D mode.
210: *
211: * @param c the component to inspect
212: * @return true if the given component has a flat hint set
213: * @see #force3D(JComponent)
214: */
215: static boolean forceFlat(JComponent c) {
216: Object value = c
217: .getClientProperty(PlasticLookAndFeel.IS_3D_KEY);
218: return Boolean.FALSE.equals(value);
219: }
220:
221: // Painting 3D Effects *************************************************************
222:
223: private static final float FRACTION_3D = 0.5f;
224:
225: private static void add3DEffekt(Graphics g, Rectangle r,
226: boolean isHorizontal, Color startC0, Color stopC0,
227: Color startC1, Color stopC1) {
228:
229: Graphics2D g2 = (Graphics2D) g;
230: int xb0, yb0, xb1, yb1, xd0, yd0, xd1, yd1, width, height;
231: if (isHorizontal) {
232: width = r.width;
233: height = (int) (r.height * FRACTION_3D);
234: xb0 = r.x;
235: yb0 = r.y;
236: xb1 = xb0;
237: yb1 = yb0 + height;
238: xd0 = xb1;
239: yd0 = yb1;
240: xd1 = xd0;
241: yd1 = r.y + r.height;
242: } else {
243: width = (int) (r.width * FRACTION_3D);
244: height = r.height;
245: xb0 = r.x;
246: yb0 = r.y;
247: xb1 = xb0 + width;
248: yb1 = yb0;
249: xd0 = xb1;
250: yd0 = yb0;
251: xd1 = r.x + r.width;
252: yd1 = yd0;
253: }
254: g2.setPaint(new GradientPaint(xb0, yb0, stopC0, xb1, yb1,
255: startC0));
256: g2.fillRect(r.x, r.y, width, height);
257: g2.setPaint(new GradientPaint(xd0, yd0, startC1, xd1, yd1,
258: stopC1));
259: g2.fillRect(xd0, yd0, width, height);
260: }
261:
262: static void add3DEffekt(Graphics g, Rectangle r) {
263: Color brightenStop = UIManager.getColor("Plastic.brightenStop");
264: if (null == brightenStop)
265: brightenStop = PlasticTheme.BRIGHTEN_STOP;
266:
267: // Add round sides
268: Graphics2D g2 = (Graphics2D) g;
269: int border = 10;
270: g2.setPaint(new GradientPaint(r.x, r.y, brightenStop, r.x
271: + border, r.y, PlasticTheme.BRIGHTEN_START));
272: g2.fillRect(r.x, r.y, border, r.height);
273: int x = r.x + r.width - border;
274: int y = r.y;
275: g2.setPaint(new GradientPaint(x, y, PlasticTheme.DARKEN_START,
276: x + border, y, PlasticTheme.LT_DARKEN_STOP));
277: g2.fillRect(x, y, border, r.height);
278:
279: add3DEffekt(g, r, true, PlasticTheme.BRIGHTEN_START,
280: brightenStop, PlasticTheme.DARKEN_START,
281: PlasticTheme.LT_DARKEN_STOP);
282: }
283:
284: static void addLight3DEffekt(Graphics g, Rectangle r,
285: boolean isHorizontal) {
286: Color ltBrightenStop = UIManager
287: .getColor("Plastic.ltBrightenStop");
288: if (null == ltBrightenStop)
289: ltBrightenStop = PlasticTheme.LT_BRIGHTEN_STOP;
290:
291: add3DEffekt(g, r, isHorizontal, PlasticTheme.BRIGHTEN_START,
292: ltBrightenStop, PlasticTheme.DARKEN_START,
293: PlasticTheme.LT_DARKEN_STOP);
294: }
295:
296: /*
297: * TODO: Required by the Chartster and JPathReport Filler; move to a
298: * FillerUI.
299: */
300: public static void addLight3DEffekt(Graphics g, Rectangle r) {
301: Color ltBrightenStop = UIManager
302: .getColor("Plastic.ltBrightenStop");
303: if (null == ltBrightenStop)
304: ltBrightenStop = PlasticTheme.LT_BRIGHTEN_STOP;
305:
306: add3DEffekt(g, r, true, PlasticTheme.DARKEN_START,
307: PlasticTheme.LT_DARKEN_STOP,
308: PlasticTheme.BRIGHTEN_START, ltBrightenStop);
309: }
310:
311: // Low level graphics ***************************************************
312:
313: /*
314: * An optimized version of Graphics.drawRect.
315: */
316: private static void drawRect(Graphics g, int x, int y, int w, int h) {
317: g.fillRect(x, y, w + 1, 1);
318: g.fillRect(x, y + 1, 1, h);
319: g.fillRect(x + 1, y + h, w, 1);
320: g.fillRect(x + w, y + 1, 1, h);
321: }
322:
323: }
|