Java/Advanced Graphics/Fade

Материал из Java эксперт
Перейти к: навигация, поиск

Fading button

   <source lang="java">

import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; import javax.swing.Timer; /*

* FadingButton_2008.java
*
* Created on May 2, 2007, 4:11 PM
*
* Copyright (c) 2007, Sun Microsystems, Inc
* 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.
*/

/**

* 
* @author Chet
*/

public class FadingButton_2008 extends JButton implements ActionListener {

 float alpha = 1.0f; // current opacity of button
 Timer timer; // for later start/stop actions
 int animationDuration = 2000; // each animation will take 2 seconds
 long animationStartTime; // start time for each animation
 BufferedImage buttonImage = null;
 /** Creates a new instance of FadingButton_2008 */
 public FadingButton_2008(String label) {
   super(label);
   setOpaque(false);
   timer = new Timer(30, this);
   addActionListener(this);
 }
 public void paint(Graphics g) {
   // Create an image for the button graphics if necessary
   if (buttonImage == null || buttonImage.getWidth() != getWidth()
       || buttonImage.getHeight() != getHeight()) {
     buttonImage = getGraphicsConfiguration().createCompatibleImage(getWidth(), getHeight());
   }
   Graphics gButton = buttonImage.getGraphics();
   gButton.setClip(g.getClip());
   // Have the superclass render the button for us
   super.paint(gButton);
   // Make the graphics object sent to this paint() method translucent
   Graphics2D g2d = (Graphics2D) g;
   AlphaComposite newComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
   g2d.setComposite(newComposite);
   // Copy the button"s image to the destination graphics, translucently
   g2d.drawImage(buttonImage, 0, 0, null);
 }
 /**
  * This method receives both click events (which start and stop the animation)
  * and Timer events (which animate the alpha of the button).
  */
 public void actionPerformed(ActionEvent ae) {
   if (ae.getSource().equals(this)) {
     // button click
     if (!timer.isRunning()) {
       animationStartTime = System.nanoTime() / 1000000;
       this.setText("Stop Animation");
       timer.start();
     } else {
       timer.stop();
       this.setText("Start Animation");
       // reset alpha to opaque
       alpha = 1.0f;
     }
   } else {
     // timer event
     // calculate the elapsed fraction
     long currentTime = System.nanoTime() / 1000000;
     long totalTime = currentTime - animationStartTime;
     if (totalTime > animationDuration) {
       animationStartTime = currentTime;
     }
     float fraction = (float) totalTime / animationDuration;
     fraction = Math.min(1.0f, fraction);
     // This calculation will cause alpha to go from 1 to 0 and back to 1
     // as the fraction goes from 0 to 1
     alpha = Math.abs(1 - (2 * fraction));
     // redisplay our button with its new alpha value
     repaint();
   }
 }
 private static void createAndShowGUI() {
   JFrame f = new JFrame("Fading Button");
   f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   f.setSize(300, 300);
   JPanel checkerboard = new Checkerboard();
   checkerboard.add(new FadingButton_2008("Start Animation"));
   f.add(checkerboard);
   f.setVisible(true);
 }
 public static void main(String args[]) {
   Runnable doCreateAndShowGUI = new Runnable() {
     public void run() {
       createAndShowGUI();
     }
   };
   SwingUtilities.invokeLater(doCreateAndShowGUI);
 }
 /**
  * Displays checkerboard background
  */
 private static class Checkerboard extends JPanel {
   private static final int DIVISIONS = 10;
   static final int CHECKER_SIZE = 60;
   public void paintComponent(Graphics g) {
     g.setColor(Color.white);
     g.fillRect(0, 0, getWidth(), getHeight());
     g.setColor(Color.BLACK);
     for (int stripeX = 0; stripeX < getWidth(); stripeX += CHECKER_SIZE) {
       for (int y = 0, row = 0; y < getHeight(); y += CHECKER_SIZE / 2, ++row) {
         int x = (row % 2 == 0) ? stripeX : (stripeX + CHECKER_SIZE / 2);
         g.fillRect(x, y, CHECKER_SIZE / 2, CHECKER_SIZE / 2);
       }
     }
   }
 }

}

</source>
   
  
 
  



Fast Blur Demo

   <source lang="java">

