001/*
002 * Copyright 2010-2015 Institut Pasteur.
003 * 
004 * This file is part of Icy.
005 * 
006 * Icy is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 * 
011 * Icy is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014 * GNU General Public License for more details.
015 * 
016 * You should have received a copy of the GNU General Public License
017 * along with Icy. If not, see <http://www.gnu.org/licenses/>.
018 */
019package icy.gui.component;
020
021import icy.image.ImageUtil;
022import icy.resource.ResourceUtil;
023
024import java.awt.Dimension;
025import java.awt.Graphics;
026import java.awt.Image;
027import java.awt.image.BufferedImage;
028
029import javax.swing.JPanel;
030
031/**
032 * @author stephane
033 */
034public class ImageComponent extends JPanel
035{
036    /**
037     * 
038     */
039    private static final long serialVersionUID = 1448746815524070306L;
040
041    private Image image;
042    private BufferedImage cachedImage;
043    protected boolean forceUpdateCache;
044
045    /**
046     * @deprecated Use {@link #ImageComponent(Image)} instead
047     */
048    @Deprecated
049    public ImageComponent(Image image, Dimension d)
050    {
051        this(image);
052    }
053
054    /**
055     * @deprecated Use {@link #ImageComponent(Image)} instead
056     */
057    @Deprecated
058    public ImageComponent(Image image, int width, int height)
059    {
060        this(image);
061    }
062
063    /**
064     * @param image
065     */
066    public ImageComponent(Image image)
067    {
068        super(true);
069
070        this.image = image;
071
072        if (image != null)
073        {
074            // be sure image data are ready
075            ImageUtil.waitImageReady(image);
076            setPreferredSize(new Dimension(image.getWidth(null), image.getHeight(null)));
077        }
078
079        forceUpdateCache = true;
080    }
081
082    public ImageComponent()
083    {
084        this(null);
085    }
086
087    /**
088     * @return the image
089     */
090    public Image getImage()
091    {
092        return image;
093    }
094
095    /**
096     * @param image
097     *        the image to set
098     */
099    public void setImage(Image image)
100    {
101        if (this.image != image)
102        {
103            this.image = image;
104            forceUpdateCache = true;
105            repaint();
106        }
107    }
108
109    protected void updateCache()
110    {
111        cachedImage = null;
112
113        if (image == null)
114            return;
115
116        // be sure image data are ready
117        ImageUtil.waitImageReady(image);
118
119        float ix = image.getWidth(null);
120        float iy = image.getHeight(null);
121
122        // something wrong here --> use 'fault' image
123        if ((ix <= 0f) || (iy <= 0f))
124        {
125            image = ResourceUtil.ICON_DELETE;
126            ix = image.getWidth(null);
127            iy = image.getHeight(null);
128        }
129
130        // we want a minimal appearance of 100,100
131        final float w = Math.max(getWidth(), 100);
132        final float h = Math.max(getHeight(), 100);
133
134        if ((w > 0f) && (h > 0f))
135        {
136            final float sx = w / ix;
137            final float sy = h / iy;
138            final float s = Math.min(sx, sy);
139            final int nix = (int) (ix * s);
140            final int niy = (int) (iy * s);
141
142            if ((nix > 0) && (niy > 0))
143            {
144                // need to rebuild cached image ?
145                if (forceUpdateCache || (cachedImage == null) || (nix != cachedImage.getWidth())
146                        || (niy != cachedImage.getHeight()))
147                {
148                    cachedImage = ImageUtil.scaleQuality(image, nix, niy);
149                    forceUpdateCache = false;
150                }
151            }
152        }
153    }
154
155    @Override
156    protected void paintComponent(Graphics g)
157    {
158        super.paintComponent(g);
159
160        updateCache();
161
162        if (cachedImage != null)
163            g.drawImage(cachedImage, (getWidth() - cachedImage.getWidth()) / 2,
164                    (getHeight() - cachedImage.getHeight()) / 2, null);
165    }
166}