JImagePanel.java :  » Rule-Engine » zilonis » org » zilonis » tool » ext » mailman » ui » Java Open Source

Java Open Source » Rule Engine » zilonis 
zilonis » org » zilonis » tool » ext » mailman » ui » JImagePanel.java
/**
 * 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 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.
 */

package org.zilonis.tool.ext.mailman.ui;

import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.TooManyListenersException;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.filechooser.FileNameExtensionFilter;

/**
 *
 * @author sky
 */
public class JImagePanel extends JPanel {
    private boolean showHintOnEmptyImage;
    private Image image;
    private URI imagePath;
    private boolean editable;
    private Image cachedImage;
    private Image dragImage;

    static {
        UIManager.getDefaults().addResourceBundle("passwordstore.swingx.resources.strings");
    }
    
    public JImagePanel() {
        setBackground(Color.WHITE);
        setOpaque(true);
        showHintOnEmptyImage = true;
        updateHintIfNecessary();
    }
    
    public void setShowHintOnEmptyImage(boolean value) {
        boolean oldValue = showHintOnEmptyImage;
        showHintOnEmptyImage = value;
        firePropertyChange("showHintOnEmptyImage", oldValue, value);
    }
    
    public boolean getShowHintOnEmptyImage() {
        return showHintOnEmptyImage;
    }
    
    public void setEditable(boolean editable) {
        if (editable != this.editable) {
            this.editable = editable;
            if (editable) {
                setDropTarget(new DropTarget());
                try {
                    getDropTarget().addDropTargetListener(new DropTargetHandler());
                } catch (TooManyListenersException ex) {
                }
                enableEvents(MouseEvent.MOUSE_EVENT_MASK);
            } else {
                setDropTarget(null);
            }
            updateHintIfNecessary();
            firePropertyChange("editable", !editable, editable);
        }
    }
    
    public boolean isEditable() {
        return editable;
    }
    
    public final void setImage(Image image) {
        setImage0(image);
        setImagePath0(null);
    }
    
    private void setImage0(Image image) {
        Image oldImage = this.image;
        this.image = image;
        clearCachedImage();
        firePropertyChange("image", oldImage, image);
        revalidate();
        repaint();
        updateHintIfNecessary();
    }
    
    public final Image getImage() {
        return image;
    }
    
    protected void setDragImage(Image image) {
        Image oldImage = this.dragImage;
        this.dragImage = image;
        clearCachedImage();
        updateHintIfNecessary();
        firePropertyChange("dragImage", oldImage, image);
    }
    
    protected Image getDragImage() {
        return dragImage;
    }
    
    public final void setImagePath(URI path) {
        if (path == null) {
            setImage0(null);
        } else {
            setImage0(ImageCache.getInstance().getImage(this, path, 0, 0));
        }
        setImagePath0(path);
    }
    
    private void setImagePath0(URI path) {
        URI oldPath = this.imagePath;
        this.imagePath = path;
        firePropertyChange("imagePath", oldPath, imagePath);
    }
    
