package org.appwork.utils.swing; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.io.File; import java.net.HttpURLConnection; import java.net.URL; import javax.imageio.ImageIO; import javax.swing.ImageIcon; import javax.swing.JLabel; import org.appwork.utils.Application; import org.appwork.utils.Files; import org.appwork.utils.Hash; import org.appwork.utils.ImageProvider.ImageProvider; import org.appwork.utils.net.SimpleHTTP; public class AsynchImage extends JLabel { public static class Updater extends Thread { private final File cache; private final int x; private final int y; private final URL url; private final AsynchImage asynchImage; public final static long EXPIRETIME = 7 * 24 * 60 * 60 * 1000l; /** * @param asynchImage * @param prefX * @param prefY * @param cache * @param url */ public Updater(final AsynchImage asynchImage, final int prefX, final int prefY, final File cache, final URL url) { x = prefX; y = prefY; this.cache = cache; this.url = url; this.asynchImage = asynchImage; } /* * (non-Javadoc) * * @see java.lang.Runnable#run() */ @Override public void run() { try { synchronized (AsynchImage.LOCK) { // check again. final long age = System.currentTimeMillis() - cache.lastModified(); if (cache.exists() && age < Updater.EXPIRETIME) { // seems like another thread updated the image in the // meantime final BufferedImage image = ImageIO.read(cache); if (asynchImage != null) { asynchImage.setDirectIcon(new ImageIcon(image)); } return; } } BufferedImage image = null; synchronized (AsynchImage.LOCK2) { synchronized (AsynchImage.LOCK) { final long age = System.currentTimeMillis() - cache.lastModified(); if (cache.exists() && age < Updater.EXPIRETIME) { // seems like another thread updated the image in // the // meantime image = ImageIO.read(cache); if (asynchImage != null) { asynchImage.setDirectIcon(new ImageIcon(image)); } return; } } System.out.println("Update image " + cache); if (url == null) { System.out.println("no url given"); return; } SimpleHTTP simple = new SimpleHTTP(); HttpURLConnection ret = null; try { ret = simple.openGetConnection(url, 30 * 1000); image = ImageIO.read(ret.getInputStream()); } finally { try { ret.disconnect(); } catch (final Throwable e) { } } System.out.println("Scale image " + cache); image = ImageProvider.getScaledInstance(image, x, y, RenderingHints.VALUE_INTERPOLATION_BILINEAR, true); } synchronized (AsynchImage.LOCK) { final long age = System.currentTimeMillis() - cache.lastModified(); if (cache.exists() && age < Updater.EXPIRETIME) { // seems like another thread updated the image in // the // meantime image = ImageIO.read(cache); if (asynchImage != null) { asynchImage.setDirectIcon(new ImageIcon(image)); } return; } System.out.println("Cachewrite image " + cache + " " + x + " - " + image.getWidth()); cache.getParentFile().mkdirs(); ImageIO.write(image, Files.getExtension(cache.getName()), cache); if (asynchImage != null) { asynchImage.setDirectIcon(new ImageIcon(image)); } } } catch (final Throwable e) { e.printStackTrace(); } } } /** * */ private static final long serialVersionUID = 1L; private File cache; private final int prefX; private final int prefY; private boolean setIconAfterLoading = true; public static Object LOCK = new Object(); private static Object LOCK2 = new Object(); /** * @param i * @param j */ public AsynchImage(final int x, final int y) { prefX = x; prefY = y; } /** * @param thumbURL * @param i * @param j */ public AsynchImage(final String thumbURL, final String extension, final int x, final int y) { super(); setBorder(new ShadowBorder(2)); prefX = x; prefY = y; this.setIcon(thumbURL, extension); } /** * @return the setIconAfterLoading */ public boolean isSetIconAfterLoading() { return setIconAfterLoading; } /** * @param imageIcon */ protected void setDirectIcon(final ImageIcon imageIcon) { if (setIconAfterLoading) { new EDTRunner() { @Override protected void runInEDT() { System.out.println("Set image " + cache); AsynchImage.this.setIcon(imageIcon); AsynchImage.this.repaint(); } }; } } /** * @param thumbURL * @param extension * @param x * @param y */ public void setIcon(final String thumbURL, final String extension) { /* cacheFile for resized image */ cache = Application.getResource("tmp/asynchimage/" + Hash.getMD5(thumbURL) + "_" + prefX + "x" + prefY + "." + extension); // if cache is older than 7 days. delete boolean refresh = true; try { synchronized (AsynchImage.LOCK) { final long age = System.currentTimeMillis() - cache.lastModified(); if (cache.exists() && age < Updater.EXPIRETIME) { refresh = false; BufferedImage image; image = ImageIO.read(cache); this.setIcon(new ImageIcon(image)); if (!isSetIconAfterLoading()) { if (image.getWidth() > 32) { // System.out.println(this.cache); } } return; } else if (cache.exists()) { BufferedImage image; image = ImageIO.read(cache); this.setIcon(new ImageIcon(image)); return; } } this.setIcon(ImageProvider.getImageIcon("imageLoader", prefX, prefY)); } catch (final Throwable e) { this.setIcon(ImageProvider.getImageIcon("imageLoader", prefX, prefY)); } finally { if (refresh) { try { new Updater(this, prefX, prefY, cache, new URL(thumbURL)).start(); } catch (final Throwable e) { } } } } /** * @param setIconAfterLoading * the setIconAfterLoading to set */ public void setSetIconAfterLoading(final boolean setIconAfterLoading) { this.setIconAfterLoading = setIconAfterLoading; } }