/*

* 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.Rectangle; import java.awt.RenderingHints; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImageOp; 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.AlphaComposite; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOException; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; /**

* See {@link org.jdesktop.swingx.image.FastBlurFilter}.
*
* @author Romain Guy <romain.guy@mac.ru>
*/

public class FastBlurDemo extends JFrame {

   private BlurTestPanel blurTestPanel;
   private JSlider radiusSlider;
   private JSlider iterationsSlider;
   public FastBlurDemo() {
       super("Fast Blur/Stack Blur");
       blurTestPanel = new BlurTestPanel();
       add(blurTestPanel);
       radiusSlider = new JSlider(0, 100, 0);
       radiusSlider.addChangeListener(new ChangeListener() {
           public void stateChanged(ChangeEvent e) {
               blurTestPanel.setRadius(radiusSlider.getValue());
           }
       });
       iterationsSlider = new JSlider(1, 15, 1);
       iterationsSlider.addChangeListener(new ChangeListener() {
           public void stateChanged(ChangeEvent e) {
               blurTestPanel.setIterations(iterationsSlider.getValue());
           }
       });
       JPanel controls = new JPanel(new FlowLayout(FlowLayout.LEFT));
       controls.add(new JLabel("Radius: 0px"));
       controls.add(radiusSlider);
       controls.add(new JLabel("100px"));
       controls.add(new JLabel("Iterations: 1"));
       controls.add(iterationsSlider);
       controls.add(new JLabel("15"));
       add(controls, BorderLayout.SOUTH);
       pack();
       setLocationRelativeTo(null);
       setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   }
   private static class BlurTestPanel extends JPanel {
       private BufferedImage image = null;
       private BufferedImage imageA;
       private int radius = 0;
       private StackBlurFilter blurFilter;
       private int iterations = 1;
       private boolean repaint = false;
       public BlurTestPanel() {
           try {
               imageA = GraphicsUtilities.loadCompatibleImage(getClass().getResource("A.jpg"));
           } catch (IOException e) {
               e.printStackTrace();
           }
           blurFilter = new StackBlurFilter(radius, iterations);
       }
       @Override
       public Dimension getPreferredSize() {
           return new Dimension(imageA.getWidth(), imageA.getHeight());
       }
       @Override
       protected void paintComponent(Graphics g) {
           if (image == null) {
               image = new BufferedImage(imageA.getWidth(),
                                         imageA.getHeight(),
                                         BufferedImage.TYPE_INT_ARGB);
               repaint = true;
           }
           
           if (repaint) {
               Graphics2D g2 = image.createGraphics();
               g2.setComposite(AlphaComposite.Clear);
               g2.fillRect(0, 0, image.getWidth(), image.getHeight());
               
               g2.setComposite(AlphaComposite.Src);
               
               if (radius > 0) {
                   long start = System.nanoTime();
                   
                   g2.drawImage(imageA, blurFilter, 0, 0);
                   
                   long delay = System.nanoTime() - start;
                   System.out.println("time = " + (delay / 1000.0f / 1000.0f) + "ms");
               } else {
                   g2.drawImage(imageA, null, 0, 0);
               }
               g2.dispose();
               
               repaint = false;
           }
           int x = (getWidth() - image.getWidth()) / 2;
           int y = (getHeight() - image.getHeight()) / 2;
           g.drawImage(image, x, y, null);
       }
       public void setRadius(int radius) {
           this.radius = radius;
           this.blurFilter = new StackBlurFilter(radius, iterations);
           repaint = true;
           repaint();
       }
       public void setIterations(int iterations) {
           this.iterations = iterations;
           this.blurFilter = new StackBlurFilter(radius, iterations);
           repaint = true;
           repaint();
       }
   }
   public static void main(String... args) {
       SwingUtilities.invokeLater(new Runnable() {
           public void run() {
               new FastBlurDemo().setVisible(true);
           }
       });
   }

} /*

* 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.
*/

/**

*

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 <romain.guy@mac.ru>
*/

class GraphicsUtilities {

