]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/gui/PhotoThumbnail.java
Version 19, May 2018
[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 javax.swing.ImageIcon;
8 import javax.swing.JPanel;
9 import javax.swing.SwingUtilities;
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 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") + " ...";
26
27
28         /**
29          * Constructor
30          */
31         public PhotoThumbnail()
32         {
33                 this(true);
34         }
35
36         /**
37          * Constructor
38          * @param inPanel true if thumbnail is inside panel
39          */
40         public PhotoThumbnail(boolean inPanel)
41         {
42                 setOpaque(true);
43                 _inPanel = inPanel;
44         }
45
46         /**
47          * Set the Photo
48          * @param inPhoto Photo object to show thumbnail for
49          */
50         public void setPhoto(Photo inPhoto)
51         {
52                 // Check whether the photo has changed
53                 if (_photo != inPhoto)
54                 {
55                         _photo = inPhoto;
56                         _thumbnail = null;
57                         _loadFailed = false;
58                 }
59                 repaint();
60         }
61
62         /**
63          * Force a refresh / reload
64          */
65         public void refresh()
66         {
67                 _thumbnail = null;
68                 _loadFailed = false;
69         }
70
71         /**
72          * Override paint method
73          * @see javax.swing.JComponent#paint(java.awt.Graphics)
74          */
75         public void paint(Graphics inG)
76         {
77                 super.paint(inG);
78                 if (_photo != null)
79                 {
80                         // read thumbnail in separate thread
81                         if (_thumbnail == null && !_loadingImage && !_loadFailed)
82                         {
83                                 _loadingImage = true;
84                                 new Thread(this).start();
85                         }
86                         // if loading, display message
87                         if (_loadingImage)
88                         {
89                                 inG.setColor(Color.BLACK);
90                                 inG.drawString(LOADING_STRING, 10, 30);
91                         }
92                         else if (_thumbnail != null && !_loadFailed)
93                         {
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))
106                                 {
107                                         Dimension newsize = new Dimension(usableWidth, usableWidth);
108                                         setPreferredSize(newsize);
109                                         setSize(newsize);
110                                         invalidate();
111                                         // Schedule a relayout because the size has changed
112                                         SwingUtilities.invokeLater(new Runnable() {
113                                                 public void run() {
114                                                         try {Thread.sleep(200);} catch (InterruptedException e) {}
115                                                         getParent().getParent().getParent().validate();
116                                                 }
117                                         });
118                                 }
119                         }
120                 }
121         }
122
123
124         /**
125          * Run method, for loading image in separate thread
126          * @see java.lang.Runnable#run()
127          */
128         public void run()
129         {
130                 if (_inPanel)
131                 {
132                         _thumbnail = null;
133                         // try to use exif thumbnail
134                         if (_photo.getExifThumbnail() != null) {
135                                 // Use exif thumbnail
136                                 Image image = new ImageIcon(_photo.getExifThumbnail()).getImage();
137                                 _thumbnail = ImageUtils.createScaledImage(image, image.getWidth(null), image.getHeight(null));
138                                 image = null;
139                         }
140                         // Maybe there's no thumbnail, maybe the load of the thumbnail failed
141                         if (_thumbnail == null)
142                         {
143                                 // no exif thumbnail available, going to have to read whole thing
144                                 int picWidth = _photo.getWidth();
145                                 int picHeight = _photo.getHeight();
146                                 if (picWidth > -1 && picHeight > -1)
147                                 {
148                                         // Just set a "reasonable" thumbnail size for now
149                                         final int DEFAULT_THUMB_SIZE = 400;
150                                         // calculate maximum thumbnail size
151                                         Dimension thumbSize = ImageUtils.getThumbnailSize(picWidth, picHeight, DEFAULT_THUMB_SIZE, DEFAULT_THUMB_SIZE);
152                                         // Make icon to load image into
153                                         Image image = _photo.createImageIcon().getImage();
154                                         // save scaled, smoothed thumbnail for reuse
155                                         _thumbnail = ImageUtils.createScaledImage(image, thumbSize.width, thumbSize.height);
156                                         image = null;
157                                 }
158                                 else _loadFailed = true;
159                         }
160                 }
161                 else {
162                         _thumbnail = _photo.createImageIcon().getImage();
163                 }
164                 _loadingImage = false;
165                 repaint();
166         }
167 }