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.common;
032:
033: import java.awt.Component;
034: import java.awt.Graphics;
035: import java.awt.Image;
036: import java.awt.Insets;
037:
038: import javax.swing.ImageIcon;
039: import javax.swing.JComponent;
040: import javax.swing.border.AbstractBorder;
041:
042: /**
043: * A border with a drop shadow intended to be used as the outer border
044: * of popups. Can paint the screen background if used with heavy-weight
045: * popup windows.
046: *
047: * @author Stefan Matthias Aust
048: * @author Karsten Lentzsch
049: * @author Andrej Golovnin
050: * @version $Revision: 1.3 $
051: *
052: * @see ShadowPopup
053: * @see ShadowPopupFactory
054: */
055: final class ShadowPopupBorder extends AbstractBorder {
056:
057: /**
058: * The drop shadow needs 5 pixels at the bottom and the right hand side.
059: */
060: private static final int SHADOW_SIZE = 5;
061:
062: /**
063: * The singleton instance used to draw all borders.
064: */
065: private static ShadowPopupBorder instance = new ShadowPopupBorder();
066:
067: /**
068: * The drop shadow is created from a PNG image with 8 bit alpha channel.
069: */
070: private static Image shadow = new ImageIcon(ShadowPopupBorder.class
071: .getResource("shadow.png")).getImage();
072:
073: // Instance Creation *****************************************************
074:
075: /**
076: * Returns the singleton instance used to draw all borders.
077: */
078: public static ShadowPopupBorder getInstance() {
079: return instance;
080: }
081:
082: /**
083: * Paints the border for the specified component with the specified
084: * position and size.
085: */
086: public void paintBorder(Component c, Graphics g, int x, int y,
087: int width, int height) {
088: // fake drop shadow effect in case of heavy weight popups
089: JComponent popup = (JComponent) c;
090: Image hShadowBg = (Image) popup
091: .getClientProperty(ShadowPopupFactory.PROP_HORIZONTAL_BACKGROUND);
092: if (hShadowBg != null) {
093: g.drawImage(hShadowBg, x, y + height - 5, c);
094: }
095: Image vShadowBg = (Image) popup
096: .getClientProperty(ShadowPopupFactory.PROP_VERTICAL_BACKGROUND);
097: if (vShadowBg != null) {
098: g.drawImage(vShadowBg, x + width - 5, y, c);
099: }
100:
101: // draw drop shadow
102: g.drawImage(shadow, x + 5, y + height - 5, x + 10, y + height,
103: 0, 6, 5, 11, null, c);
104: g.drawImage(shadow, x + 10, y + height - 5, x + width - 5, y
105: + height, 5, 6, 6, 11, null, c);
106: g.drawImage(shadow, x + width - 5, y + 5, x + width, y + 10, 6,
107: 0, 11, 5, null, c);
108: g.drawImage(shadow, x + width - 5, y + 10, x + width, y
109: + height - 5, 6, 5, 11, 6, null, c);
110: g.drawImage(shadow, x + width - 5, y + height - 5, x + width, y
111: + height, 6, 6, 11, 11, null, c);
112: }
113:
114: /**
115: * Returns the insets of the border.
116: */
117: public Insets getBorderInsets(Component c) {
118: return new Insets(0, 0, SHADOW_SIZE, SHADOW_SIZE);
119: }
120:
121: /**
122: * Reinitializes the insets parameter with this Border's current Insets.
123: * @param c the component for which this border insets value applies
124: * @param insets the object to be reinitialized
125: * @return the <code>insets</code> object
126: */
127: public Insets getBorderInsets(Component c, Insets insets) {
128: insets.left = insets.top = 0;
129: insets.right = insets.bottom = SHADOW_SIZE;
130: return insets;
131: }
132:
133: }
|