   private GraphicsUtilities() {
   }
   // Returns the graphics configuration for the primary screen
   private static GraphicsConfiguration getGraphicsConfiguration() {
       return GraphicsEnvironment.getLocalGraphicsEnvironment().
                   getDefaultScreenDevice().getDefaultConfiguration();
   }
   /**
*

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.

    *
    * @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.

    *
    * @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 getGraphicsConfiguration().createCompatibleImage(width, height,
                                                  image.getTransparency());
   }
   /**
*

Returns a new opaque compatible image of the specified width and * height.

    *
    * @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 getGraphicsConfiguration().createCompatibleImage(width, height);
   }
   /**
*

Returns a new translucent compatible image of the specified width * and height.

    *
    * @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 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.

    *
    * @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 (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</code> is larger
    *   than the height of image or if one of the dimensions
    *   is <= 0
    */
   public static BufferedImage createThumbnailFast(BufferedImage image,
                                                   int newWidth, int newHeight) {
       if (newWidth >= image.getWidth() ||
           newHeight >= image.getHeight()) {
           throw new IllegalArgumentException("newWidth and newHeight cannot" +
                                              " be greater than the image" +
                                              " dimensions");
       } else if (newWidth <= 0 || newHeight <= 0) {
           throw new IllegalArgumentException("newWidth and newHeight must" +
                                              " be greater than 0");
       }
       BufferedImage temp = createCompatibleImage(image, newWidth, newHeight);
       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. 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.

    *
    * @see #createThumbnailFast(java.awt.image.BufferedImage, int, int)
    * @see #createThumbnailFast(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 createThumbnail(BufferedImage image,
                                               int newSize) {
       int width = image.getWidth();
       int height = image.getHeight();
       boolean isWidthGreater = width > height;
       if (isWidthGreater) {
           if (newSize >= width) {
               throw new IllegalArgumentException("newSize must be lower than" +
                                                  " the image width");
           }
       } else if (newSize >= height) {
           throw new IllegalArgumentException("newSize must be lower than" +
                                              " the image height");
       }
       if (newSize <= 0) {
           throw new IllegalArgumentException("newSize must" +
                                              " be greater than 0");
       }
       float ratioWH = (float) width / (float) height;
       float ratioHW = (float) height / (float) width;
       BufferedImage thumb = image;
       do {
           if (isWidthGreater) {
               width /= 2;
               if (width < newSize) {
                   width = newSize;
               }
               height = (int) (width / ratioWH);
           } else {
               height /= 2;
               if (height < newSize) {
                   height = newSize;
               }
               width = (int) (height / ratioHW);
           }
           BufferedImage temp = createCompatibleImage(image, width, height);
           Graphics2D g2 = temp.createGraphics();
           g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                               RenderingHints.VALUE_INTERPOLATION_BILINEAR);
           g2.drawImage(thumb, 0, 0, temp.getWidth(), temp.getHeight(), null);
           g2.dispose();
           thumb = temp;
       } while (newSize != (isWidthGreater ? width : height));
       return thumb;
   }
   /**
*

Returns 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.

    *
    * @see #createThumbnailFast(java.awt.image.BufferedImage, int)
    * @see #createThumbnailFast(java.awt.image.BufferedImage, int, int)
    * @see #createThumbnail(java.awt.image.BufferedImage, 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</code> is larger
    *   than the height of image or if one the dimensions is not > 0
    */
   public static BufferedImage createThumbnail(BufferedImage image,
                                               int newWidth, int newHeight) {
       int width = image.getWidth();
       int height = image.getHeight();
       if (newWidth >= width || newHeight >= height) {
           throw new IllegalArgumentException("newWidth and newHeight cannot" +
                                              " be greater than the image" +
                                              " dimensions");
       } else if (newWidth <= 0 || newHeight <= 0) {
           throw new IllegalArgumentException("newWidth and newHeight must" +
                                              " be greater than 0");
       }
       BufferedImage thumb = image;
       do {
           if (width > newWidth) {
               width /= 2;
               if (width < newWidth) {
                   width = newWidth;
               }
           }
           if (height > newHeight) {
               height /= 2;
               if (height < newHeight) {
                   height = newHeight;
               }
           }
           BufferedImage temp = createCompatibleImage(image, width, height);
           Graphics2D g2 = temp.createGraphics();
           g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                               RenderingHints.VALUE_INTERPOLATION_BILINEAR);
           g2.drawImage(thumb, 0, 0, temp.getWidth(), temp.getHeight(), null);
           g2.dispose();
           thumb = temp;
       } while (width != newWidth || height != newHeight);
       return thumb;
   }
   /**
*

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.

    *
    * @param img the source image
    * @param x the x location at which to start grabbing pixels
    * @param y the y location at which to start grabbing pixels
    * @param w the width of the rectangle of pixels to grab
    * @param h the height of the rectangle of pixels to grab
    * @param pixels a pre-allocated array of pixels of size w*h; can be null
    * @return pixels if non-null, a new array of integers
    *   otherwise
    * @throws IllegalArgumentException is pixels is non-null and
    *   of length < w*h
    */
   public static int[] getPixels(BufferedImage img,
                                 int x, int y, int w, int h, int[] pixels) {
       if (w == 0 || h == 0) {
           return new int[0];
       }
       if (pixels == null) {
           pixels = new int[w * h];
       } else if (pixels.length < w * h) {
           throw new IllegalArgumentException("pixels array must have a length" +
                                              " >= w*h");
       }
       int imageType = img.getType();
       if (imageType == BufferedImage.TYPE_INT_ARGB ||
           imageType == BufferedImage.TYPE_INT_RGB) {
           Raster raster = img.getRaster();
           return (int[]) raster.getDataElements(x, y, w, h, pixels);
       }
       // Unmanages the image
       return img.getRGB(x, y, w, h, pixels, 0, w);
   }
   /**
*

Writes 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.

    *
    * @param img the destination image
    * @param x the x location at which to start storing pixels
    * @param y the y location at which to start storing pixels
    * @param w the width of the rectangle of pixels to store
    * @param h the height of the rectangle of pixels to store
    * @param pixels an array of pixels, stored as integers
    * @throws IllegalArgumentException is pixels is non-null and
    *   of length < w*h
    */
   public static void setPixels(BufferedImage img,
                                int x, int y, int w, int h, int[] pixels) {
       if (pixels == null || w == 0 || h == 0) {
           return;
       } else if (pixels.length < w * h) {
           throw new IllegalArgumentException("pixels array must have a length" +
                                              " >= w*h");
       }
       int imageType = img.getType();
       if (imageType == BufferedImage.TYPE_INT_ARGB ||
           imageType == BufferedImage.TYPE_INT_RGB) {
           WritableRaster raster = img.getRaster();
           raster.setDataElements(x, y, w, h, pixels);
       } else {
           // Unmanages the image
           img.setRGB(x, y, w, h, pixels, 0, w);
       }
   }

} /*

* 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.
*/

