/* Copyright (C) 2006 Christian Schneider * * This file is part of Nomad. * * Nomad is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Nomad is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nomad; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* * Created on Jun 29, 2006 */ package net.sf.nmedit.jtheme; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Image; import java.awt.Insets; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.image.BufferedImage; import javax.swing.JPanel; import javax.swing.SwingUtilities; import net.sf.nmedit.nmutils.graphics.GraphicsToolkit; public class ImagePreview extends JPanel { /** * */ private static final long serialVersionUID = -1152051978348388139L; private Image original = null; private BufferedImage scaled = null; private boolean autoResizeH = false; private boolean autoResizeV = false; private boolean onlyScaledDown = true; public ImagePreview() { addComponentListener(new PreviewUpdater()); } public boolean isOnlyScaledDownEnabled() { return onlyScaledDown; } public void setOnlyScaleDownEnabled(boolean enable) { this.onlyScaledDown = enable; } public boolean isHorizontalAutoresizeEnabled() { return autoResizeH; } public boolean isVerticalAutoresizeEnabled() { return autoResizeH; } public void setHorizontalAutoresizeEnabled(boolean enable) { if (this.autoResizeH!=enable) { this.autoResizeH = enable; //updateScaledImage(); } } public void setVerticalAutoresizeEnabled(boolean enable) { if (this.autoResizeV!=enable) { this.autoResizeV = enable; //updateScaledImage(); } } public void setPreviewImage(Image image) { if (original != image) { this.original = image; updateScaledImage(); } } private void updateScaledImage() { if (original!=null) SwingUtilities.invokeLater(new ScaledImageProducer(original)); else setScaledImage(null); } public Image getPreviewImage() { return original; } protected void paintComponent(Graphics g) { super.paintComponent(g); if (scaled != null) { final int w = getWidth(); final int h = getHeight(); final int sw = scaled.getWidth(null); final int sh = scaled.getHeight(null); final int dx = Math.max(0, (w-sw)/2); final int dy = Math.max(0, (h-sh)/2); g.drawImage(scaled, dx, dy, null); } } private void setScaledImage(BufferedImage scaled) { if (this.scaled != scaled) { this.scaled = scaled; if (scaled!=null) { int w = scaled.getWidth(); int h = scaled.getHeight(); Insets insets = getInsets(); if (insets!=null) { w+= insets.left+insets.right; h+= insets.top+insets.bottom; } Dimension d = getMinimumSize(); if (d!=null) { w = Math.max(w, d.width); h = Math.max(h, d.height); } setPreferredSize(new Dimension(w, h)); } else { setPreferredSize(getMinimumSize()); } revalidate(); repaint(); } } private class ScaledImageProducer implements Runnable { private final Image image; private final int maxw; private final int maxh; private boolean autoV ; private boolean autoH ; public ScaledImageProducer(Image image) { this.image = image; int insetsTotalX = 0; int insetsTotalY = 0; Insets insets = getInsets(); if (insets!=null) { insetsTotalX = insets.left+insets.right; insetsTotalY = insets.top+insets.bottom; } this.maxw = getWidth() - insetsTotalX; this.maxh = getHeight() - insetsTotalY; this.autoH = autoResizeH; this.autoV = autoResizeV; } public void run() { if (!scaleAndSet()) setScaledImage(null); else if (autoV || autoH) setSize(getPreferredSize()); } public boolean scaleAndSet() { if (original != image || maxw<=0 || maxh<=0) return false; // image has changed in the meanwhile final int iw = image.getWidth(null); final int ih = image.getHeight(null); if (iw <= 0 || ih <= 0) return false; final double fw = maxw/(double)iw; final double fh = maxh/(double)ih; double f; if ((!autoH) && (!autoV)) f = Math.min(fw, fh); else if ((autoH) && (!autoV)) f = fh; else if ((!autoH) && (autoV)) f = fw; else { // no scaling required f = 1; if (image instanceof BufferedImage) { setScaledImage((BufferedImage) image); return true; } } f = Math.max(f, 0); if (isOnlyScaledDownEnabled()) f = Math.min(f, 1); if (f==0) return false; // should not happen setScaledImage(GraphicsToolkit.getScaledImage(image, f)); return true; } } private class PreviewUpdater extends ComponentAdapter { public void componentResized(ComponentEvent e) { updateScaledImage(); } } }