/* * Bibliothek - DockingFrames * Library built on Java/Swing, allows the user to "drag and drop" * panels containing any Swing-Component the developer likes to add. * * Copyright (C) 2007 Benjamin Sigg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Benjamin Sigg * benjamin_sigg@gmx.ch * CH - Switzerland */ package bibliothek.gui.dock.dockable; import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import javax.swing.Icon; import bibliothek.gui.DockController; import bibliothek.gui.Dockable; import bibliothek.gui.dock.title.DockTitle; import bibliothek.gui.dock.util.AWTComponentCaptureStrategy; import bibliothek.gui.dock.util.DockSwingUtilities; /** * A factory that makes a snapshot of the {@link Dockable} which will be represented * by its {@link MovingImage}. * @author Benjamin Sigg * */ public class ScreencaptureMovingImageFactory implements DockableMovingImageFactory { /** the maximal size of the images created by this factory */ private Dimension max; /** the transparency */ private float alpha; /** * Creates a new factory. * @param max the maximal size of the images created by this factory, or <code>null</code> * for not having a maximum size */ public ScreencaptureMovingImageFactory( Dimension max ){ this( max, 1.0f ); } /** * Creates a new factory. * @param max the maximal size of the images created by this factory, or <code>null</code> * for not having a maximum size * @param alpha the transparency of this image, where 0 means completely transparent and 1 means completely * opaque */ public ScreencaptureMovingImageFactory( Dimension max, float alpha ){ this.max = max; setAlpha( alpha ); } /** * Set the transparency of this image, where 0 means completely transparent and 1 means completely * opaque * @param alpha the strength of the image */ public void setAlpha( float alpha ){ if( alpha < 0 || alpha > 1 || Float.isNaN( alpha )){ throw new IllegalArgumentException( "alpha must be between 0 and 1" ); } this.alpha = alpha; } /** * Gets the transparency. * @return the transparency, a value between 0 and 1 */ public float getAlpha(){ return alpha; } public MovingImage create( DockController controller, DockTitle snatched ) { return create( controller, snatched.getDockable() ); } public MovingImage create( DockController controller, Dockable dockable ) { BufferedImage image = createImageFrom( controller, dockable ); TrueMovingImage moving = new TrueMovingImage(); moving.setAlpha( alpha ); moving.setImage( image ); return moving; } /** * This method creates a new image that contains the contents of <code>dockable</code>. * @param controller the controller for which the image is made * @param dockable the element whose image should be taken * @return an image of <code>dockable</code> which is not larger than the * maximum {@link Dimension} that was given to this factory in the * constructor. * @see AWTComponentCaptureStrategy */ public BufferedImage createImageFrom( DockController controller, Dockable dockable ){ Component c = dockable.getComponent(); BufferedImage image = createImageFrom( controller, c ); if( image == null ){ Icon icon = dockable.getTitleIcon(); if( icon == null || icon.getIconHeight() < 1 || icon.getIconWidth() < 1 ) return null; image = new BufferedImage( icon.getIconWidth()+2, icon.getIconHeight()+2, BufferedImage.TYPE_INT_ARGB ); Graphics2D g = image.createGraphics(); g.setColor( c.getBackground() ); g.fillRect( 0, 0, image.getWidth(), image.getHeight() ); icon.paintIcon( c, g, 1, 1 ); g.dispose(); } return image; } /** * This method creates a new image that contains the contents of <code>c</code>. * @param controller the controller for which the image is made * @param c the {@link Component} whose image should be taken * @return an image of <code>c</code> which is not larger than the * maximum {@link Dimension} that was given to this factory in the * constructor. * @see AWTComponentCaptureStrategy */ public BufferedImage createImageFrom( DockController controller, Component c ){ Dimension size = new Dimension( Math.max( 1, c.getWidth() ), Math.max( 1, c.getHeight() )); BufferedImage image = null; if( size.width >= 10 && size.height >= 10 ){ if( DockSwingUtilities.containsAWTComponents( c )){ image = controller.getProperties().get( AWTComponentCaptureStrategy.STRATEGY ).createCapture( controller, c ); } else{ image = new BufferedImage( size.width, size.height, BufferedImage.TYPE_INT_ARGB ); Graphics g = image.createGraphics(); c.paint( g ); g.dispose(); } if( image != null ){ double factor = 1.0; if( max != null ){ factor = Math.min( max.getWidth() / size.getWidth(), max.getHeight() / size.getHeight() ); } if( factor < 1.0 ){ int w = (int)( factor * size.getWidth() ); int h = (int)( factor * size.getHeight() ); w = Math.max( w, 1 ); h = Math.max( h, 1 ); if( w != size.width || h != size.height ){ BufferedImage small = new BufferedImage( w, h, image.getType() ); Graphics2D g = small.createGraphics(); g.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC ); g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ); g.drawImage( image, 0, 0, w, h, 0, 0, size.width, size.height, null ); g.dispose(); image = small; } } } } return image; } }