Advanced Graphics Java

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.jdesktop.animation.timing.Animator;
import org.jdesktop.animation.transitions.Effect;
import org.jdesktop.animation.transitions.EffectsManager;
import org.jdesktop.animation.transitions.EffectsManager.TransitionType;
import org.jdesktop.animation.transitions.ScreenTransition;
import org.jdesktop.animation.transitions.TransitionTarget;
import org.jdesktop.animation.transitions.effects.CompositeEffect;
import org.jdesktop.animation.transitions.effects.Move;
import org.jdesktop.animation.transitions.effects.Scale;
//import org.jdesktop.tools.io.FileTreeWalk;
//import org.jdesktop.tools.io.FileTreeWalker;
//import org.jdesktop.tools.io.UnixGlobFileFilter;
import java.io.FileFilter;
import java.io.File;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
/*
 * ImageBrowser.java
 *
 * Created on May 3, 2007, 3: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.
 */
/**
 * This demo of the AnimatedTransitions library uses a layout manager
 * to assist in setting up the next screen that the application
 * transitions to.
 *
 * The slider in the window controls the picture thumbnail size. The
 * standard FlowLayout manager organizes the pictures according to
 * the thumbnail sizes. The transition animates the change from
 * one thumbnail size to the next.
 *
 * @author Chet
 */
public class ImageBrowser extends JComponent 
        implements TransitionTarget, ChangeListener {
    
    private static final int SLIDER_INCREMENT = 50;
    int numPictures = 40;
    JLabel label[];
    Animator animator = new Animator(500);
    ScreenTransition transition = new ScreenTransition(this, this, animator);
    Dimension newSize = new Dimension();
    List images = new ArrayList();
    static int currentSize = 50;
    GradientPaint bgGradient = null;
    int prevHeight = 0;
    static JSlider slider = new JSlider(1, 400 / SLIDER_INCREMENT, 
            1 + currentSize / SLIDER_INCREMENT);
    static int numImages = 0;
    
    /** Creates a new instance of ImageBrowser */
    public ImageBrowser() {
        setOpaque(true);
        animator.setAcceleration(.1f);
        animator.setDeceleration(.4f);
        setLayout(new FlowLayout());
        loadImages();
        label = new JLabel[images.size()];
        // For each image:
        // - set the icon at the current thumbnail size
        // - create/set a custom effect that will move/scale the
        // images. Note that the main reason for the custom effect
        // is that scaling effects typically redraw the actual component
        // instead of using image tricks. In this case, image tricks are
        // just fine. So the custom effect is purely an optimization here.
        for (int i = 0; i < images.size(); ++i) {
            label[i] = new JLabel();
            label[i].setIcon(new ImageIcon(images.get(i).getImage(currentSize)));
            add(label[i]);
            Effect move = new Move();
            Effect scale = new Scale();
            CompositeEffect comp = new CompositeEffect(move);
            comp.addEffect(scale);
            comp.setRenderComponent(false);
            EffectsManager.setEffect(label[i], comp, TransitionType.CHANGING);
        }
    }
    /**
     * Paints a gradient in the background of this component
     */
    @Override
    protected void paintComponent(Graphics g) {
        if (getHeight() != prevHeight) {
            prevHeight = getHeight();
            bgGradient = new GradientPaint(0, 0, 
                    new Color(0xEBF4FA), 0, prevHeight, new Color(0xBBD9EE));
        }
        ((Graphics2D)g).setPaint(bgGradient);
        g.fillRect(0, 0, getWidth(), prevHeight);
    }
    
    /**
     * Loads all images found in the directory "images" (which therefore must
     * be found in the folder in which this app runs).
     */
    private void loadImages() {
        //try {
            //File imagesDir = new File("images");
            //FileTreeWalker walker = new FileTreeWalker(imagesDir, 
              //      new UnixGlobFileFilter("*.jpg"));
            //walker.walk(new FileTreeWalk() {
              //  public void walk(File path) {
                    //numImages++;
                    try {
                        BufferedImage image = ImageIO.read(ImageBrowser.class.getResource("shanghai.jpg"));
                        images.add(new ImageHolder(image));
                    } catch (Exception e) {
                        System.out.println("Problem loading images: " + e);
                    }
                //}
            //});
        //} catch (Exception e) {
          //  System.out.println("Problem loading images: " + e);
        //}
    }
        
    /**
     * TransitionTarget implementation: The setup for the next screen entails
     * merely assigning a new icon to each JLabel with the new thumbnail
     * size
     */
    public void setupNextScreen() {
        for (int i = 0; i < images.size(); ++i) {
            label[i].setIcon(new ImageIcon(images.get(i).getImage(currentSize)));
        }
        // revalidation is necessary for the LayoutManager to do its job
        revalidate();
    }
    
    /**
     * This method handles changes in slider state, which can come from either
     * mouse manipulation of the slider or right/left keyboard events. This
     * event changes the current thumbnail size and starts the transition.
     * We will then receive a callback to setupNextScreen() where we set up
     * the GUI according to this new thumbnail size.
     */
    public void stateChanged(ChangeEvent ce) {
        currentSize = slider.getValue() * 25;
        if (!transition.getAnimator().isRunning()) {
            transition.start();
        }
    }
    
    private static void createAndShowGUI() {
  JFrame f = new JFrame("Image Browser");
        f.setLayout(new BorderLayout());
  f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  f.setSize(500, 400);
  ImageBrowser component = new ImageBrowser();
  f.add(component, BorderLayout.CENTER);
        f.add(slider, BorderLayout.SOUTH);
        slider.setBackground(new Color(0xBBD9EE));
        slider.addChangeListener(component);
  f.setVisible(true);
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        } catch (InstantiationException ex) {
            ex.printStackTrace();
        } catch (IllegalAccessException ex) {
            ex.printStackTrace();
        } catch (UnsupportedLookAndFeelException ex) {
            ex.printStackTrace();
        }
  Runnable doCreateAndShowGUI = new Runnable() {
      public void run() {
    createAndShowGUI();
      }
  };
  SwingUtilities.invokeLater(doCreateAndShowGUI);
    }
}
/**
 * This is a utility class that holds our images at various scaled
 * sizes. The images are pre-scaled down by halves, using the progressive
 * bilinear technique. Thumbnails from these images are requested
 * from this class, which are created by down-scaling from the next-largest
 * pre-scaled size available.
 */