/**

*

A stack blur filter can be used to create an approximation of a * gaussian blur. The approximation is controlled by the number of times the * {@link org.jdesktop.swingx.image.FastBlurFilter} is applied onto the source * picture. The default number of iterations, 3, provides a decent compromise * between speed and rendering quality.

*

The force of the blur can be controlled with a radius and the * default radius is 3. Since the blur clamps values on the edges of the * source picture, you might need to provide a picture with empty borders * to avoid artifacts at the edges. The performance of this filter are * independant from the radius.

*
* @author Romain Guy <romain.guy@mac.ru>
  • /

class StackBlurFilter extends AbstractFilter {

   private final int radius;
   private final int iterations;
   /**
*

Creates a new blur filter with a default radius of 3 and 3 iterations.

    */
   public StackBlurFilter() {
       this(3, 3);
   }
   /**
*

Creates a new blur filter with the specified radius and 3 iterations. * If the radius is lower than 1, a radius of 1 will be used automatically.

    *
    * @param radius the radius, in pixels, of the blur
    */
   public StackBlurFilter(int radius) {
       this(radius, 3);
   }
   /**
*

Creates a new blur filter with the specified radius. If the radius * is lower than 1, a radius of 1 will be used automatically. The number * of iterations controls the approximation to a gaussian blur. If the * number of iterations is lower than 1, one iteration will be used * automatically.

    *
    * @param radius the radius, in pixels, of the blur
    * @param iterations the number of iterations to approximate a gaussian blur
    */
   public StackBlurFilter(int radius, int iterations) {
       if (radius < 1) {
           radius = 1;
       }
       if (iterations < 1) {
           iterations = 1;
       }
       this.radius = radius;
       this.iterations = iterations;
   }
   /**
*

Returns the effective radius of the stack blur. If the radius of the * blur is 1 and the stack iterations count is 3, then the effective blur * radius is 1 * 3 = 3.

    * @return the number of iterations times the blur radius
    */
   public int getEffectiveRadius() {
       return getIterations() * getRadius();
   }
   /**
*

Returns the radius used by this filter, in pixels.

    *
    * @return the radius of the blur
    */
   public int getRadius() {
       return radius;
   }
   /**
*

Returns the number of iterations used to approximate a gaussian * blur.

    *
    * @return the number of iterations used by this blur
    */
   public int getIterations() {
       return iterations;
   }
   /**
    * {@inheritDoc}
    */
   @Override
   public BufferedImage filter(BufferedImage src, BufferedImage dst) {
       int width = src.getWidth();
       int height = src.getHeight();
       if (dst == null) {
           dst = createCompatibleDestImage(src, null);
       }
       int[] srcPixels = new int[width * height];
       int[] dstPixels = new int[width * height];
       GraphicsUtilities.getPixels(src, 0, 0, width, height, srcPixels);
       for (int i = 0; i < iterations; i++) {
           // horizontal pass
           FastBlurFilter.blur(srcPixels, dstPixels, width, height, radius);
           // vertical pass
           FastBlurFilter.blur(dstPixels, srcPixels, height, width, radius);
       }
       // the result is now stored in srcPixels due to the 2nd pass
       GraphicsUtilities.setPixels(dst, 0, 0, width, height, srcPixels);
       return dst;
   }

} /*

* 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.
*/

