-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathImageProxy.java
More file actions
81 lines (71 loc) · 3.45 KB
/
ImageProxy.java
File metadata and controls
81 lines (71 loc) · 3.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package ProxyPattern.VirtualProxyPattern.ImageProxy;
import java.net.URL;
import javax.swing.ImageIcon;
import java.awt.Component;
import java.awt.Graphics;
public class ImageProxy implements Icon {
// Reference to the real image object
volatile ImageIcon imageIcon;
final URL imageURL;
Thread retreivalThread;
boolean retrieving = false;
public ImageProxy(URL url){
imageURL = url;
}
public int getIconWidth(){
if(imageIcon != null){
return imageIcon.getIconWidth();}
else{
return 800;
}
}
public int getIconHeight(){
if(imageIcon != null){
return imageIcon.getIconHeight();
}else{
return 600;
}
}
// ImageIcon is used by two different threads so along with making the variable to volatile,
// we also need to synchronize the method that sets the imageIcon variable to ensure thread safety.
synchronized void setImageIcon(ImageIcon imageIcon){
this.imageIcon = imageIcon;
}
// Only one thread calls paintIcon() at a time, so we don't need to synchronize this method.
public void paintIcon(final Component c, Graphics g, int x, int y){
if(imageIcon != null){
System.out.println("Painting actual image: " + imageIcon.getIconWidth() + "x" + imageIcon.getIconHeight());
imageIcon.paintIcon(c, g, x, y);
}else{
System.out.println("Painting loading message at position: " + x + ", " + y);
g.drawString("Loading CD cover, please wait...", x+300, y+190);
if (!retrieving) {
retrieving = true;
System.out.println("Starting image retrieval from: " + imageURL);
// Creates another thread so we don't hang the user interface while the image is being loaded.
// The thread will load the image and then call repaint() on the component to update the display.
retreivalThread = new Thread(new Runnable() {
public void run() {
try {
// Adding a manual delay to demonstrate the loading state
// This gives users time to see the "Loading CD cover, please wait..." message
System.out.println("Waiting 3 seconds before loading image...");
Thread.sleep(3000); // 3 second delay for demonstration purposes
System.out.println("Now loading image from URL...");
setImageIcon(new ImageIcon(imageURL, "CD Cover"));
System.out.println("Image loaded! Size: " + imageIcon.getIconWidth() + "x" + imageIcon.getIconHeight());
// Tell the component to repaint itself now that the image is ready.
// The image loading IconImage is sychronous and will block the thread until the image is loaded, so we can be sure that when we call repaint() the image will be ready to be drawn.
c.repaint();
System.out.println("Repaint called!");
} catch (Exception e) {
System.out.println("Error loading image: " + e.getMessage());
e.printStackTrace();
}
}
});
retreivalThread.start();
}
}
}
}