package kiyut.ekspos; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Insets; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.imageio.ImageReader; import javax.imageio.event.IIOReadProgressListener; import javax.imageio.event.IIOReadUpdateListener; import javax.imageio.event.IIOReadWarningListener; import javax.imageio.stream.ImageInputStream; import javax.swing.JPanel; import javax.swing.SwingUtilities; import kiyut.ekspos.prefs.IIOPreferences; import kiyut.swing.shell.image.ImageUtilities; import kiyut.swing.shell.util.ShellUtilities; /** ImagePane * * @author tonny */ public class ImagePane extends JPanel implements IIOReadUpdateListener, IIOReadProgressListener { /** an image for this component */ protected BufferedImage image; /** the scale with for this component. */ protected double scaleWidth = 1.0; /** the scaleHeight for this component. */ protected double scaleHeight = 1.0; protected Dimension imageSize; protected ImageReader imageReader; protected Thread loadThread; //protected EventListenerList listenerList; protected double percentComplete; protected double repaintProgress = 25; /** Creates a new instance of ImagePane */ public ImagePane() { //listenerList = new EventListenerList(); } /** Overriden to display or render the {@code Image} * {@inheritDoc} * @param g {@inheritDoc} */ @Override public void paintComponent(Graphics g) { super.paintComponent(g); // paint background if (image == null) { return; } Graphics2D g2 = (Graphics2D) g; Insets insets = getInsets(); double areaWidth = getWidth() - insets.left - insets.right; double areaHeight = getHeight() - insets.top - insets.bottom; double x = insets.left; double y = insets.top; double w = image.getWidth() * scaleWidth; double h = image.getHeight() * scaleHeight; double tmpX = (areaWidth - w)/2; double tmpY = (areaHeight - h)/2; if (tmpX > x) { x = tmpX; } if (tmpY > y) { y =tmpY; } //System.err.println("x:" + x + " y:" + y); g2.drawImage(image,(int)x,(int)y,(int)w,(int)h,this); } /** set the image for this component to display * if the value of image is null or empty string, nothing is displayed. * @param image the image to display */ public void setImage(BufferedImage image) { this.image = image; if (image != null) { imageSize.width = image.getWidth(); imageSize.height = image.getHeight(); } } /** Return Image * @return Image */ public BufferedImage getImage() { return this.image; } /** set the image rescale * @param scaleWidth the scaleWidth for the image. * @param scaleHeight the scaleHeight for the image. */ public void setImageRescale(double scaleWidth, double scaleHeight) { this.scaleWidth = scaleWidth; this.scaleHeight = scaleHeight; } /** Set the repaint progress increment value between 0 to 100. *The default value is 25 *@param increment The repaint progress increment *@see #getProgressRepaint */ public void setProgressRepaint(double increment) { if (increment < 0 || increment > 100) { throw new IllegalArgumentException("value must be between 0 - 100"); } this.repaintProgress = increment; } /** Return the repaint progress increment * @return repaint progress increment * @see #setProgressRepaint(double) */ public double getProgessRepaint() { return this.repaintProgress; } /** *@see javax.imageio.ImageReader#addIIOReadProgressListener(IIOReadProgressListener) */ public void addIIOReadProgressListener(IIOReadProgressListener listener) { listenerList.add(IIOReadProgressListener.class, listener); } /** *@see javax.imageio.ImageReader#removeIIOReadProgressListener(IIOReadProgressListener) */ public void removeIIOReadProgressListener(IIOReadProgressListener listener) { listenerList.remove(IIOReadProgressListener.class, listener); } /** *@see javax.imageio.ImageReader#addIIOReadUpdateListener(IIOReadUpdateListener) */ public void addIIOReadUpdateListener(IIOReadUpdateListener listener) { listenerList.add(IIOReadUpdateListener.class, listener); } /** *@see javax.imageio.ImageReader#removeIIOReadUpdateListener(IIOReadUpdateListener) */ public void removeIIOReadUpdateListener(IIOReadUpdateListener listener) { listenerList.remove(IIOReadUpdateListener.class, listener); } /** *@see javax.imageio.ImageReader#addIIOReadWarningListener(IIOReadWarningListener) */ public void addIIOReadWarningListener(IIOReadWarningListener listener) { listenerList.add(IIOReadWarningListener.class, listener); } /** *@see javax.imageio.ImageReader#removeIIOReadWarningListener(IIOReadWarningListener) */ public void removeIIOReadWarningListener(IIOReadWarningListener listener) { listenerList.remove(IIOReadWarningListener.class, listener); } /** Display the File Image * @param file <code>File</code> */ public void view(File file) { if ( (file==null) || (!ImageUtilities.isFileImage(file)) ) { setImage(null); repaint(); return; } startFileImageLoading(file); } private void startFileImageLoading(File file) { if (imageReader != null) { imageReader.abort(); } if (loadThread != null) { while (loadThread.isAlive()) { try { //Thread.currentThread().wait(); loadThread.join(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } try { image = null; imageReader = getImageReader(file); Dimension imageDim = new Dimension(imageReader.getWidth(0), imageReader.getHeight(0)); imageSize = imageDim; Rectangle rect = SwingUtilities.calculateInnerArea(this,null); Dimension size = new Dimension(rect.width,rect.height); double scale = ImageUtilities.scaleToFit(imageDim,size); scaleWidth = scale; scaleHeight = scale; } catch (IOException e) {} Runnable r = new Runnable() { public void run() { readImage(); if (imageReader != null) { imageReader.dispose(); } } }; loadThread = new Thread(r); loadThread.start(); } private void readImage() { try { imageReader.addIIOReadUpdateListener(this); imageReader.addIIOReadProgressListener(this); Object[] listeners = listenerList.getListenerList(); for (int i = listeners.length-2; i>=0; i-=2) { if (listeners[i]==IIOReadUpdateListener.class) { imageReader.addIIOReadUpdateListener((IIOReadUpdateListener)listeners[i+1]); } else if (listeners[i]==IIOReadProgressListener.class) { imageReader.addIIOReadProgressListener((IIOReadProgressListener)listeners[i+1]); } else if (listeners[i]==IIOReadWarningListener.class) { imageReader.addIIOReadWarningListener((IIOReadWarningListener)listeners[i+1]); } } image = imageReader.read(0); } catch (IOException ex) { ex.printStackTrace(); } finally { if (imageReader.getInput() instanceof ImageInputStream) { try { ((ImageInputStream)imageReader.getInput()).close(); } catch (Exception e) {} } imageReader.removeIIOReadUpdateListener(this); imageReader.removeIIOReadProgressListener(this); Object[] listeners = listenerList.getListenerList(); for (int i = listeners.length-2; i>=0; i-=2) { if (listeners[i]==IIOReadUpdateListener.class) { imageReader.removeIIOReadUpdateListener((IIOReadUpdateListener)listeners[i+1]); } else if (listeners[i]==IIOReadProgressListener.class) { imageReader.removeIIOReadProgressListener((IIOReadProgressListener)listeners[i+1]); } else if (listeners[i]==IIOReadWarningListener.class) { imageReader.removeIIOReadWarningListener((IIOReadWarningListener)listeners[i+1]); } } imageReader.dispose(); imageReader = null; } } /** return the <code>ImageReader</code> use to read the specified <code>file</code> * @return the <code>ImageReader</code> or null if no suitable reader * @throws IOException If an I/O error occurs */ private ImageReader getImageReader(File file) throws IOException { // find suitable reader String suffix = ShellUtilities.getFileSuffix(file); IIOPreferences iioPrefs = IIOPreferences.getInstance(); ImageReader reader = iioPrefs.getImageReaderWriterPreferences().getPreferredImageReaderBySuffix(suffix); if (reader == null) { return null; } ImageInputStream iis = ImageIO.createImageInputStream(file); reader.setInput(iis,true); return reader; } /** {@inheritDoc} */ public void imageComplete(ImageReader source) { percentComplete = 100; repaint(); } /** {@inheritDoc} */ public void imageProgress(ImageReader source, float percentageDone) { if (((percentageDone - percentComplete) >= repaintProgress) ) { //paintImmediately(0,0,getWidth(),getHeight()); repaint(); percentComplete = percentageDone; } } /** {@inheritDoc} */ public void imageStarted(ImageReader source, int imageIndex) { percentComplete = 0; } /** {@inheritDoc} */ public void imageUpdate(ImageReader source, BufferedImage theImage, int minX, int minY, int width, int height, int periodX, int periodY, int[] bands) { //repaint(); } /** {@inheritDoc} */ public void passComplete(ImageReader source, BufferedImage theImage) { } /** {@inheritDoc} */ public void passStarted(ImageReader source, BufferedImage theImage, int pass, int minPass, int maxPass, int minX, int minY, int periodX, int periodY, int[] bands) { if (pass == 0) { this.image = theImage; repaint(); } } /** {@inheritDoc} */ public void readAborted(ImageReader source) { } /** {@inheritDoc} */ public void sequenceComplete(ImageReader source) { } /** {@inheritDoc} */ public void sequenceStarted(ImageReader source, int minIndex) { } /** {@inheritDoc} */ public void thumbnailComplete(ImageReader source) { } /** {@inheritDoc} */ public void thumbnailPassComplete(ImageReader source, BufferedImage theThumbnail) { } /** {@inheritDoc} */ public void thumbnailPassStarted(ImageReader source, BufferedImage theThumbnail, int pass, int minPass, int maxPass, int minX, int minY, int periodX, int periodY, int[] bands) { } /** {@inheritDoc} */ public void thumbnailProgress(ImageReader source, float percentageDone) { } /** {@inheritDoc} */ public void thumbnailStarted(ImageReader source, int imageIndex, int thumbnailIndex) { } /** {@inheritDoc} */ public void thumbnailUpdate(ImageReader source, BufferedImage theThumbnail, int minX, int minY, int width, int height, int periodX, int periodY, int[] bands) { } }