/**

*

A fast blur filter can be used to blur pictures quickly. This filter is an * implementation of the box blur algorithm. The blurs generated by this * algorithm might show square artifacts, especially on pictures containing * straight lines (rectangles, text, etc.) On most pictures though, the * result will look very good.

*

The force of the blur can be controlled with a radius and the * default radius is 3. Since the blur clamps values on the edges of the * source picture, you might need to provide a picture with empty borders * to avoid artifacts at the edges. The performance of this filter are * independant from the radius.

*
* @author Romain Guy <romain.guy@mac.ru>
*/

class FastBlurFilter extends AbstractFilter {

   private final int radius;
   /**
*

Creates a new blur filter with a default radius of 3.

    */
   public FastBlurFilter() {
       this(3);
   }
   /**
*

Creates a new blur filter with the specified radius. If the radius * is lower than 1, a radius of 1 will be used automatically.

    *
    * @param radius the radius, in pixels, of the blur
    */
   public FastBlurFilter(int radius) {
       if (radius < 1) {
           radius = 1;
       }
       this.radius = radius;
   }
   /**
*

Returns the radius used by this filter, in pixels.

    *
    * @return the radius of the blur
    */
   public int getRadius() {
       return radius;
   }
   /**
    * {@inheritDoc}
    */
   @Override
   public BufferedImage filter(BufferedImage src, BufferedImage dst) {
       int width = src.getWidth();
       int height = src.getHeight();
       if (dst == null) {
           dst = createCompatibleDestImage(src, null);
       }
       int[] srcPixels = new int[width * height];
       int[] dstPixels = new int[width * height];
       GraphicsUtilities.getPixels(src, 0, 0, width, height, srcPixels);
       // horizontal pass
       blur(srcPixels, dstPixels, width, height, radius);
       // vertical pass
       blur(dstPixels, srcPixels, height, width, radius);
       // the result is now stored in srcPixels due to the 2nd pass
       GraphicsUtilities.setPixels(dst, 0, 0, width, height, srcPixels);
       return dst;
   }
   /**
*

Blurs the source pixels into the destination pixels. The force of * the blur is specified by the radius which must be greater than 0.

*

The source and destination pixels arrays are expected to be in the * INT_ARGB format.

    *
    * @param srcPixels the source pixels
    * @param dstPixels the destination pixels
    * @param width the width of the source picture
    * @param height the height of the source picture
    * @param radius the radius of the blur effect
    */
   static void blur(int[] srcPixels, int[] dstPixels,
                    int width, int height, int radius) {
       final int windowSize = radius * 2 + 1;
       final int radiusPlusOne = radius + 1;
       int sumAlpha;
       int sumRed;
       int sumGreen;
       int sumBlue;
       int srcIndex = 0;
       int dstIndex;
       int pixel;
       int[] sumLookupTable = new int[256 * windowSize];
       for (int i = 0; i < sumLookupTable.length; i++) {
           sumLookupTable[i] = i / windowSize;
       }
       int[] indexLookupTable = new int[radiusPlusOne];
       if (radius < width) {
           for (int i = 0; i < indexLookupTable.length; i++) {
               indexLookupTable[i] = i;
           }
       } else {
           for (int i = 0; i < width; i++) {
               indexLookupTable[i] = i;
           }
           for (int i = width; i < indexLookupTable.length; i++) {
               indexLookupTable[i] = width - 1;
           }
       }
       for (int y = 0; y < height; y++) {
           sumAlpha = sumRed = sumGreen = sumBlue = 0;
           dstIndex = y;
           pixel = srcPixels[srcIndex];
           sumAlpha += radiusPlusOne * ((pixel >> 24) & 0xFF);
           sumRed   += radiusPlusOne * ((pixel >> 16) & 0xFF);
           sumGreen += radiusPlusOne * ((pixel >>  8) & 0xFF);
           sumBlue  += radiusPlusOne * ( pixel        & 0xFF);
           for (int i = 1; i <= radius; i++) {
               pixel = srcPixels[srcIndex + indexLookupTable[i]];
               sumAlpha += (pixel >> 24) & 0xFF;
               sumRed   += (pixel >> 16) & 0xFF;
               sumGreen += (pixel >>  8) & 0xFF;
               sumBlue  +=  pixel        & 0xFF;
           }
           for  (int x = 0; x < width; x++) {
               dstPixels[dstIndex] = sumLookupTable[sumAlpha] << 24 |
                                     sumLookupTable[sumRed]   << 16 |
                                     sumLookupTable[sumGreen] <<  8 |
                                     sumLookupTable[sumBlue];
               dstIndex += height;
               int nextPixelIndex = x + radiusPlusOne;
               if (nextPixelIndex >= width) {
                   nextPixelIndex = width - 1;
               }
               int previousPixelIndex = x - radius;
               if (previousPixelIndex < 0) {
                   previousPixelIndex = 0;
               }
               int nextPixel = srcPixels[srcIndex + nextPixelIndex];
               int previousPixel = srcPixels[srcIndex + previousPixelIndex];
               sumAlpha += (nextPixel     >> 24) & 0xFF;
               sumAlpha -= (previousPixel >> 24) & 0xFF;
               sumRed += (nextPixel     >> 16) & 0xFF;
               sumRed -= (previousPixel >> 16) & 0xFF;
               sumGreen += (nextPixel     >> 8) & 0xFF;
               sumGreen -= (previousPixel >> 8) & 0xFF;
               sumBlue += nextPixel & 0xFF;
               sumBlue -= previousPixel & 0xFF;
           }
           srcIndex += width;
       }
   }

} /*

* 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.
*/

