KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > j > ImageBuffer


1 /*
2  * ImageBuffer.java
3  *
4  * Copyright (C) 2000-2002 Peter Graves
5  * $Id: ImageBuffer.java,v 1.2 2002/10/11 01:42:37 piso Exp $
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */

21
22 package org.armedbear.j;
23
24 import java.awt.Color JavaDoc;
25 import java.awt.Cursor JavaDoc;
26 import java.awt.Image JavaDoc;
27 import java.awt.MediaTracker JavaDoc;
28
29 public class ImageBuffer extends Buffer implements Constants
30 {
31     private static Color JavaDoc backgrounds[];
32
33     static {
34         backgrounds = new Color JavaDoc[3];
35         backgrounds[0] = new Color JavaDoc(153, 153, 153);
36         backgrounds[1] = Color.black;
37         backgrounds[2] = Color.white;
38     }
39
40     private int backgroundIndex;
41     private Image JavaDoc currentImage;
42     private Image JavaDoc originalImage;
43     private int originalWidth;
44     private int originalHeight;
45     private int currentWidth;
46     private int currentHeight;
47     private ImageLoader loader;
48
49     private ImageBuffer(File file, File cache, String JavaDoc listing)
50     {
51         super();
52         mode = Editor.getModeList().getMode(IMAGE_MODE);
53         setFile(file);
54         supportsUndo = false;
55         readOnly = true;
56         autosaveEnabled = false;
57         type = TYPE_IMAGE;
58         setCache(cache);
59         setListing(listing);
60         setInitialized(true);
61     }
62
63     public static ImageBuffer createImageBuffer(File file, File cache, String JavaDoc listing)
64     {
65         // Load the image before creating the buffer, so we don't have to
66
// unlink the buffer if we can't load the image.
67
File toBeLoaded = cache != null ? cache : file;
68         ImageLoader loader = new ImageLoader(toBeLoaded);
69         Image JavaDoc img = loader.loadImage();
70         if (img != null) {
71             // The image was loaded successfully. Now create the buffer.
72
ImageBuffer ib = new ImageBuffer(file, cache, listing);
73             ib.loader = loader;
74             ib.currentImage = ib.originalImage = img;
75             ib.currentWidth = ib.originalWidth = img.getWidth(null);
76             ib.currentHeight = ib.originalHeight = img.getHeight(null);
77             ib.setLastModified(toBeLoaded.lastModified());
78             ib.setLoaded(true);
79             return ib;
80         } else
81             return null;
82     }
83
84     public final Position getInitialDotPos()
85     {
86         return null;
87     }
88
89     public final boolean needsParsing()
90     {
91         return false;
92     }
93
94     public final Image JavaDoc getImage()
95     {
96         return currentImage;
97     }
98
99     public final int getDisplayHeight()
100     {
101         if (getModeId() == IMAGE_MODE)
102             return currentImage.getHeight(null) + Display.getImageBorderHeight() * 2;
103         else
104             return super.getDisplayHeight();
105     }
106
107     public final int getDisplayWidth()
108     {
109         if (getModeId() == IMAGE_MODE)
110             return currentImage.getWidth(null) + Display.getImageBorderWidth() * 2;
111         else
112             return super.getDisplayWidth();
113     }
114
115     public int load()
116     {
117         if (!isLoaded()) {
118             Debug.assertTrue(loader == null);
119             final File toBeLoaded = getCache() != null ? getCache() : getFile();
120             loader = new ImageLoader(toBeLoaded);
121             Image JavaDoc img = loader.loadImage();
122             if (img != null) {
123                 currentImage = originalImage = img;
124                 currentWidth = originalWidth = img.getWidth(null);
125                 currentHeight = originalHeight = img.getHeight(null);
126             } else
127                 MessageDialog.showMessageDialog("Error loading image", "Error");
128             setLastModified(toBeLoaded.lastModified());
129             setLoaded(true);
130         }
131         return LOAD_COMPLETED;
132     }
133
134     public void reload()
135     {
136         switch (getModeId()) {
137             case BINARY_MODE:
138                 if (loader != null) {
139                     loader.dispose();
140                     loader = null;
141                 }
142                 currentImage = null;
143                 originalImage = null;
144                 super.reload();
145                 return;
146             case IMAGE_MODE:
147                 if (getFile().isLocal())
148                     reloadLocal();
149                 else
150                     reloadRemote();
151                 return;
152             default:
153                 Debug.bug();
154         }
155     }
156
157     private void reloadLocal()
158     {
159         empty();
160         if (loader != null) {
161             loader.dispose();
162             loader = null;
163         }
164         currentImage = null;
165         originalImage = null;
166         load();
167         for (EditorIterator it = new EditorIterator(); it.hasNext();) {
168             Editor ed = it.nextEditor();
169             if (ed.getBuffer() == ImageBuffer.this) {
170                 ed.getDisplay().repaint();
171                 ed.updateDisplay();
172             }
173         }
174     }
175
176     private void reloadRemote()
177     {
178         final File file = getFile();
179         LoadProcess p = null;
180         if (file instanceof FtpFile) {
181             FtpSession session = FtpSession.getSession((FtpFile)file);
182             p = new FtpLoadProcess(this, (FtpFile)file, session);
183         } else if (file instanceof HttpFile) {
184             p = new HttpLoadProcess(this, (HttpFile)file);
185         } else {
186             Debug.bug();
187             return;
188         }
189         final LoadProcess loadProcess = p;
190         Runnable JavaDoc successRunnable = new Runnable JavaDoc() {
191             public void run()
192             {
193                 final File cache = getCache();
194                 if (cache != null && cache.isFile())
195                     cache.delete();
196                 setCache(loadProcess.getCache());
197                 reloadLocal();
198                 setBusy(false);
199             }
200         };
201         ErrorRunnable errorRunnable = new ErrorRunnable("Reload failed");
202         loadProcess.setProgressNotifier(new StatusBarProgressNotifier(this));
203         loadProcess.setSuccessRunnable(successRunnable);
204         loadProcess.setErrorRunnable(errorRunnable);
205         loadProcess.start();
206     }
207
208     public final Color JavaDoc getBackgroundColor()
209     {
210         return getBackground(backgroundIndex);
211     }
212
213     public static final Color JavaDoc getDefaultBackgroundColor()
214     {
215         return getBackground(0);
216     }
217
218     public final int getImageWidth()
219     {
220         return originalWidth;
221     }
222
223     public final int getImageHeight()
224     {
225         return originalHeight;
226     }
227
228     public final void cycleBackground()
229     {
230         if (++backgroundIndex >= getBackgroundCount())
231             backgroundIndex = 0;
232     }
233
234     private static final int getBackgroundCount()
235     {
236         return backgrounds.length;
237     }
238
239     private static Color JavaDoc getBackground(int index)
240     {
241         if (index >= 0 && index < backgrounds.length)
242             return backgrounds[index];
243         else
244             return backgrounds[0];
245     }
246
247     public void zoomIn()
248     {
249         int w = currentWidth * 2;
250         int h = currentHeight * 2;
251         if (w > 0 && h > 0)
252             resize(w, h);
253     }
254
255     public void zoomOut()
256     {
257         int w = currentWidth / 2;
258         int h = currentHeight / 2;
259         if (w > 0 && h > 0)
260             resize(w, h);
261     }
262
263     public void fit()
264     {
265         if (originalWidth == 0 || originalHeight == 0)
266             return;
267         Editor editor = Editor.currentEditor();
268         Display display = editor.getDisplay();
269         int displayWidth = display.getWidth() - Display.getImageBorderWidth() * 2;
270         int displayHeight = display.getHeight() - Display.getImageBorderHeight() * 2;
271         float factor = (float) displayWidth / (float) originalWidth;
272         if (factor * originalHeight > displayHeight)
273             factor = (float) displayHeight / (float) originalHeight;
274         int w = (int) (originalWidth * factor);
275         int h = (int) (originalHeight * factor);
276         resize(w, h);
277     }
278
279     public void restore()
280     {
281         resize(originalWidth, originalHeight);
282     }
283
284     private void resize(int w, int h)
285     {
286         Editor editor = Editor.currentEditor();
287         editor.setWaitCursor();
288         Image JavaDoc img = null;
289         MediaTracker JavaDoc mt = null;
290
291         try
292         {
293             long pixels = w * h;
294             if (pixels > originalWidth * originalHeight && pixels > 2592000) {
295                 // 1800x1440 (an arbitrary limit)
296
editor.status("Too many pixels!");
297                 return;
298             }
299             long bytesRequired = pixels * 4; // 4 bytes (32 bits) per pixel
300
Runtime JavaDoc runtime = Runtime.getRuntime();
301             long bytesFree = runtime.freeMemory();
302             if (bytesRequired > bytesFree) {
303                 runtime.gc();
304                 bytesFree = runtime.freeMemory();
305                 if (bytesRequired > bytesFree) {
306                     editor.status("Not enough memory");
307                     return;
308                 }
309             }
310             img = originalImage.getScaledInstance(w, h, Image.SCALE_DEFAULT);
311             mt = new MediaTracker JavaDoc(editor);
312             mt.addImage(img , 0);
313             mt.waitForID(0);
314         }
315         catch (Exception JavaDoc e) {
316             Log.error(e);
317         }
318         finally {
319             editor.setDefaultCursor();
320         }
321
322         if (mt == null || mt.isErrorAny())
323             img = null;
324
325         if (img != null) {
326             if (currentImage != originalImage)
327                 currentImage.flush();
328             currentImage = img;
329             currentWidth = img.getWidth(null);
330             currentHeight = img.getHeight(null);
331             for (EditorIterator it = new EditorIterator(); it.hasNext();) {
332                 Editor ed = it.nextEditor();
333                 if (ed.getBuffer() == this) {
334                     ed.getDisplay().repaint();
335                     status(ed);
336                 }
337             }
338         }
339     }
340
341     public boolean reactivate()
342     {
343         final File file = getFile();
344         if (file == null || file.isRemote() || !file.isFile())
345             return false;
346         if (isLoaded() && file.lastModified() != getLastModified()) {
347             reload();
348             for (EditorIterator it = new EditorIterator(); it.hasNext();) {
349                 Editor ed = it.nextEditor();
350                 if (ed.getBuffer() == this) {
351                     ed.getDisplay().repaint();
352                     status(ed);
353                 }
354             }
355             return true;
356         }
357         return false;
358     }
359
360     private void status(Editor editor)
361     {
362         int percent =
363             (int) ((float) currentWidth * 100 / (float) originalWidth + 0.5);
364         editor.status(String.valueOf(percent) + '%');
365     }
366
367     public void dispose()
368     {
369         if (loader != null)
370             loader.dispose();
371         super.dispose();
372     }
373
374     public Cursor JavaDoc getDefaultCursor()
375     {
376         return Cursor.getDefaultCursor();
377     }
378
379     public Cursor JavaDoc getDefaultCursor(Position pos)
380     {
381         return Cursor.getDefaultCursor();
382     }
383
384     public void saveView(Editor editor)
385     {
386         // Nothing to do.
387
}
388
389     public String JavaDoc getStatusText(Editor editor)
390     {
391         FastStringBuffer sb = new FastStringBuffer(String.valueOf(getImageWidth()));
392         sb.append('x');
393         sb.append(String.valueOf(getImageHeight()));
394         sb.append(" pixels");
395         return sb.toString();
396     }
397 }
398
Popular Tags