/*
* Copyright (c) 2007, Romain Guy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the TimingFramework project nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.TransferHandler;
import javax.swing.TransferHandler.TransferSupport;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.awt.GraphicsConfiguration;
import java.awt.Transparency;
import java.awt.Graphics;
import java.awt.GraphicsEnvironment;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
/**
*
* @author Romain Guy
*/
public class GlassPaneDragAndDrop extends javax.swing.JFrame {
private PictureGlassPane glassPane = new PictureGlassPane();
public GlassPaneDragAndDrop() {
setContentPane(new JPanel(new BorderLayout()) {
private BufferedImage image = null;
@Override
public boolean isOpaque() {
return imageList.getModel().getSize() > 0;
}
@Override
protected void paintComponent(Graphics g) {
Rectangle clip = g.getClipBounds();
g.setColor(Color.WHITE);
g.fillRect(clip.x, clip.y, clip.width, clip.height);
if (image == null) {
try {
image = ImageIO.read(getClass().getResource("drop-here.png"));
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
g.drawImage(image, (getWidth() - image.getWidth()) / 2,
(getHeight() - image.getHeight()) / 2, null);
}
});
initComponents();
imageList.setOpaque(false);
listScroller.setOpaque(false);
listScroller.getViewport().setOpaque(false);
setGlassPane(glassPane);
imageList.setModel(new DefaultListModel());
imageList.setTransferHandler(new FileDropHandler());
imageList.addPropertyChangeListener("dropLocation", new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
glassPane.moveIt(MouseInfo.getPointerInfo().getLocation());
}
});
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
// //GEN-BEGIN:initComponents
private void initComponents() {
javax.swing.JLabel jLabel1;
javax.swing.JLabel jLabel2;
javax.swing.JLabel jLabel3;
javax.swing.JPanel jPanel1;
javax.swing.JSeparator jSeparator1;
listScroller = new javax.swing.JScrollPane();
imageList = new javax.swing.JList();
jPanel1 = new javax.swing.JPanel();
jLabel1 = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel();
jSeparator1 = new javax.swing.JSeparator();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Glass Drag and Drop");
imageList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
imageList.setLayoutOrientation(javax.swing.JList.HORIZONTAL_WRAP);
imageList.setVisibleRowCount(-1);
listScroller.setViewportView(imageList);
jPanel1.setBackground(new java.awt.Color(255, 255, 255));
jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("app-icon.png")));
jLabel2.setFont(jLabel2.getFont().deriveFont(jLabel2.getFont().getStyle() | java.awt.Font.BOLD, jLabel2.getFont().getSize()+2));
jLabel2.setText("Glass Drag and Drop");
jLabel3.setText("Drag and drop image files (PNG or JPEG) onto the application.");
org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.add(jLabel1)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jLabel2)
.add(jLabel3))
.addContainerGap(158, Short.MAX_VALUE))
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jPanel1Layout.createSequentialGroup()
.add(jLabel2)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(jLabel3))
.add(jLabel1))
.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.add(jSeparator1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 618, Short.MAX_VALUE)
.add(layout.createSequentialGroup()
.addContainerGap()
.add(listScroller, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 578, Short.MAX_VALUE)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(layout.createSequentialGroup()
.add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.add(0, 0, 0)
.add(jSeparator1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 10, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(listScroller, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 372, Short.MAX_VALUE)
.addContainerGap())
);
pack();
java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
java.awt.Dimension dialogSize = getSize();
setLocation((screenSize.width-dialogSize.width)/2,(screenSize.height-dialogSize.height)/2);
}// //GEN-END:initComponents
class FileDropHandler extends TransferHandler {
private boolean imported = false;
private List fileList;
public boolean canImport(TransferSupport support) {
if (!support.isDrop()) {
return false;
}
if (!support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
return false;
}
boolean copySupported = (COPY & support.getSourceDropActions()) == COPY;
if (copySupported) {
support.setDropAction(COPY);
if (!imported) {
Transferable t = support.getTransferable();
try {
Object data = t.getTransferData(DataFlavor.javaFileListFlavor);
this.fileList = (List) data;
BufferedImage image = createImage(fileList);
if (image != null) {
Point p = MouseInfo.getPointerInfo().getLocation();
glassPane.showIt(image, p);
imported = true;
}
} catch (UnsupportedFlavorException e) {
return false;
} catch (IOException e) {
return false;
}
}
return true;
}
return false;
}
private BufferedImage createImage(List files) {
List imageFiles = new ArrayList(3);
for (File file : files) {
if (file.getName().endsWith(".png") ||
file.getName().endsWith(".jpg")) {
imageFiles.add(file);
if (imageFiles.size() == 3) {
break;
}
}
}
if (imageFiles.size() == 0) {
return null;
}
int width = 60 + (imageFiles.size() - 1) * 10;
int height = 45 + (imageFiles.size() - 1) * 10;
BufferedImage image =
GraphicsUtilities.createCompatibleTranslucentImage(width, height);
Graphics2D g2 = image.createGraphics();
for (int i = 0; i < imageFiles.size(); i++) {
File imageFile = imageFiles.get(i);
BufferedImage externalImage = null;
try {
externalImage = GraphicsUtilities.loadCompatibleImage(imageFile.toURI().toURL());
} catch (MalformedURLException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
externalImage = GraphicsUtilities.createThumbnail(externalImage, 60, 45);
g2.drawImage(externalImage, i * 10, i * 10, null);
}
g2.dispose();
return image;
}
public boolean importData(TransferSupport support) {
if (!canImport(support)) {
return false;
}
if (!support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
return false;
}
for (int i = 0; i < fileList.size(); i++) {
File imageFile = fileList.get(i);
BufferedImage externalImage = null;
try {
externalImage = GraphicsUtilities.loadCompatibleImage(imageFile.toURI().toURL());
externalImage = GraphicsUtilities.createThumbnail(externalImage, 120);
} catch (MalformedURLException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
((DefaultListModel) imageList.getModel()).add(0, new ImageIcon(externalImage));
}
glassPane.hideIt();
imported = false;
return true;
}
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new GlassPaneDragAndDrop().setVisible(true);
}
});
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JList imageList;
private javax.swing.JScrollPane listScroller;
// End of variables declaration//GEN-END:variables
}
/*
* $Id: GraphicsUtilities.java,v 1.11 2007/04/29 22:33:33 gfx Exp $
*
* Dual-licensed under LGPL (Sun and Romain Guy) and BSD (Romain Guy).
*
* Copyright 2005 Sun Microsystems, Inc., 4150 Network Circle,
* Santa Clara, California 95054, U.S.A. All rights reserved.
*
* Copyright (c) 2006 Romain Guy
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* GraphicsUtilities
contains a set of tools to perform
* common graphics operations easily. These operations are divided into
* several themes, listed below.
*
* Compatible Images
*
* Compatible images can, and should, be used to increase drawing
* performance. This class provides a number of methods to load compatible
* images directly from files or to convert existing images to compatibles
* images.
*
* Creating Thumbnails
*
* This class provides a number of methods to easily scale down images.
* Some of these methods offer a trade-off between speed and result quality and
* shouuld be used all the time. They also offer the advantage of producing
* compatible images, thus automatically resulting into better runtime
* performance.
*
* All these methodes are both faster than
* {@link java.awt.Image#getScaledInstance(int, int, int)} and produce
* better-looking results than the various drawImage()
methods
* in {@link java.awt.Graphics}, which can be used for image scaling.
* Image Manipulation
*
* This class provides two methods to get and set pixels in a buffered image.
* These methods try to avoid unmanaging the image in order to keep good
* performance.
*
* @author Romain Guy
* @author rbair
*/
class GraphicsUtilities {
private GraphicsUtilities() {
}
// Returns the graphics configuration for the primary screen
private static GraphicsConfiguration getGraphicsConfiguration() {
return GraphicsEnvironment.getLocalGraphicsEnvironment().
getDefaultScreenDevice().getDefaultConfiguration();
}
private static boolean isHeadless() {
return GraphicsEnvironment.isHeadless();
}
/**
* Returns a new BufferedImage
using the same color model
* as the image passed as a parameter. The returned image is only compatible
* with the image passed as a parameter. This does not mean the returned
* image is compatible with the hardware.
*
* @param image the reference image from which the color model of the new
* image is obtained
* @return a new BufferedImage
, compatible with the color model
* of image
*/
public static BufferedImage createColorModelCompatibleImage(BufferedImage image) {
ColorModel cm = image.getColorModel();
return new BufferedImage(cm,
cm.createCompatibleWritableRaster(image.getWidth(),
image.getHeight()),
cm.isAlphaPremultiplied(), null);
}
/**
* Returns a new compatible image with the same width, height and
* transparency as the image specified as a parameter. That is, the
* returned BufferedImage will be compatible with the graphics hardware.
* If this method is called in a headless environment, then
* the returned BufferedImage will be compatible with the source
* image.
*
* @see java.awt.Transparency
* @see #createCompatibleImage(int, int)
* @see #createCompatibleImage(java.awt.image.BufferedImage, int, int)
* @see #createCompatibleTranslucentImage(int, int)
* @see #loadCompatibleImage(java.net.URL)
* @see #toCompatibleImage(java.awt.image.BufferedImage)
* @param image the reference image from which the dimension and the
* transparency of the new image are obtained
* @return a new compatible BufferedImage
with the same
* dimension and transparency as image
*/
public static BufferedImage createCompatibleImage(BufferedImage image) {
return createCompatibleImage(image, image.getWidth(), image.getHeight());
}
/**
* Returns a new compatible image of the specified width and height, and
* the same transparency setting as the image specified as a parameter.
* That is, the returned BufferedImage
is compatible with
* the graphics hardware. If the method is called in a headless
* environment, then the returned BufferedImage will be compatible with
* the source image.
*
* @see java.awt.Transparency
* @see #createCompatibleImage(java.awt.image.BufferedImage)
* @see #createCompatibleImage(int, int)
* @see #createCompatibleTranslucentImage(int, int)
* @see #loadCompatibleImage(java.net.URL)
* @see #toCompatibleImage(java.awt.image.BufferedImage)
* @param width the width of the new image
* @param height the height of the new image
* @param image the reference image from which the transparency of the new
* image is obtained
* @return a new compatible BufferedImage
with the same
* transparency as image
and the specified dimension
*/
public static BufferedImage createCompatibleImage(BufferedImage image,
int width, int height) {
return isHeadless() ?
new BufferedImage(width, height, image.getType()) :
getGraphicsConfiguration().createCompatibleImage(width, height,
image.getTransparency());
}
/**
* Returns a new opaque compatible image of the specified width and
* height. That is, the returned BufferedImage
is compatible with
* the graphics hardware. If the method is called in a headless
* environment, then the returned BufferedImage will be compatible with
* the source image.
*
* @see #createCompatibleImage(java.awt.image.BufferedImage)
* @see #createCompatibleImage(java.awt.image.BufferedImage, int, int)
* @see #createCompatibleTranslucentImage(int, int)
* @see #loadCompatibleImage(java.net.URL)
* @see #toCompatibleImage(java.awt.image.BufferedImage)
* @param width the width of the new image
* @param height the height of the new image
* @return a new opaque compatible BufferedImage
of the
* specified width and height
*/
public static BufferedImage createCompatibleImage(int width, int height) {
return isHeadless() ?
new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB) :
getGraphicsConfiguration().createCompatibleImage(width, height);
}
/**
* Returns a new translucent compatible image of the specified width and
* height. That is, the returned BufferedImage
is compatible with
* the graphics hardware. If the method is called in a headless
* environment, then the returned BufferedImage will be compatible with
* the source image.
*
* @see #createCompatibleImage(java.awt.image.BufferedImage)
* @see #createCompatibleImage(java.awt.image.BufferedImage, int, int)
* @see #createCompatibleImage(int, int)
* @see #loadCompatibleImage(java.net.URL)
* @see #toCompatibleImage(java.awt.image.BufferedImage)
* @param width the width of the new image
* @param height the height of the new image
* @return a new translucent compatible BufferedImage
of the
* specified width and height
*/
public static BufferedImage createCompatibleTranslucentImage(int width,
int height) {
return isHeadless() ?
new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB) :
getGraphicsConfiguration().createCompatibleImage(width, height,
Transparency.TRANSLUCENT);
}
/**
* Returns a new compatible image from a URL. The image is loaded from the
* specified location and then turned, if necessary into a compatible
* image.
*
* @see #createCompatibleImage(java.awt.image.BufferedImage)
* @see #createCompatibleImage(java.awt.image.BufferedImage, int, int)
* @see #createCompatibleImage(int, int)
* @see #createCompatibleTranslucentImage(int, int)
* @see #toCompatibleImage(java.awt.image.BufferedImage)
* @param resource the URL of the picture to load as a compatible image
* @return a new translucent compatible BufferedImage
of the
* specified width and height
* @throws java.io.IOException if the image cannot be read or loaded
*/
public static BufferedImage loadCompatibleImage(URL resource)
throws IOException {
BufferedImage image = ImageIO.read(resource);
return toCompatibleImage(image);
}
/**
* Return a new compatible image that contains a copy of the specified
* image. This method ensures an image is compatible with the hardware,
* and therefore optimized for fast blitting operations.
*
* If the method is called in a headless environment, then the returned
* BufferedImage
will be the source image.
*
* @see #createCompatibleImage(java.awt.image.BufferedImage)
* @see #createCompatibleImage(java.awt.image.BufferedImage, int, int)
* @see #createCompatibleImage(int, int)
* @see #createCompatibleTranslucentImage(int, int)
* @see #loadCompatibleImage(java.net.URL)
* @param image the image to copy into a new compatible image
* @return a new compatible copy, with the
* same width and height and transparency and content, of image
*/
public static BufferedImage toCompatibleImage(BufferedImage image) {
if (isHeadless()) {
return image;
}
if (image.getColorModel().equals(
getGraphicsConfiguration().getColorModel())) {
return image;
}
BufferedImage compatibleImage =
getGraphicsConfiguration().createCompatibleImage(
image.getWidth(), image.getHeight(),
image.getTransparency());
Graphics g = compatibleImage.getGraphics();
g.drawImage(image, 0, 0, null);
g.dispose();
return compatibleImage;
}
/**
* Returns a thumbnail of a source image. newSize
defines
* the length of the longest dimension of the thumbnail. The other
* dimension is then computed according to the dimensions ratio of the
* original picture.
* This method favors speed over quality. When the new size is less than
* half the longest dimension of the source image,
* {@link #createThumbnail(BufferedImage, int)} or
* {@link #createThumbnail(BufferedImage, int, int)} should be used instead
* to ensure the quality of the result without sacrificing too much
* performance.
*
* @see #createThumbnailFast(java.awt.image.BufferedImage, int, int)
* @see #createThumbnail(java.awt.image.BufferedImage, int)
* @see #createThumbnail(java.awt.image.BufferedImage, int, int)
* @param image the source image
* @param newSize the length of the largest dimension of the thumbnail
* @return a new compatible BufferedImage
containing a
* thumbnail of image
* @throws IllegalArgumentException if newSize
is larger than
* the largest dimension of image
or <= 0
*/
public static BufferedImage createThumbnailFast(BufferedImage image,
int newSize) {
float ratio;
int width = image.getWidth();
int height = image.getHeight();
if (width > height) {
if (newSize >= width) {
throw new IllegalArgumentException("newSize must be lower than" +
" the image width");
} else if (newSize <= 0) {
throw new IllegalArgumentException("newSize must" +
" be greater than 0");
}
ratio = (float) width / (float) height;
width = newSize;
height = (int) (newSize / ratio);
} else {
if (newSize >= height) {
throw new IllegalArgumentException("newSize must be lower than" +
" the image height");
} else if (newSize <= 0) {
throw new IllegalArgumentException("newSize must" +
" be greater than 0");
}
ratio = (float) height / (float) width;
height = newSize;
width = (int) (newSize / ratio);
}
BufferedImage temp = createCompatibleImage(image, width, height);
Graphics2D g2 = temp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(image, 0, 0, temp.getWidth(), temp.getHeight(), null);
g2.dispose();
return temp;
}
/**
* Returns a thumbnail of a source image.
* This method favors speed over quality. When the new size is less than
* half the longest dimension of the source image,
* {@link #createThumbnail(BufferedImage, int)} or
* {@link #createThumbnail(BufferedImage, int, int)} should be used instead
* to ensure the quality of the result without sacrificing too much
* performance.
*
* @see #createThumbnailFast(java.awt.image.BufferedImage, int)
* @see #createThumbnail(java.awt.image.BufferedImage, int)
* @see #createThumbnail(java.awt.image.BufferedImage, int, int)
* @param image the source image
* @param newWidth the width of the thumbnail
* @param newHeight the height of the thumbnail
* @return a new compatible BufferedImage
containing a
* thumbnail of image
* @throws IllegalArgumentException if newWidth
is larger than
* the width of image
or if code>newHeight
is largerimage
or if one of the dimensionsReturns a thumbnail of a source image. newSize
defines
* the length of the longest dimension of the thumbnail. The other
* dimension is then computed according to the dimensions ratio of the
* original picture.
This method offers a good trade-off between speed and quality.
* The result looks better than
* {@link #createThumbnailFast(java.awt.image.BufferedImage, int)} when
* the new size is less than half the longest dimension of the source
* image, yet the rendering speed is almost similar.
BufferedImage
containing aimage
newSize
is larger thanimage
or <= 0Returns a thumbnail of a source image.
This method offers a good trade-off between speed and quality.
* The result looks better than
* {@link #createThumbnailFast(java.awt.image.BufferedImage, int)} when
* the new size is less than half the longest dimension of the source
* image, yet the rendering speed is almost similar.
BufferedImage
containing aimage
newWidth
is larger thanimage
or if code>newHeight is largerimage or if one the dimensions is not > 0
Returns an array of pixels, stored as integers, from a
* BufferedImage
. The pixels are grabbed from a rectangular
* area defined by a location and two dimensions. Calling this method on
* an image of type different from BufferedImage.TYPE_INT_ARGB
* and BufferedImage.TYPE_INT_RGB
will unmanage the image.
pixels
if non-null, a new array of integerspixels
is non-null andWrites a rectangular area of pixels in the destination
* BufferedImage
. Calling this method on
* an image of type different from BufferedImage.TYPE_INT_ARGB
* and BufferedImage.TYPE_INT_RGB
will unmanage the image.
pixels
is non-null andA shadow renderer generates a drop shadow for any given picture, respecting
* the transparency channel if present. The resulting picture contains the
* shadow only and to create a drop shadow effect you will need to stack the
* original picture and the shadow generated by the renderer.
A shadow is defined by three properties:
*
* ShadowRenderer renderer = new ShadowRenderer(10, 0.5f, Color.GREEN);
* // ..
* renderer = new ShadowRenderer();
* renderer.setSize(10);
* renderer.setOpacity(0.5f);
* renderer.setColor(Color.GREEN);
*
A shadow is generated as a BufferedImage
from another
* BufferedImage
. Once the renderer is set up, you must call
* {@link #createShadow} to actually generate the shadow:
*
* ShadowRenderer renderer = new ShadowRenderer();
* // renderer setup
* BufferedImage shadow = renderer.createShadow(bufferedImage);
*
The generated image dimensions are computed as following:
* width = imageWidth + 2 * shadowSize
* height = imageHeight + 2 * shadowSize
*
This renderer allows to register property change listeners with
* {@link #addPropertyChangeListener}. Listening to properties changes is very
* useful when you emebed the renderer in a graphical component and give the API
* user the ability to access the renderer. By listening to properties changes,
* you can easily repaint the component when needed.
ShadowRenderer
is not guaranteed to be thread-safe.
Identifies a change to the size used to render the shadow.
When the property change event is fired, the old value and the new
* value are provided as Integer
instances.
Identifies a change to the opacity used to render the shadow.
When the property change event is fired, the old value and the new
* value are provided as Float
instances.
Identifies a change to the color used to render the shadow.
Creates a default good looking shadow generator.
* The default shadow renderer provides the following default values:
*
These properties provide a regular, good looking shadow.
A shadow renderer needs three properties to generate shadows.
* These properties are:
Add a PropertyChangeListener to the listener list. The listener is
* registered for all properties. The same listener object may be added
* more than once, and will be called as many times as it is added. If
* listener
is null, no exception is thrown and no action
* is taken.
Remove a PropertyChangeListener from the listener list. This removes
* a PropertyChangeListener that was registered for all properties. If
* listener
was added more than once to the same event source,
* it will be notified one less time after being removed. If
* listener
is null, or was never added, no exception is thrown
* and no action is taken.
Gets the color used by the renderer to generate shadows.
Sets the color used by the renderer to generate shadows.
Consecutive calls to {@link #createShadow} will all use this color
* until it is set again.
If the color provided is null, the previous color will be retained.
Gets the opacity used by the renderer to generate shadows.
The opacity is comprised between 0.0f and 1.0f; 0.0f being fully
* transparent and 1.0f fully opaque.
Sets the opacity used by the renderer to generate shadows.
Consecutive calls to {@link #createShadow} will all use this opacity
* until it is set again.
The opacity is comprised between 0.0f and 1.0f; 0.0f being fully
* transparent and 1.0f fully opaque. If you provide a value out of these
* boundaries, it will be restrained to the closest boundary.
Gets the size in pixel used by the renderer to generate shadows.
Sets the size, in pixels, used by the renderer to generate shadows.
The size defines the blur radius applied to the shadow to create the
* fuzziness.
There is virtually no limit to the size. The size cannot be negative.
* If you provide a negative value, the size will be 0 instead.
Generates the shadow for a given picture and the current properties
* of the renderer.
The generated image dimensions are computed as following:
* width = imageWidth + 2 * shadowSize
* height = imageHeight + 2 * shadowSize
*
image