001: /*
002: * Copyright Javelin Software, All rights reserved.
003: */
004:
005: package com.javelin.swinglets;
006:
007: import java.net.*;
008: import java.awt.*;
009: import java.awt.image.*;
010:
011: import java.io.*;
012:
013: /**
014: * SImage is an AWT Image that can be created from dimensions, or
015: * a file. The written to an output stream. The image is cached
016: * as a byte array to write quickly to the output stream. If the
017: * image has changed used the flush() method to ensure that the
018: * new image is reflected in the next write().
019: *
020: * @author Robin Sharp
021: */
022:
023: public class SImage extends Image {
024: /**
025: * Create a blank image with the following dimensions.
026: * @exception IllegalArgumentException if width or height is less than 1
027: */
028: public SImage(int width, int height) {
029: image = getImage(null, width, height);
030: }
031:
032: /**
033: * Create an image with the following url suitable for painting on.<br>
034: * @param url for the image
035: * @exception IllegalArgumentException if the url does not exist
036: */
037: public SImage(String url) throws MalformedURLException {
038: this (new URL(url));
039: }
040:
041: /**
042: * Create an image with the following url suitable for painting on.<br>
043: * @param url the image URL
044: * @exception IllegalArgumentException if the url does not exist
045: */
046: public SImage(URL url) {
047: Image tempImage = getImage(url, 0, 0);
048:
049: image = getImage(null, width, height);
050:
051: getGraphics().drawImage(tempImage, 0, 0, imageObserver);
052:
053: }
054:
055: /**
056: * Determines the name of the image.
057: */
058: public String getName() {
059: if (name == null) {
060: name = "SImage" + (COUNTER++);
061: }
062: return name;
063: }
064:
065: /**
066: * Determines the width of the image.
067: */
068: public int getWidth() {
069: return getWidth(null);
070: }
071:
072: /**
073: * Determines the width of the image.
074: */
075: public int getWidth(ImageObserver observer) {
076: return width;
077: }
078:
079: /**
080: * Determines the height of the image.
081: */
082: public int getHeight() {
083: return getHeight(null);
084: }
085:
086: /**
087: * Determines the height of the image.
088: */
089: public int getHeight(ImageObserver observer) {
090: return height;
091: }
092:
093: /**
094: * Gets the object that produces the pixels for the image.
095: */
096: public ImageProducer getSource() {
097: return image.getSource();
098: }
099:
100: /**
101: * Creates a graphics context for drawing to an off-screen image.
102: */
103: public Graphics getGraphics() {
104: return image.getGraphics();
105: }
106:
107: /**
108: * Gets a property of this image by name.
109: */
110: public Object getProperty(String name, ImageObserver observer) {
111: return null;
112: }
113:
114: /**
115: * Flush the image.
116: */
117: public void flush() {
118: byteArray = null;
119: }
120:
121: /**
122: * Get the image as a byte array
123: */
124: public byte[] getBytes() {
125: if (byteArray == null) {
126: loadByteArray();
127: }
128:
129: return byteArray;
130: }
131:
132: /**
133: * Write the image as a GIF.
134: * This will handle either OutputStream's or Graphics.
135: */
136: public void paint(Object out) throws IOException {
137: if (out instanceof OutputStream) {
138: if (byteArray == null) {
139: loadByteArray();
140: }
141:
142: ((OutputStream) out).write(byteArray);
143: } else if (out instanceof Graphics) {
144: ((Graphics) out).drawImage(this , 0, 0, imageObserver);
145: }
146: }
147:
148: // OBJECT ///////////////////////////////////////////////////////////////
149:
150: /**
151: * Hashcode. Is based on the name.
152: */
153: public int hashCode() {
154: return getName().hashCode();
155: }
156:
157: /**
158: * To String returns the stream that would be painted. This is useful
159: * for JSP and debugging.
160: */
161: public String toString() {
162: loadByteArray();
163: return new String(byteArray);
164: }
165:
166: /**
167: * Equals is based on the name and class.
168: */
169: public boolean equals(Object object) {
170: if (object == null)
171: return false;
172: if (this == object)
173: return true;
174:
175: if (object instanceof SImage
176: && ((SImage) object).getName() == getName()
177: && object.getClass().equals(getClass())) {
178: return true;
179: }
180:
181: return false;
182: }
183:
184: // PRIVATE /////////////////////////////////////////////////////////
185:
186: /**
187: * Load the image from a file or create it in memory.
188: * If the url is not null then load the image from the url
189: * and set the width and height. Otherwise create an image
190: * from memory with the defined dimensions and set the
191: * width and height proprerties.
192: */
193: protected Image getImage(URL url, int w, int h)
194: throws IllegalArgumentException {
195: if (component == null) {
196: component = new Component() {
197: };
198: tracker = new MediaTracker(component);
199: Frame f = new Frame();
200: f.add(component);
201: f.pack();
202: }
203:
204: Image tempImage = null;
205:
206: if (url == null) {
207: if (w < 1 || h < 1) {
208: throw new IllegalArgumentException(
209: "Illegal image size " + w + "," + h);
210: }
211:
212: tempImage = component.createImage(w, h);
213: this .width = w;
214: this .height = h;
215: } else {
216: tempImage = Toolkit.getDefaultToolkit().getImage(url);
217: }
218:
219: tracker.addImage(tempImage, 0);
220: try {
221: tracker.waitForID(0, 10000);
222: } catch (InterruptedException e) {
223: throw new IllegalArgumentException(
224: "INTERRUPTED while loading Image "
225: + url.toExternalForm());
226: }
227:
228: loadStatus = tracker.statusID(0, false);
229: tracker.removeImage(tempImage, 0);
230:
231: if (url != null) {
232: width = tempImage.getWidth(imageObserver);
233: height = tempImage.getHeight(imageObserver);
234:
235: if (width < 1 || height < 1) {
236: throw new IllegalArgumentException("Cannot load image "
237: + url.toExternalForm());
238: }
239: }
240:
241: return tempImage;
242: }
243:
244: protected static int COUNTER = 0;
245: protected String name;
246:
247: protected int width;
248: protected int height;
249:
250: protected Image image;
251: transient int loadStatus = 0;
252: protected ImageObserver imageObserver;
253: protected static Component component;
254: protected static MediaTracker tracker;
255:
256: protected byte[] byteArray;
257:
258: protected void loadByteArray() {
259: if (byteArray != null)
260: return;
261:
262: try {
263: GIFEncoder encoder = new GIFEncoder(image);
264:
265: ByteArrayOutputStream baos = new ByteArrayOutputStream();
266: encoder.write(baos);
267: baos.close();
268:
269: byteArray = baos.toByteArray();
270: } catch (Exception e) {
271: e.printStackTrace();
272: }
273: }
274:
275: }
|