4 import java.awt.Dimension;
5 import java.awt.Graphics;
7 import java.awt.image.BufferedImage;
8 import javax.swing.ImageIcon;
9 import javax.swing.JPanel;
10 import javax.swing.SwingUtilities;
12 import tim.prune.I18nManager;
13 import tim.prune.data.Photo;
16 * GUI component for showing photo thumbnail
18 public class PhotoThumbnail extends JPanel implements Runnable
20 private Photo _photo = null;
21 private BufferedImage _thumbnail = null;
22 private boolean _loadingImage = false;
23 private boolean _loadFailed = false;
24 /** String to show before photo is loaded */
25 private static final String LOADING_STRING = I18nManager.getText("details.photo.loading") + " ...";
31 public PhotoThumbnail()
39 * @param inPhoto Photo object to show thumbnail for
41 public void setPhoto(Photo inPhoto)
43 // Check whether the photo has changed
44 if (_photo != inPhoto) {
53 * Force a refresh / reload
55 public void refresh() {
61 * Override paint method
62 * @see javax.swing.JComponent#paint(java.awt.Graphics)
64 public void paint(Graphics inG)
69 // read thumbnail in separate thread
70 if (_thumbnail == null && !_loadingImage && !_loadFailed)
73 new Thread(this).start();
75 // if loading, display message
78 inG.setColor(Color.BLACK);
79 inG.drawString(LOADING_STRING, 10, 30);
81 else if (_thumbnail != null && !_loadFailed)
83 // Copy scaled, smoothed (and rotated) image into scaled
84 int usableWidth = getParent().getWidth()-10;
85 Image scaled = ImageUtils.rotateImage(_thumbnail, usableWidth, usableWidth, _photo.getRotationDegrees());
86 int scaleWidth = scaled.getWidth(null);
87 int scaleHeight = scaled.getHeight(null);
88 // Draw scaled / rotated image to component
89 int horizOffset = (getWidth() - scaleWidth) / 2;
90 int vertOffset = (getHeight() - scaleHeight) / 2;
91 inG.drawImage(scaled, horizOffset, vertOffset, scaleWidth, scaleHeight, null);
92 if (getHeight() < getWidth() || getHeight() > usableWidth)
94 Dimension newsize = new Dimension(usableWidth, usableWidth);
95 setPreferredSize(newsize);
98 // Schedule a relayout because the size has changed
99 SwingUtilities.invokeLater(new Runnable() {
101 try {Thread.sleep(200);} catch (InterruptedException e) {}
102 getParent().getParent().getParent().validate();
112 * Run method, for loading image in separate thread
113 * @see java.lang.Runnable#run()
117 // Use exif thumbnail?
118 if (_photo.getExifThumbnail() != null) {
119 Image image = new ImageIcon(_photo.getExifThumbnail()).getImage();
120 _thumbnail = ImageUtils.createScaledImage(image, image.getWidth(null), image.getHeight(null));
125 // no exif thumbnail available, going to have to read whole thing
126 int picWidth = _photo.getWidth();
127 int picHeight = _photo.getHeight();
128 if (picWidth > -1 && picHeight > -1)
130 // Just set a "reasonable" thumbnail size for now
131 final int DEFAULT_THUMB_SIZE = 400;
132 // calculate maximum thumbnail size
133 Dimension thumbSize = ImageUtils.getThumbnailSize(picWidth, picHeight, DEFAULT_THUMB_SIZE, DEFAULT_THUMB_SIZE);
134 // Make icon to load image into
135 Image image = new ImageIcon(_photo.getFile().getAbsolutePath()).getImage();
136 // save scaled, smoothed thumbnail for reuse
137 _thumbnail = ImageUtils.createScaledImage(image, thumbSize.width, thumbSize.height);
140 else _loadFailed = true;
142 _loadingImage = false;