class ImageHolder {
    private List scaledImages = new ArrayList();
    private static final int MIN_SIZE = 50;
   
    /**
     * Given any image, this constructor creates and stores down-scaled
     * versions of this image down to some MIN_SIZE
     */
    ImageHolder(BufferedImage originalImage) {
        int imageW = originalImage.getWidth();
        int imageH = originalImage.getHeight();
        scaledImages.add(originalImage);
        BufferedImage prevImage = originalImage;
        while (imageW > MIN_SIZE && imageH > MIN_SIZE) {
            imageW = imageW >> 1;
            imageH = imageH >> 1;
            BufferedImage scaledImage = new BufferedImage(imageW, imageH,
                    prevImage.getType());
            Graphics2D g2d = scaledImage.createGraphics();
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2d.drawImage(prevImage, 0, 0, imageW, imageH, null);
            g2d.dispose();
            scaledImages.add(scaledImage);
        }
    }
    
    /**
     * This method returns an image with the specified width. It finds
     * the pre-scaled size with the closest/larger width and scales
     * down from it, to provide a fast and high-quality scaed version
     * at the requested size.
     */
    BufferedImage getImage(int width) {
        for (BufferedImage scaledImage : scaledImages) {
            int scaledW = scaledImage.getWidth();
            // This is the one to scale from if:
            // - the requested size is larger than this size
            // - the requested size is between this size and 
            //   the next size down
            // - this is the smallest (last) size
            if (scaledW < width || ((scaledW >> 1) < width) ||
                    (scaledW >> 1) < MIN_SIZE) {
                if (scaledW != width) {
                    // Create new version scaled to this width
                    // Set the width at this width, scale the
                    // height proportional to the image width
                    float scaleFactor = (float)width / scaledW;
                    int scaledH = (int)(scaledImage.getHeight() * 
                            scaleFactor + .5f);
                    BufferedImage image = new BufferedImage(width,
                            scaledH, scaledImage.getType());
                    Graphics2D g2d = image.createGraphics();
                    g2d.setRenderingHint(
                            RenderingHints.KEY_INTERPOLATION,
                            RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                    g2d.drawImage(scaledImage, 0, 0, 
                            width, scaledH, null);
                    g2d.dispose();
                    scaledImage = image;
                }
                return scaledImage;
            }
        }
        // shouldn't get here
        return null;
    }
}
/**
 * Copyright (c) 2006, 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 Harvester 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.
 */
class UnixGlobFileFilter implements FileFilter {
    private Pattern pattern;
    public UnixGlobFileFilter(String filter) {
        pattern = Pattern.compile(globToRegex(filter));
    }
    public boolean accept(File file) {
        String path = file.getName();
        Matcher matcher = pattern.matcher(path);
        return matcher.matches();
    }
    private String globToRegex(String glob) {
        char c = '\0';
        boolean escape = false;
        boolean enclosed = false;
        StringBuffer buffer = new StringBuffer(glob.length());
        for (int i = 0; i < glob.length(); i++) {
            c = glob.charAt(i);
            if (escape) {
                buffer.append('\\');
                buffer.append(c);
                escape = false;
                continue;
            }
            switch (c) {
                case '*':
                    buffer.append('.').append('*');
                    break;
                case '?':
                    buffer.append('.');
                    break;
                case '\\':
                    escape = true;
                    break;
                case '.':
                    buffer.append('\\').append('.');
                    break;
                case '{':
                    buffer.append('(');
                    enclosed = true;
                    break;
                case '}':
                    buffer.append(')');
                    enclosed = false;
                    break;
                case ',':
                    if (enclosed)
                        buffer.append('|');
                    else
                        buffer.append(',');
                    break;
                default:
                    buffer.append(c);
            }
        }
        return buffer.toString();
    }
}
/**
 * Copyright (c) 2006, 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 Harvester 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.
 */
class FileTreeWalker {
    private File path;
    private static final FileFilter directoryFilter = new FileFilter() {
        public boolean accept(File pathname) {
            return pathname.isDirectory();
        }
    };
    private FileFilter filter;
    public FileTreeWalker(File path) throws IOException {
        this(path, new FileFilter() {
            public boolean accept(File pathname) {
                return pathname.isFile();
            }
        });
    }
    public FileTreeWalker(File path, FileFilter filter) throws IOException {
        if (path == null || !path.exists() || path.isFile()) {
            throw new IOException("Path " + path + " is not a valid directory.");
        }
        this.path = path;
        this.filter = filter;
    }
    public void walk(FileTreeWalk walk) {
        walkDirectory(walk, path);
    }
    private void walkDirectory(FileTreeWalk walk, File dir) {
        File[] files = dir.listFiles(filter);
        for (File file : files) {
            walk.walk(file);
        }
        File[] dirs = dir.listFiles(directoryFilter);
        for (File subDir : dirs) {
            walkDirectory(walk, subDir);
        }
    }
}
/**
 * Copyright (c) 2006, 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 Harvester 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.
 */
interface FileTreeWalk {
    public void walk(File path);
}
           
         
    
  
Filthy-Rich-Clients-ImageZooming.zip( 228 k)