001: /*
002: * $RCSfile: DisplayJAI.java,v $
003: *
004: * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Use is subject to license terms.
007: *
008: * $Revision: 1.1 $
009: * $Date: 2005/02/11 04:57:03 $
010: * $State: Exp $
011: */
012: package com.sun.media.jai.widget;
013:
014: import java.awt.Color;
015: import java.awt.Component;
016: import java.awt.Dimension;
017: import java.awt.Graphics;
018: import java.awt.Graphics2D;
019: import java.awt.Insets;
020: import java.awt.Point;
021: import java.awt.Rectangle;
022: import java.awt.event.MouseEvent;
023: import java.awt.event.MouseListener;
024: import java.awt.event.MouseMotionListener;
025: import java.awt.geom.AffineTransform;
026: import java.awt.image.RenderedImage;
027: import javax.swing.JComponent;
028: import javax.swing.JPanel;
029:
030: /**
031: * A Java<sup>TM</sup> Foundation Classes {@link JPanel} which is able
032: * to contain an image. The image and its container may have different
033: * sizes. The image may also be positioned within the container.
034: *
035: * <p>This class extends <code>JPanel</code> in order to support layout
036: * management. Image tiling is supported as of version 1.3 of the
037: * Java<sup>TM</sup> 2 Platform via
038: * {@link Graphics2D#drawRenderedImage(RenderedImage,AffineTransform)}.</p>
039: *
040: * <p><i>This class is not a committed part of the Java<sup>TM</sup>
041: * Advanced Imaging API per se. It might therefore not be supported by
042: * JAI implementations other than that of Sun Microsystems, Inc.</i></p>
043: *
044: * @see java.awt.Graphics2D
045: * @see java.awt.image.RenderedImage
046: * @see javax.swing.JPanel
047: * @see javax.swing.JComponent
048: */
049: public class DisplayJAI extends JPanel implements MouseListener,
050: MouseMotionListener {
051:
052: /** The image to display. */
053: protected RenderedImage source = null;
054:
055: /** Abscissa of image origin relative to panel origin. */
056: protected int originX = 0;
057:
058: /** Ordinate of image origin relative to panel origin. */
059: protected int originY = 0;
060:
061: /**
062: * Constructs a <code>DisplayJAI</code> and sets its
063: * the layout to <code>null</code>.
064: */
065: public DisplayJAI() {
066: super ();
067: setLayout(null);
068: }
069:
070: /**
071: * Constructs a <code>DisplayJAI</code>, sets its layout to
072: * <code>null</code>, and sets its displayed image.
073: *
074: * <p>The preferred size is set such that its width is the image
075: * width plus the left and right insets and its height is the image
076: * height plus the top and bottom insets.</p>
077: *
078: * @param image The image to display.
079: * @throws IllegalArgumentException if <code>image</code> is
080: * <code>null</code>.
081: */
082: public DisplayJAI(RenderedImage image) {
083: super ();
084: setLayout(null);
085:
086: if (image == null) {
087: throw new IllegalArgumentException("image == null!");
088: }
089:
090: source = image;
091:
092: // Swing geometry
093: int w = source.getWidth();
094: int h = source.getHeight();
095: Insets insets = getInsets();
096: Dimension dim = new Dimension(w + insets.left + insets.right, h
097: + insets.top + insets.bottom);
098:
099: setPreferredSize(dim);
100: }
101:
102: /**
103: * Moves the image within it's container. The instance variables
104: * <code>originX</code> and <code>originY</code> are set to the
105: * parameter valus <code>x</code> and <code>y</code>, respectively.
106: * {@link #repaint()} is invoked after the origin values are changed.
107: *
108: * @param x image origin abscissa.
109: * @param y image origin ordinate.
110: */
111: public void setOrigin(int x, int y) {
112: originX = x;
113: originY = y;
114: repaint();
115: }
116:
117: /** Retrieves the image origin. */
118: public Point getOrigin() {
119: return new Point(originX, originY);
120: }
121:
122: /**
123: * Sets a new image to display.
124: *
125: * <p>The preferred size is set such that its width is the image
126: * width plus the left and right insets and its height is the image
127: * height plus the top and bottom insets. {@link #revalidate()} and
128: * {@link #repaint()} are invoked after all other changes.</p>
129: *
130: * @param im The image to display.
131: * @throws IllegalArgumentException if <code>im</code> is
132: * <code>null</code>.
133: */
134: public void set(RenderedImage im) {
135: if (im == null) {
136: throw new IllegalArgumentException("im == null!");
137: }
138:
139: source = im;
140:
141: // Swing geometry
142: int w = source.getWidth();
143: int h = source.getHeight();
144: Insets insets = getInsets();
145: Dimension dim = new Dimension(w + insets.left + insets.right, h
146: + insets.top + insets.bottom);
147:
148: setPreferredSize(dim);
149: revalidate();
150: repaint();
151: }
152:
153: /**
154: * Sets a new image to display and its coordinates within the container.
155: *
156: * <p>The preferred size is set such that its width is the image
157: * width plus the left and right insets and its height is the image
158: * height plus the top and bottom insets. {@link #revalidate()} and
159: * {@link #repaint()} are invoked after all other changes.</p>
160: *
161: * @param im The image to display.
162: * @param x image origin abscissa.
163: * @param y image origin ordinate.
164: * @throws IllegalArgumentException if <code>im</code> is
165: * <code>null</code>.
166: */
167: public void set(RenderedImage im, int x, int y) {
168: if (im == null) {
169: throw new IllegalArgumentException("im == null!");
170: }
171:
172: source = im;
173:
174: // Swing geometry
175: int w = source.getWidth();
176: int h = source.getHeight();
177: Insets insets = getInsets();
178: Dimension dim = new Dimension(w + insets.left + insets.right, h
179: + insets.top + insets.bottom);
180:
181: setPreferredSize(dim);
182:
183: originX = x;
184: originY = y;
185:
186: revalidate();
187: repaint();
188: }
189:
190: /**
191: * Returns the image to be displayed by this panel.
192: *
193: * @return The value of the {@link #source} instance variable.
194: */
195: public RenderedImage getSource() {
196: return source;
197: }
198:
199: /**
200: * Draws the image or fills the panel with a background color.
201: *
202: * <p>If the current image is <code>null</code>, the rectangle
203: * <code>new Rectangle(0,0,{@link #getWidth()},{@link #getHeight()})</code>
204: * is filled with the background color returned by
205: * {@link #getBackground()}.</p>
206: *
207: * <p>If the current image is non-<code>null</code>, the rectangle
208: * returned by {@link Graphics2D#getClipBounds()} is filled with the
209: * background color and the image is drawn using
210: * {@link Graphics2D#drawRenderedImage(RenderedImage,AffineTransform)}
211: * at the location
212: * <code>({@link #getInsets()}.left+originX,
213: * {@link #getInsets()}.right+originY)</code>.
214: *
215: * @param g <code>Graphics</code> context in which to paint.
216: */
217: public synchronized void paintComponent(Graphics g) {
218:
219: Graphics2D g2d = (Graphics2D) g;
220:
221: // empty component (no image)
222: if (source == null) {
223: g2d.setColor(getBackground());
224: g2d.fillRect(0, 0, getWidth(), getHeight());
225: return;
226: }
227:
228: // clear damaged component area
229: Rectangle clipBounds = g2d.getClipBounds();
230: g2d.setColor(getBackground());
231: g2d.fillRect(clipBounds.x, clipBounds.y, clipBounds.width,
232: clipBounds.height);
233:
234: // account for borders
235: Insets insets = getInsets();
236: int tx = insets.left + originX;
237: int ty = insets.top + originY;
238:
239: // Translation moves the entire image within the container
240: try {
241: g2d.drawRenderedImage(source, AffineTransform
242: .getTranslateInstance(tx, ty));
243: } catch (OutOfMemoryError e) {
244: }
245: }
246:
247: /**
248: * An empty method which should be overridden by subclasses which
249: * respond to mouse presses.
250: */
251: public void mousePressed(MouseEvent e) {
252: }
253:
254: /**
255: * An empty method which should be overridden by subclasses which
256: * respond to mouse releases.
257: */
258: public void mouseReleased(MouseEvent e) {
259: }
260:
261: /**
262: * An empty method which should be overridden by subclasses which
263: * respond to mouse movement.
264: */
265: public void mouseMoved(MouseEvent e) {
266: }
267:
268: /**
269: * An empty method which should be overridden by subclasses which
270: * respond to mouse dragging.
271: */
272: public void mouseDragged(MouseEvent e) {
273: }
274:
275: /**
276: * An empty method which should be overridden by subclasses which
277: * respond to mouse entrances.
278: */
279: public void mouseEntered(MouseEvent e) {
280: }
281:
282: /**
283: * An empty method which should be overridden by subclasses which
284: * respond to mouse exits.
285: */
286: public void mouseExited(MouseEvent e) {
287: }
288:
289: /**
290: * An empty method which should be overridden by subclasses which
291: * respond to mouse clicks.
292: */
293: public void mouseClicked(MouseEvent e) {
294: }
295: }
|