package class9_3_VirtualProxy_inClass_start; import javax.imageio.ImageIO; import javax.swing.*; import java.awt.*; import java.io.File; import java.io.IOException; import java.net.URL; // This class implements a virtual proxy, which temporarily substitutes // a "cheap" resource in place of one that takes longer to create public class ImageProxy implements Icon { // TODO: Coding private Icon realImage; // private Image tempImage; // the cheap resource private final int realImageWidth = 13500; private final int realImageHeight = 6750; private URL imageURL; // the location of the real resource private boolean isRetrieving = false; // indicates whether the thread is getting the real resource private JFrame parent; private Thread thread; // thread to load the image on // constructor // @throws IOException if an error occurs public ImageProxy(URL url, JFrame parent) throws IOException { this.imageURL = url; this.parent = parent; // TODO: Stuff // tempImage = ImageIO.read(getClass().getResource("dnb_land_ocean_ice.2012.13500x6750.small.jpg"));// load the temporary resource } @Override // required accessor public int getIconHeight() { // TODO: Note that we can make the image change size if desired. // int height = tempImage.getHeight(null); // if(realImage!=null) { // height = realImage.getIconHeight(); // } return realImageHeight; } @Override // required accessor public int getIconWidth() { // int width = tempImage.getWidth(null); // if(realImage!=null) { // width = realImage.getIconWidth(); // } return realImageWidth; } @Override // Called by the Swing framework whenever this icon needs to paint itself public void paintIcon(final Component c, Graphics g, int x, int y) { if(realImage!=null) { // we already have the real image loaded realImage.paintIcon(c, g, x, y); } else { // the real image has not been loaded yet // display the temporary image for now... // g.drawImage(tempImage, 0, 0, realImageWidth, realImageHeight, null); g.setColor(Color.BLACK); g.setFont(Font.decode("Arial 30")); g.drawString("Loading image, please wait...", x+50, y+50); System.out.println("DEBUG: Loading image...."); //...and load the real image // TODO: How to not load the image every time we call this? System.out.println("Debug: starting to load remote image"); Thread thread = new Thread(()-> { // the following may take some time to execute // if the imageURL is on a slow remote server realImage = new ImageIcon(imageURL); // try { // Thread.sleep(4000); // sleep a little longer for good measure. // } catch (InterruptedException e) { // System.out.println("Our sleep was cut short."); // } System.out.println("Done loading icon."); // TODO: Why doesn't it paint? SwingUtilities.invokeLater( new Runnable(){ public void run() { realImage.paintIcon(c, g, x, y); parent.repaint(); } }); }); thread.start(); } } } //private ImageIcon image; //private URL imageURL; //private Thread retrievalThread; //private boolean retrieving = false; // //public ImageProxy(URL url) { // imageURL = url; //} // //@Override //public int getIconHeight() { // int height = ImageComponent.MAX_HEIGHT; // if(image!=null) { // height = image.getIconHeight(); // } // return height; //} // //@Override //public int getIconWidth() { // int width = ImageComponent.MAX_WIDTH; // if(image!=null) { // width = image.getIconWidth(); // } // return width; //} // //@Override //public void paintIcon(final Component component, Graphics graphics, int x, int y) { // if(image!=null) { // image.paintIcon(component, graphics, x, y); // } else { // graphics.drawString("Loading image, please wait...", x+50, y+100); // if(!retrieving) { // retrieving = true; // retrievalThread = new Thread(new Runnable() { // public void run() { // try { // Thread.sleep(200); // image = new ImageIcon(imageURL, "Image"); // component.repaint(); // } catch(Exception e) { // e.printStackTrace(); // } // } // }); // retrievalThread.start(); // } // } //}