/**

*

Provides an abstract implementation of the BufferedImageOp * interface. This class can be used to created new image filters based * on BufferedImageOp.

*
* @author Romain Guy <romain.guy@mac.ru>
*/

abstract class AbstractFilter implements BufferedImageOp {

   public abstract BufferedImage filter(BufferedImage src, BufferedImage dest);
   /**
    * {@inheritDoc}
    */
   public Rectangle2D getBounds2D(BufferedImage src) {
       return new Rectangle(0, 0, src.getWidth(), src.getHeight());
   }
   /**
    * {@inheritDoc}
    */
   public BufferedImage createCompatibleDestImage(BufferedImage src,
                                                  ColorModel destCM) {
       if (destCM == null) {
           destCM = src.getColorModel();
       }
       return new BufferedImage(destCM,
                                destCM.createCompatibleWritableRaster(
                                        src.getWidth(), src.getHeight()),
                                destCM.isAlphaPremultiplied(), null);
   }
   /**
    * {@inheritDoc}
    */
   public Point2D getPoint2D(Point2D srcPt, Point2D dstPt) {
       return (Point2D) srcPt.clone();
   }
   /**
    * {@inheritDoc}
    */
   public RenderingHints getRenderingHints() {
       return null;
   }

}


</source>
   
  
 
  



Translucent Button

   <source lang="java">


import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; /*

* TranslucentButton.java
*
* Created on May 1, 2007, 3:54 PM
*
* Copyright (c) 2007, Sun Microsystems, Inc
* 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.
*/

/**

* 
* @author Chet
*/

public class TranslucentButton extends JButton {

