]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/gui/PhotoThumbnail.java
88e77ca58ce6795986185604435eb59e317a6b8e
[GpsPrune.git] / tim / prune / gui / PhotoThumbnail.java
1 package tim.prune.gui;
2
3 import java.awt.Color;
4 import java.awt.Dimension;
5 import java.awt.Graphics;
6 import java.awt.Image;
7 import java.awt.image.BufferedImage;
8 import javax.swing.ImageIcon;
9 import javax.swing.JPanel;
10
11 import tim.prune.I18nManager;
12 import tim.prune.data.Photo;
13
14 /**
15  * GUI component for showing photo thumbnail
16  */
17 public class PhotoThumbnail extends JPanel implements Runnable
18 {
19         private Photo _photo = null;
20         private BufferedImage _thumbnail = null;
21         private boolean _loadingImage = false;
22         private boolean _loadFailed = false;
23         /** String to show before photo is loaded */
24         private static final String LOADING_STRING = I18nManager.getText("details.photo.loading") + " ...";
25
26
27         /**
28          * Constructor
29          */
30         public PhotoThumbnail()
31         {
32                 setOpaque(true);
33         }
34
35
36         /**
37          * Set the Photo
38          * @param inPhoto Photo object to show thumbnail for
39          */
40         public void setPhoto(Photo inPhoto)
41         {
42                 // Check whether the photo has changed
43                 if (_photo != inPhoto) {
44                         _photo = inPhoto;
45                         _thumbnail = null;
46                         _loadFailed = false;
47                 }
48                 repaint();
49         }
50
51         /**
52          * Force a refresh / reload
53          */
54         public void refresh() {
55                 _thumbnail = null;
56                 _loadFailed = false;
57         }
58
59         /**
60          * Override paint method
61          * @see javax.swing.JComponent#paint(java.awt.Graphics)
62          */
63         public void paint(Graphics inG)
64         {
65                 super.paint(inG);
66                 if (_photo != null)
67                 {
68                         // read thumbnail in separate thread
69                         if (_thumbnail == null && !_loadingImage && !_loadFailed)
70                         {
71                                 _loadingImage = true;
72                                 new Thread(this).start();
73                         }
74                         // if loading, display message
75                         if (_loadingImage)
76                         {
77                                 inG.setColor(Color.BLACK);
78                                 inG.drawString(LOADING_STRING, 10, 30);
79                         }
80                         else if (_thumbnail != null && !_loadFailed)
81                         {
82                                 // Copy scaled, smoothed (and rotated) image into scaled
83                                 int usableWidth = getParent().getWidth()-10;
84                                 Image scaled = ImageUtils.rotateImage(_thumbnail, usableWidth, usableWidth, _photo.getRotationDegrees());
85                                 int scaleWidth = scaled.getWidth(null);
86                                 int scaleHeight = scaled.getHeight(null);
87                                 // Draw scaled / rotated image to component
88                                 int horizOffset = (getWidth() - scaleWidth) / 2;
89                                 int vertOffset = (getHeight() - scaleHeight) / 2;
90                                 inG.drawImage(scaled, horizOffset, vertOffset, scaleWidth, scaleHeight, null);
91                                 if (getHeight() < getWidth())
92                                 {
93                                         setPreferredSize(new Dimension(usableWidth, usableWidth));
94                                         invalidate();
95                                 }
96                         }
97                 }
98         }
99
100
101         /**
102          * Run method, for loading image in separate thread
103          * @see java.lang.Runnable#run()
104          */
105         public void run()
106         {
107                 // Use exif thumbnail?
108                 if (_photo.getExifThumbnail() != null) {
109                         Image image = new ImageIcon(_photo.getExifThumbnail()).getImage();
110                         _thumbnail = ImageUtils.createScaledImage(image, image.getWidth(null), image.getHeight(null));
111                         image = null;
112                 }
113                 else
114                 {
115                         // no exif thumbnail available, going to have to read whole thing
116                         int picWidth = _photo.getWidth();
117                         int picHeight = _photo.getHeight();
118                         if (picWidth > -1 && picHeight > -1)
119                         {
120                                 // Just set a "reasonable" thumbnail size for now
121                                 final int DEFAULT_THUMB_SIZE = 400;
122                                 // calculate maximum thumbnail size
123                                 Dimension thumbSize = ImageUtils.getThumbnailSize(picWidth, picHeight, DEFAULT_THUMB_SIZE, DEFAULT_THUMB_SIZE);
124                                 // Make icon to load image into
125                                 Image image = new ImageIcon(_photo.getFile().getAbsolutePath()).getImage();
126                                 // save scaled, smoothed thumbnail for reuse
127                                 _thumbnail = ImageUtils.createScaledImage(image, thumbSize.width, thumbSize.height);
128                                 image = null;
129                         }
130                         else _loadFailed = true;
131                 }
132                 _loadingImage = false;
133                 repaint();
134         }
135 }