4 import java.awt.Dimension;
5 import java.awt.Graphics;
7 import javax.swing.ImageIcon;
8 import javax.swing.JPanel;
9 import javax.swing.SwingUtilities;
11 import tim.prune.I18nManager;
12 import tim.prune.data.Photo;
15 * GUI component for showing photo thumbnail
17 public class PhotoThumbnail extends JPanel implements Runnable
19 private Photo _photo = null;
20 private Image _thumbnail = null;
21 private boolean _loadingImage = false;
22 private boolean _loadFailed = false;
23 private boolean _inPanel = false;
24 /** String to show before photo is loaded */
25 private static final String LOADING_STRING = I18nManager.getText("details.photo.loading") + " ...";
31 public PhotoThumbnail()
38 * @param inPanel true if thumbnail is inside panel
40 public PhotoThumbnail(boolean inPanel)
48 * @param inPhoto Photo object to show thumbnail for
50 public void setPhoto(Photo inPhoto)
52 // Check whether the photo has changed
53 if (_photo != inPhoto)
63 * Force a refresh / reload
72 * Override paint method
73 * @see javax.swing.JComponent#paint(java.awt.Graphics)
75 public void paint(Graphics inG)
80 // read thumbnail in separate thread
81 if (_thumbnail == null && !_loadingImage && !_loadFailed)
84 new Thread(this).start();
86 // if loading, display message
89 inG.setColor(Color.BLACK);
90 inG.drawString(LOADING_STRING, 10, 30);
92 else if (_thumbnail != null && !_loadFailed)
94 // Copy scaled, smoothed (and rotated) image into scaled
95 int usableWidth = getParent().getWidth()-10;
96 int usableHeight = (_inPanel?usableWidth:getHeight()-10);
97 Image scaled = ImageUtils.rotateImage(_thumbnail, usableWidth, usableHeight, _photo.getRotationDegrees());
98 int scaleWidth = scaled.getWidth(null);
99 int scaleHeight = scaled.getHeight(null);
100 // Draw scaled / rotated image to component
101 int horizOffset = (getWidth() - scaleWidth) / 2;
102 int vertOffset = (getHeight() - scaleHeight) / 2;
103 inG.drawImage(scaled, horizOffset, vertOffset, scaleWidth, scaleHeight, null);
104 // Special resize behaviour when locked inside details panel
105 if (_inPanel && (getHeight() < getWidth() || getHeight() > usableWidth))
107 Dimension newsize = new Dimension(usableWidth, usableWidth);
108 setPreferredSize(newsize);
111 // Schedule a relayout because the size has changed
112 SwingUtilities.invokeLater(new Runnable() {
114 try {Thread.sleep(200);} catch (InterruptedException e) {}
115 getParent().getParent().getParent().validate();
125 * Run method, for loading image in separate thread
126 * @see java.lang.Runnable#run()
132 // use either exif thumbnail or photo scaled down to sensible size
133 if (_photo.getExifThumbnail() != null) {
134 // Use exif thumbnail
135 Image image = new ImageIcon(_photo.getExifThumbnail()).getImage();
136 _thumbnail = ImageUtils.createScaledImage(image, image.getWidth(null), image.getHeight(null));
141 // no exif thumbnail available, going to have to read whole thing
142 int picWidth = _photo.getWidth();
143 int picHeight = _photo.getHeight();
144 if (picWidth > -1 && picHeight > -1)
146 // Just set a "reasonable" thumbnail size for now
147 final int DEFAULT_THUMB_SIZE = 400;
148 // calculate maximum thumbnail size
149 Dimension thumbSize = ImageUtils.getThumbnailSize(picWidth, picHeight, DEFAULT_THUMB_SIZE, DEFAULT_THUMB_SIZE);
150 // Make icon to load image into
151 Image image = _photo.createImageIcon().getImage();
152 // save scaled, smoothed thumbnail for reuse
153 _thumbnail = ImageUtils.createScaledImage(image, thumbSize.width, thumbSize.height);
156 else _loadFailed = true;
160 _thumbnail = _photo.createImageIcon().getImage();
162 _loadingImage = false;