X-Git-Url: http://gitweb.fperrin.net/?p=GpsPrune.git;a=blobdiff_plain;f=src%2Ftim%2Fprune%2Fgui%2FPhotoThumbnail.java;fp=src%2Ftim%2Fprune%2Fgui%2FPhotoThumbnail.java;h=458ee8d84d866945d92d4cf51fb2b1da83ee5cd4;hp=0000000000000000000000000000000000000000;hb=ce6f2161b8596f7018d6a76bff79bc9e571f35fd;hpb=2d8cb72e84d5cc1089ce77baf1e34ea3ea2f8465 diff --git a/src/tim/prune/gui/PhotoThumbnail.java b/src/tim/prune/gui/PhotoThumbnail.java new file mode 100644 index 0000000..458ee8d --- /dev/null +++ b/src/tim/prune/gui/PhotoThumbnail.java @@ -0,0 +1,167 @@ +package tim.prune.gui; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Image; +import javax.swing.ImageIcon; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; + +import tim.prune.I18nManager; +import tim.prune.data.Photo; + +/** + * GUI component for showing photo thumbnail + */ +public class PhotoThumbnail extends JPanel implements Runnable +{ + private Photo _photo = null; + private Image _thumbnail = null; + private boolean _loadingImage = false; + private boolean _loadFailed = false; + private boolean _inPanel = false; + /** String to show before photo is loaded */ + private static final String LOADING_STRING = I18nManager.getText("details.photo.loading") + " ..."; + + + /** + * Constructor + */ + public PhotoThumbnail() + { + this(true); + } + + /** + * Constructor + * @param inPanel true if thumbnail is inside panel + */ + public PhotoThumbnail(boolean inPanel) + { + setOpaque(true); + _inPanel = inPanel; + } + + /** + * Set the Photo + * @param inPhoto Photo object to show thumbnail for + */ + public void setPhoto(Photo inPhoto) + { + // Check whether the photo has changed + if (_photo != inPhoto) + { + _photo = inPhoto; + _thumbnail = null; + _loadFailed = false; + } + repaint(); + } + + /** + * Force a refresh / reload + */ + public void refresh() + { + _thumbnail = null; + _loadFailed = false; + } + + /** + * Override paint method + * @see javax.swing.JComponent#paint(java.awt.Graphics) + */ + public void paint(Graphics inG) + { + super.paint(inG); + if (_photo != null) + { + // read thumbnail in separate thread + if (_thumbnail == null && !_loadingImage && !_loadFailed) + { + _loadingImage = true; + new Thread(this).start(); + } + // if loading, display message + if (_loadingImage) + { + inG.setColor(Color.BLACK); + inG.drawString(LOADING_STRING, 10, 30); + } + else if (_thumbnail != null && !_loadFailed) + { + // Copy scaled, smoothed (and rotated) image into scaled + int usableWidth = getParent().getWidth()-10; + int usableHeight = (_inPanel?usableWidth:getHeight()-10); + Image scaled = ImageUtils.rotateImage(_thumbnail, usableWidth, usableHeight, _photo.getRotationDegrees()); + int scaleWidth = scaled.getWidth(null); + int scaleHeight = scaled.getHeight(null); + // Draw scaled / rotated image to component + int horizOffset = (getWidth() - scaleWidth) / 2; + int vertOffset = (getHeight() - scaleHeight) / 2; + inG.drawImage(scaled, horizOffset, vertOffset, scaleWidth, scaleHeight, null); + // Special resize behaviour when locked inside details panel + if (_inPanel && (getHeight() < getWidth() || getHeight() > usableWidth)) + { + Dimension newsize = new Dimension(usableWidth, usableWidth); + setPreferredSize(newsize); + setSize(newsize); + invalidate(); + // Schedule a relayout because the size has changed + SwingUtilities.invokeLater(new Runnable() { + public void run() { + try {Thread.sleep(200);} catch (InterruptedException e) {} + getParent().getParent().getParent().validate(); + } + }); + } + } + } + } + + + /** + * Run method, for loading image in separate thread + * @see java.lang.Runnable#run() + */ + public void run() + { + if (_inPanel) + { + _thumbnail = null; + // try to use exif thumbnail + if (_photo.getExifThumbnail() != null) { + // Use exif thumbnail + Image image = new ImageIcon(_photo.getExifThumbnail()).getImage(); + _thumbnail = ImageUtils.createScaledImage(image, image.getWidth(null), image.getHeight(null)); + image = null; + } + // Maybe there's no thumbnail, maybe the load of the thumbnail failed + if (_thumbnail == null) + { + // no exif thumbnail available, going to have to read whole thing + int picWidth = _photo.getWidth(); + int picHeight = _photo.getHeight(); + if (picWidth > -1 && picHeight > -1) + { + // Just set a "reasonable" thumbnail size for now + final int DEFAULT_THUMB_SIZE = 400; + // calculate maximum thumbnail size + Dimension thumbSize = ImageUtils.getThumbnailSize(picWidth, picHeight, DEFAULT_THUMB_SIZE, DEFAULT_THUMB_SIZE); + // Make icon to load image into + Image image = _photo.createImageIcon().getImage(); + // save scaled, smoothed thumbnail for reuse + _thumbnail = ImageUtils.createScaledImage(image, thumbSize.width, thumbSize.height); + image = null; + } + else _loadFailed = true; + } + } + else { + _thumbnail = _photo.createImageIcon().getImage(); + } + _loadingImage = false; + repaint(); + } +}