 BufferedImage buttonImage = null;
 /** Creates a new instance of TranslucentButton */
 public TranslucentButton(String label) {
   super(label);
   setOpaque(false);
 }
 public void paint(Graphics g) {
   // Create an image for the button graphics if necessary
   if (buttonImage == null || buttonImage.getWidth() != getWidth()
       || buttonImage.getHeight() != getHeight()) {
     buttonImage = getGraphicsConfiguration().createCompatibleImage(getWidth(), getHeight());
   }
   Graphics gButton = buttonImage.getGraphics();
   gButton.setClip(g.getClip());
   // Have the superclass render the button for us
   super.paint(gButton);
   // Make the graphics object sent to this paint() method translucent
   Graphics2D g2d = (Graphics2D) g;
   AlphaComposite newComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .5f);
   g2d.setComposite(newComposite);
   // Copy the button"s image to the destination graphics, translucently
   g2d.drawImage(buttonImage, 0, 0, null);
 }
 private static void createAndShowGUI() {
   JFrame f = new JFrame();
   f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   f.setSize(300, 300);
   JPanel checkerboard = new Checkerboard();
   checkerboard.add(new TranslucentButton("Translucent Button"));
   f.add(checkerboard);
   f.setVisible(true);
 }
 public static void main(String args[]) {
   Runnable doCreateAndShowGUI = new Runnable() {
     public void run() {
       createAndShowGUI();
     }
   };
   SwingUtilities.invokeLater(doCreateAndShowGUI);
 }
 private static class Checkerboard extends JPanel {
   private static final int DIVISIONS = 10;
   static final int CHECKER_SIZE = 60;
   public void paintComponent(Graphics g) {
     g.setColor(Color.white);
     g.fillRect(0, 0, getWidth(), getHeight());
     g.setColor(Color.BLACK);
     for (int stripeX = 0; stripeX < getWidth(); stripeX += CHECKER_SIZE) {
       for (int y = 0, row = 0; y < getHeight(); y += CHECKER_SIZE / 2, ++row) {
         int x = (row % 2 == 0) ? stripeX : (stripeX + CHECKER_SIZE / 2);
         g.fillRect(x, y, CHECKER_SIZE / 2, CHECKER_SIZE / 2);
       }
     }
   }
 }

}

</source>
   
  
 
  



Translucent Panel

   <source lang="java">



/*

* 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.AlphaComposite; import java.awt.BorderLayout; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTable; import javax.swing.SwingUtilities; public class TranslucentPanel extends JPanel {

 BufferedImage image = null;
 @Override
 public void paint(Graphics g) {
   if (image == null || image.getWidth() != getWidth() || image.getHeight() != getHeight()) {
     image = (BufferedImage) createImage(getWidth(), getHeight());
   }
   Graphics2D g2 = image.createGraphics();
   g2.setClip(g.getClip());
   super.paint(g2);
   g2.dispose();
   g2 = (Graphics2D) g.create();
   g2.setComposite(AlphaComposite.SrcOver.derive(0.2f));
   g2.drawImage(image, 0, 0, null);
 }
 public static void main(String... args) {
   SwingUtilities.invokeLater(new Runnable() {
     public void run() {
       JFrame f = new JFrame("Translucent Panel");
       f.setContentPane(new TranslucentPanel());
       f.getContentPane().setLayout(new BorderLayout());
       Object[] names = new Object[] { "Title", "Artist", "Album" };
       String[][] data = new String[][] { { "Los Angeles", "Sugarcult", "Lights Out" },
           { "Do It Alone", "Sugarcult", "Lights Out" },
           { "Made a Mistake", "Sugarcult", "Lights Out" },
           { "Kiss You Better", "Maximo Park", "A Certain Trigger" },
           { "All Over the Shop", "Maximo Park", "A Certain Trigger" },
           { "Going Missing", "Maximo Park", "A Certain Trigger" } };
       JTable table = new JTable(data, names);
       f.add(table);
       JPanel p = new JPanel();
       p.add(new JButton("Play"));
       p.add(new JButton("Pause"));
       p.add(new JButton("Stop"));
       f.add(p, BorderLayout.SOUTH);
       f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       f.setSize(400, 300);
       f.setLocationRelativeTo(null);
       f.setVisible(true);
     }
   });
 }

}

</source>