001: /*
002: * Copyright (c) 2004 JETA Software, Inc. All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without modification,
005: * 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 JETA Software nor the names of its contributors may
015: * be used to endorse or promote products derived from this software without
016: * 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, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
021: * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
022: * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
023: * INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
024: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
025: * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
026: * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: */
029:
030: package com.jeta.forms.gui.effects;
031:
032: import java.awt.Component;
033: import java.awt.Graphics;
034: import java.awt.Rectangle;
035:
036: import javax.swing.Icon;
037:
038: import com.jeta.forms.gui.common.FormUtils;
039: import com.jeta.forms.store.properties.ImageProperty;
040: import com.jeta.open.registry.JETARegistry;
041: import com.jeta.open.resources.AppResourceLoader;
042: import com.jeta.open.resources.ResourceLoader;
043:
044: /**
045: * This class is an implementation of a painter that renders an image on a part
046: * of a canvas or component. The caller specifies an Icon and alignment
047: * properties for the painter. Since this is not an AWT component, the caller
048: * must explicitly call paint. The caller must also pass a rectangle that
049: * specifies the coordinates of the painting area relative to the given graphics
050: * context.
051: *
052: * @author Jeff Tassin
053: */
054: public class ImagePainter implements Painter {
055: /**
056: * The icon that is rendered when paint is called.
057: */
058: private Icon m_icon;
059:
060: /**
061: * The horizontal alignment ImageProperty.LEFT, CENTER, RIGHT
062: */
063: private int m_halign;
064:
065: /**
066: * The vertical alignment ImageProperty.TOP, CENTER, BOTTOM
067: */
068: private int m_valign;
069:
070: /**
071: * This icon is used in design mode when the assigned icon is null.
072: */
073: private static Icon m_design_icon;
074:
075: /**
076: * A rectangle used for clipping. We keep it around so we don't have to
077: * reinstantiate with every paint message.
078: */
079: private Rectangle m_rect = new Rectangle();
080:
081: /**
082: * Creates an <code>ImagePainter</code> instance with no icon.
083: */
084: public ImagePainter() {
085: this (null, 0, 0);
086: }
087:
088: /**
089: * Creates an <code>ImagePainter</code> instance with the specified icon
090: * and alignment properties.
091: *
092: * @param icon
093: * the icon that will be rendered on the graphics context when
094: * paint is invoked.
095: * @param hAlign
096: * the horizontal alignment of the icon relative to the painting
097: * area.
098: * @param vAlign
099: * the horizontal alignment of the icon relative to the painting
100: * area.
101: */
102: public ImagePainter(Icon icon, int hAlign, int vAlign) {
103: m_icon = icon;
104: m_halign = hAlign;
105: m_valign = vAlign;
106: synchronized (ImagePainter.class) {
107: if (m_design_icon == null) {
108: try {
109: /** use a place holder icon if the given icon is null */
110: if (FormUtils.isDesignMode()) {
111: ResourceLoader loader = (ResourceLoader) JETARegistry
112: .lookup(ResourceLoader.COMPONENT_ID);
113: FormUtils.safeAssert(loader != null);
114: if (loader != null) {
115: m_design_icon = loader
116: .loadImage("jeta.resources/images/general/16x16/portrait.png");
117: }
118: } else {
119: m_design_icon = AppResourceLoader
120: .getEmptyIcon();
121: }
122: } catch (Exception e) {
123: e.printStackTrace();
124: }
125: }
126: }
127: }
128:
129: /**
130: * Return the height of the icon associated with this painter.
131: *
132: * @return the height of the icon associated with this painter
133: */
134: public int getIconHeight() {
135: if (m_icon == null) {
136: if (m_design_icon == null)
137: return 0;
138: else
139: return m_design_icon.getIconHeight();
140: } else {
141: return m_icon.getIconHeight();
142: }
143: }
144:
145: /**
146: * Return the width of the icon associated with this painter.
147: *
148: * @return the width of the icon associated with this painter
149: */
150: public int getIconWidth() {
151: if (m_icon == null) {
152: if (m_design_icon == null)
153: return 0;
154: else
155: return m_design_icon.getIconWidth();
156: } else {
157: return m_icon.getIconWidth();
158: }
159: }
160:
161: /**
162: * Returns the horizontal alignment of the icon relative to the painting
163: * area. The alignment has an effect only if the painting area is larger
164: * than the icon size. Valid values are: ImageProperty.LEFT,
165: * ImageProperty.CENTER, ImageProperty.RIGHT
166: *
167: * @return the horizontal alignment of the icon. See
168: * {@link com.jeta.forms.store.properties.ImageProperty}
169: */
170: public int getHorizontalAlignment() {
171: return m_halign;
172: }
173:
174: /**
175: * Returns the vertical alignment of the icon relative to the painting area.
176: * The alignment has an effect only if the painting area is larger than the
177: * icon size. Valid values are: ImageProperty.TOP, ImageProperty.CENTER,
178: * ImageProperty.BOTTOM
179: *
180: * @return the vertical alignment of the icon. See
181: * {@link com.jeta.forms.store.properties.ImageProperty}
182: */
183: public int getVerticalAlignment() {
184: return m_valign;
185: }
186:
187: /**
188: * Returns the icon used by this painter.
189: *
190: * @return the icon associated with this painter.
191: */
192: public Icon getIcon() {
193: return m_icon;
194: }
195:
196: /**
197: * Sets the horizontal alignment of the icon relative to the painting area.
198: *
199: * @param halign
200: * the horizontal alignment of the icon.
201: */
202: public void setHorizontalAlignment(int halign) {
203: m_halign = halign;
204: }
205:
206: /**
207: * Sets the vertical alignment of the icon relative to the painting area.
208: *
209: * @param valign
210: * the vertical alignment of the icon.
211: */
212: public void setVerticalAlignment(int valign) {
213: m_valign = valign;
214: }
215:
216: /**
217: * Sets the icon used by this painter.
218: *
219: * @param icon
220: * the icon associated with this painter.
221: */
222: public void setIcon(Icon icon) {
223: m_icon = icon;
224: }
225:
226: /**
227: * Renders this image in the given rectangle. Note, that the coordinates
228: * passed here are different than the clipping rectangle.
229: *
230: * @param g
231: * the graphics context
232: * @param x
233: * the x position that defines the region to paint.
234: * @param y
235: * the y position that defines the region to paint.
236: * @param width
237: * the width that defines the region to paint.
238: * @param height
239: * the height that defines the region to paint.
240: */
241: public void paint(Component comp, Graphics g, int x1, int y1,
242: int width, int height) {
243: int x = x1;
244: int y = y1;
245:
246: int halign = getHorizontalAlignment();
247: if (halign == ImageProperty.CENTER) {
248: x = (width - getIconWidth()) / 2;
249: } else if (halign == ImageProperty.RIGHT) {
250: x = width - getIconWidth();
251: } else {
252: x = x1;
253: }
254:
255: int valign = getVerticalAlignment();
256: if (valign == ImageProperty.CENTER) {
257: y = (height - getIconHeight()) / 2;
258: } else if (valign == ImageProperty.BOTTOM) {
259: y = height - getIconHeight();
260: } else {
261: y = y1;
262: }
263:
264: if (x < x1)
265: x = x1;
266: if (y < y1)
267: y = y1;
268:
269: Icon icon = getIcon();
270:
271: Rectangle clip_rect = g.getClipBounds();
272: m_rect.setBounds(x, y, width, height);
273: if (m_rect.intersects(clip_rect)) {
274: m_rect = m_rect.intersection(clip_rect);
275: g.setClip(m_rect.x, m_rect.y, m_rect.width, m_rect.height);
276:
277: if (icon == null) {
278: if (m_design_icon != null)
279: m_design_icon.paintIcon(comp, g, x, y);
280: } else {
281: icon.paintIcon(comp, g, x, y);
282: }
283:
284: g.setClip(clip_rect.x, clip_rect.y, clip_rect.width,
285: clip_rect.height);
286: }
287: }
288:
289: /**
290: * Renders this image in the given rectangle
291: *
292: * @param g
293: * the graphics context
294: * @param rect
295: * the rectangle that defines the region to paint. Note, that
296: * this is different than the clipping rectangle.
297: */
298: public void paint(Component comp, Graphics g, Rectangle rect) {
299: if (rect == null)
300: return;
301:
302: paint(comp, g, rect.x, rect.y, rect.width, rect.height);
303: }
304:
305: }
|