    public final URI getImagePath() {
        return imagePath;
    }
    
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Image image = getImageToDraw();
        if (image != null) {
            Point loc = getImageLocation();
            g.drawImage(image, loc.x, loc.y, this);
        }
    }
    
    private Image getImageToDraw() {
        if (cachedImage == null) {
            cachedImage = createCachedImage();
        }
        return cachedImage;
    }
    
    private Image createCachedImage() {
        Image image = getDragImage();
        boolean isDrag = true;
        if (image == null) {
            image = getImage();
            isDrag = false;
        }
        if (image != null) {
            int iw = image.getWidth(this);
            int ih = image.getHeight(this);
            if (iw > 0 && ih > 0) {
                Insets insets = getInsets();
                int w = getWidth() - insets.left - insets.right;
                int h = getHeight() - insets.top - insets.bottom;
                float aspectRatio = (float)image.getWidth(this) /
                        (float)image.getHeight(this);
                int targetWidth;
                int targetHeight;
                if (iw > ih) {
                    targetWidth = w;
                    targetHeight = (int)(targetWidth / aspectRatio);
                    if (targetHeight > h) {
                        targetHeight = h;
                        targetWidth = (int)(aspectRatio * targetHeight);
                    }
                } else {
                    targetHeight = h;
                    targetWidth = (int)(aspectRatio * targetHeight);
                    if (targetWidth > w) {
                        targetWidth = w;
                        targetHeight = (int)(targetWidth / aspectRatio);
                    }
                }
                if (targetWidth != iw || targetHeight != ih) {
                    Image cachedImage;
                    if (isDrag) {
                        if (getGraphicsConfiguration() != null) {
                            cachedImage = getGraphicsConfiguration().
                                    createCompatibleImage(targetWidth, targetHeight,
                                    Transparency.TRANSLUCENT);
                        } else {
                            cachedImage = new BufferedImage(targetWidth,
                                    targetHeight, BufferedImage.TYPE_INT_ARGB);
                        }
                        Graphics imageG = cachedImage.getGraphics();
                        if (imageG instanceof Graphics2D) {
                            ((Graphics2D)imageG).setComposite(AlphaComposite.
                                    getInstance(AlphaComposite.SRC_OVER, .3f));
                            ((Graphics2D)imageG).setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                                    RenderingHints.VALUE_INTERPOLATION_BICUBIC);
                        }
                        imageG.drawImage(image, 0, 0, targetWidth, targetHeight,
                                0, 0, iw, ih, this);
                        imageG.dispose();
                    } else {
                        cachedImage = ImageCache.getInstance().getImage(this, 
                                image, targetWidth, targetHeight);
                    }
                    return cachedImage;
                }
                return image;
            }
        }
        return null;
    }
    
    private Point getImageLocation() {
        Image image = getImageToDraw();
        Insets insets = getInsets();
        int w = getWidth() - insets.left - insets.right;
        int h = getHeight() - insets.top - insets.bottom;
        int iw = image.getWidth(this);
        int ih = image.getHeight(this);
        return new Point(insets.left + (w - iw) / 2,
                insets.top + (h - ih) / 2);
    }
    
    private void clearCachedImage() {
        cachedImage = null;
        repaint();
    }
    
    public void reshape(int x, int y, int w, int h) {
        super.reshape(x, y, w, h);
        clearCachedImage();
    }
    
    public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h) {
        if (img == getImage()) {
            return super.imageUpdate(img, infoflags, x, y, w, h);
        }
        return false;
    }
    
    public void setBorder(Border border) {
        super.setBorder(border);
        clearCachedImage();
    }
    
    protected void showChooser() {
        JFileChooser chooser = new JFileChooser();
        chooser.addChoosableFileFilter(new FileNameExtensionFilter(
                "image", "jpg", "gif", "jpeg", "png"));
        URI imageURI = getImagePath();
        if (imageURI != null && imageURI.getScheme().equals("file")) {
            chooser.setSelectedFile(new File(imageURI));
        }
        chooser.setMultiSelectionEnabled(false);
        if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
            File file = chooser.getSelectedFile();
            URI uri = file.toURI();
            setImagePath(uri);
        }
    }
    
    protected void processMouseEvent(MouseEvent e) {
        super.processMouseEvent(e);
        if (!e.isConsumed() && e.getClickCount() == 1) {
            showChooser();
        }
    }

    private void updateHintIfNecessary() {
        Component hint = getHintComponent();
        if (getImage() == null && getDragImage() == null &&
                getShowHintOnEmptyImage() && isEditable()) {
            if (hint == null) {
                hint = createHintComponent();
                setLayout(new BorderLayout());
            }
            add(hint, BorderLayout.SOUTH);
            revalidate();
            repaint();
        } else if (hint != null) {
            remove(hint);
            revalidate();
            repaint();
        }
    }
    
    private Component getHintComponent() {
        if (getComponentCount() > 0) {
            return getComponent(0);
        }
        return null;
    }

    private Component createHintComponent() {
        // PENDING: this is a hack, should be a text area or something that
        // can wrap
        JLabel label = new JLabel(getLabelText());
        label.setHorizontalAlignment(JLabel.CENTER);
        label.setForeground(Color.LIGHT_GRAY);
        label.setBorder(new EmptyBorder(4, 4, 4, 4));
        return label;
    }
    
    private String getLabelText() {
        String text = UIManager.getString("ImagePanel.clickText");
        if (text == null) {
            text = "Click or Drop to Set";
        }
        return text;
    }
    
    
    private class DropTargetHandler implements ActionListener,
            DropTargetListener {
        private URI dragURI;
        private Timer dragTimer;
        private boolean validDragImage;
        
        public void dragEnter(DropTargetDragEvent e) {
            dragURI = null;
            stopTimer();
            validDragImage = false;
            if (e.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
                try {
                    List<File>files = (List<File>) e.getTransferable().
                            getTransferData(DataFlavor.javaFileListFlavor);
                    if (files.size() == 1) {
                        File file = files.get(0);
                        dragURI = file.getCanonicalFile().toURI();
                        updateDragImage();
                    }
                } catch (IOException ex) {
                } catch (UnsupportedFlavorException ex) {
                }
            }
        }
        
        public void dragOver(DropTargetDragEvent e) {
        }
        
        public void dropActionChanged(DropTargetDragEvent e) {
        }
        
        public void dragExit(DropTargetEvent e) {
            setDragImage(null);
            stopTimer();
        }
        
        public void drop(DropTargetDropEvent e) {
            if (dragURI != null && !validDragImage) {
                updateDragImage();
            }
            boolean accepted = false;
            if (validDragImage) {
                setImage0(getDragImage());
                setDragImage(null);
                setImagePath0(dragURI);
                accepted = true;
            }
            if (accepted) {
                e.acceptDrop(DnDConstants.ACTION_COPY);
            } else {
                e.rejectDrop();
            }
        }
        
        public void actionPerformed(ActionEvent e) {
            updateDragImage();
        }
        
        private void updateDragImage() {
            File file = new File(dragURI);
            if (file.length() > 0) {
                try {
                    ImageIcon icon = new ImageIcon(dragURI.toURL());
                    Image image = icon.getImage();
                    if (image.getWidth(JImagePanel.this) > 0) {
                        stopTimer();
                        setDragImage(image);
                        validDragImage = true;
                    } else if (dragTimer == null) {
                        startTimer();
                    }
                } catch (MalformedURLException ex) {
                    validDragImage = true;
                    stopTimer();
                }
            } else if (dragTimer == null) {
                startTimer();
            }
        }
        
        private void startTimer() {
            dragTimer = new Timer(50, this);
            dragTimer.setRepeats(true);
            dragTimer.start();
        }
        
        private void stopTimer() {
            if (dragTimer != null) {
                dragTimer.stop();
                dragTimer = null;
            }
        }
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.