001: /*
002: * Copyright (c) 2003-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.validation.extras;
032:
033: import java.awt.Component;
034: import java.awt.Graphics;
035:
036: import javax.swing.Icon;
037:
038: /**
039: * An <code>Icon</code> implementation that paints two icons
040: * as compound or overlaid icon using a specified alignment.<p>
041: *
042: * <strong>Note:</strong> This class is not yet part of the binary Validation
043: * library; it comes with the Validation distributions as an extra.
044: * <strong>The API is work in progress and may change without notice;
045: * this class may even be completely removed from future distributions.</strong>
046: * If you want to use this class, you may consider copying it into
047: * your code base.
048: *
049: * @author Karsten Lentzsch
050: * @version $Revision: 1.11 $
051: *
052: * @see javax.swing.ImageIcon
053: */
054: public final class CompoundIcon implements Icon {
055:
056: /**
057: * Describes how to position the foreground icon to the background icon.
058: */
059: public enum Anchor {
060: CENTER, NORTH, NORTHEAST, EAST, SOUTHEAST, SOUTH, SOUTHWEST, WEST, NORTHWEST
061: }
062:
063: /**
064: * Refers to the icon that will be painted in the background.
065: */
066: private final Icon backgroundIcon;
067:
068: /**
069: * Refers to the icon that will be painted in the foreground.
070: * This will often be a smaller overlay icon.
071: */
072: private final Icon foregroundIcon;
073:
074: private final int height;
075: private final int width;
076: private int xOffset;
077: private int yOffset;
078:
079: // Instance Creation ******************************************************
080:
081: /**
082: * Constructs a compound icon for the given foreground and background icons,
083: * using a default anchor.
084: *
085: * @param backgroundIcon the icon in the centered background
086: * @param foregroundIcon the icon that overlays the background icon
087: */
088: public CompoundIcon(Icon backgroundIcon, Icon foregroundIcon) {
089: this (backgroundIcon, foregroundIcon, Anchor.SOUTHEAST);
090: }
091:
092: /**
093: * Constructs a compound icon for the given foreground and background icons,
094: * using the specified anchor.
095: *
096: * @param backgroundIcon the icon in the centered background
097: * @param foregroundIcon the icon that overlays the background icon
098: * @param anchor the position of the foreground icon relative
099: * to the background icon
100: */
101: public CompoundIcon(Icon backgroundIcon, Icon foregroundIcon,
102: Anchor anchor) {
103: this .backgroundIcon = backgroundIcon;
104: this .foregroundIcon = foregroundIcon;
105: height = Math.max(backgroundIcon.getIconHeight(),
106: foregroundIcon.getIconHeight());
107: width = Math.max(backgroundIcon.getIconWidth(), foregroundIcon
108: .getIconWidth());
109: setAnchor(anchor);
110: }
111:
112: // Implementing the Icon Interface ****************************************
113:
114: /**
115: * Returns this icon's width, which is the maximum of
116: * the widths of the background and foreground icons.
117: *
118: * @return an int specifying the fixed width of this icon.
119: */
120: public int getIconWidth() {
121: return width;
122: }
123:
124: /**
125: * Returns this icon's height, which is the maximum of
126: * the heights of the background and foreground icons.
127: *
128: * @return an int specifying the fixed height of this icon.
129: */
130: public int getIconHeight() {
131: return height;
132: }
133:
134: /**
135: * Draws this icon at the specified location. First paints
136: * the background icon at the specified location, then paints
137: * the foreground icon using the offsets computed in #setAnchor.
138: */
139: public void paintIcon(Component c, Graphics g, int x, int y) {
140: backgroundIcon.paintIcon(c, g, x, y);
141: foregroundIcon.paintIcon(c, g, x + xOffset, y + yOffset);
142: }
143:
144: // Helper Code ************************************************************
145:
146: private void setAnchor(Anchor anchor) {
147: int xDiff = backgroundIcon.getIconWidth()
148: - foregroundIcon.getIconWidth();
149: int yDiff = backgroundIcon.getIconHeight()
150: - foregroundIcon.getIconHeight();
151:
152: xOffset = ((anchor == Anchor.NORTHWEST)
153: || (anchor == Anchor.WEST) || (anchor == Anchor.SOUTHWEST)) ? 0
154: : (((anchor == Anchor.NORTH)
155: || (anchor == Anchor.CENTER) || (anchor == Anchor.SOUTH)) ? xDiff / 2
156: : xDiff);
157:
158: yOffset = ((anchor == Anchor.NORTHWEST)
159: || (anchor == Anchor.NORTH) || (anchor == Anchor.NORTHEAST)) ? 0
160: : (((anchor == Anchor.WEST)
161: || (anchor == Anchor.CENTER) || (anchor == Anchor.EAST)) ? yDiff / 2
162: : yDiff);
163: }
164:
165: }
|