JXImagePanel.java
上传用户:zhengdagz
上传日期:2014-03-06
资源大小:1956k
文件大小:10k
源码类别:

xml/soap/webservice

开发平台:

Java

  1. /*
  2.  * $Id: JXImagePanel.java,v 1.8 2005/10/10 18:01:45 rbair Exp $
  3.  *
  4.  * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
  5.  * Santa Clara, California 95054, U.S.A. All rights reserved.
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  * 
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  * 
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  20.  */
  21. package org.jdesktop.swingx;
  22. import java.awt.Cursor;
  23. import java.awt.Dimension;
  24. import java.awt.Graphics;
  25. import java.awt.Graphics2D;
  26. import java.awt.Image;
  27. import java.awt.Rectangle;
  28. import java.awt.event.MouseAdapter;
  29. import java.awt.event.MouseEvent;
  30. import java.awt.image.BufferedImage;
  31. import java.io.File;
  32. import java.net.URL;
  33. import javax.swing.ImageIcon;
  34. import javax.swing.JFileChooser;
  35. import javax.swing.JLabel;
  36. import javax.swing.SwingUtilities;
  37. import static org.jdesktop.swingx.JXImagePanel.Style.CENTERED;
  38. import static org.jdesktop.swingx.JXImagePanel.Style.SCALED;
  39. import static org.jdesktop.swingx.JXImagePanel.Style.TILED;
  40. /**
  41.  * <p>A panel that draws an image. The standard (and currently only supported)
  42.  * mode is to draw the specified image starting at position 0,0 in the
  43.  * panel. The component&amp;s preferred size is based on the image, unless
  44.  * explicitly set by the user.</p>
  45.  *
  46.  * <p>In the future, the JXImagePanel will also support tiling of images,
  47.  * scaling, resizing, cropping, segways etc.</p>
  48.  *
  49.  * <p>This component also supports allowing the user to set the image. If the
  50.  * <code>JXImagePanel</code> is editable, then when the user clicks on the
  51.  * <code>JXImagePanel</code> a FileChooser is shown allowing the user to pick
  52.  * some other image to use within the <code>JXImagePanel</code>.</p>
  53.  *
  54.  * <p>Images to be displayed can be set based on URL, Image, etc.
  55.  *
  56.  * @author unattributed, rbair
  57.  */
  58. public class JXImagePanel extends JXPanel {
  59.     public static enum Style {CENTERED, TILED, SCALED};
  60.     
  61.     /**
  62.      * Text informing the user that clicking on this component will allow them to set the image
  63.      */
  64.     private static final String TEXT = "<html><i><b>Click here<br>to set the image</b></i></html>";
  65.     /**
  66.      * The image to draw
  67.      */
  68.     private BufferedImage img;
  69.     /**
  70.      * If true, then the image can be changed. Perhaps a better name is
  71.      * &quot;readOnly&quot;, but editable was chosen to be more consistent
  72.      * with other Swing components.
  73.      */
  74.     private boolean editable = false;
  75.     /**
  76.      * The mouse handler that is used if the component is editable
  77.      */
  78.     private MouseHandler mhandler = new MouseHandler();
  79.     /**
  80.      * If not null, then the user has explicitly set the preferred size of
  81.      * this component, and this should be honored
  82.      */
  83.     private Dimension preferredSize;
  84.     /**
  85.      * Specifies how to draw the image, i.e. what kind of Style to use
  86.      * when drawing
  87.      */
  88.     private Style style = Style.CENTERED;
  89.     
  90.     public JXImagePanel() {
  91.     }
  92.     
  93.     public JXImagePanel(URL imageUrl) {
  94.         try {
  95.             setImage((BufferedImage)new ImageIcon(imageUrl).getImage());
  96.         } catch (Exception e) {
  97.             //TODO need to log
  98.             e.printStackTrace();
  99.         }
  100.     }
  101.     
  102.     /**
  103.      * Sets the image to use for the background of this panel. This image is
  104.      * painted whether the panel is opaque or translucent.
  105.      * @param image if null, clears the image. Otherwise, this will set the
  106.      * image to be painted. If the preferred size has not been explicitly set,
  107.      * then the image dimensions will alter the preferred size of the panel.
  108.      */
  109.     public void setImage(BufferedImage image) {
  110.         if (image != img) {
  111.             BufferedImage oldImage = img;
  112.             img = image;
  113.             firePropertyChange("icon", oldImage, img);
  114.             invalidate();
  115.             repaint();
  116.         }
  117.     }
  118.     
  119.     /**
  120.      * @return the image used for painting the background of this panel
  121.      */
  122.     public BufferedImage getImage() {
  123.         return img;
  124.     }
  125.     
  126.     /**
  127.      * @param editable
  128.      */
  129.     public void setEditable(boolean editable) {
  130.         if (editable != this.editable) {
  131.             //if it was editable, remove the mouse handler
  132.             if (this.editable) {
  133.                 removeMouseListener(mhandler);
  134.             }
  135.             this.editable = editable;
  136.             //if it is now editable, add the mouse handler
  137.             if (this.editable) {
  138.                 addMouseListener(new MouseHandler());
  139.             }
  140.             setToolTipText(editable ? TEXT : "");
  141.             firePropertyChange("editable", !editable, editable);
  142.             repaint();
  143.         }
  144.     }
  145.     
  146.     /**
  147.      * @return whether the image for this panel can be changed or not via
  148.      * the UI. setImage may still be called, even if <code>isEditable</code>
  149.      * returns false.
  150.      */
  151.     public boolean isEditable() {
  152.         return editable;
  153.     }
  154.     
  155.     /**
  156.      * Sets what style to use when painting the image
  157.      *
  158.      * @param s
  159.      */
  160.     public void setStyle(Style s) {
  161.         if (style != s) {
  162.             Style oldStyle = style;
  163.             style = s;
  164.             firePropertyChange("style", oldStyle, s);
  165.             repaint();
  166.         }
  167.     }
  168.     /**
  169.      * @return the Style used for drawing the image (CENTERED, TILED, etc).
  170.      */
  171.     public Style getStyle() {
  172.         return style;
  173.     }
  174.     
  175.     public void setPreferredSize(Dimension pref) {
  176.         preferredSize = pref;
  177.         super.setPreferredSize(pref);
  178.     }
  179.     
  180.     public Dimension getPreferredSize() {
  181.         if (preferredSize == null && img != null) {
  182.             //it has not been explicitly set, so return the width/height of the image
  183.             return new Dimension(img.getWidth(), img.getHeight());
  184.         } else {
  185.             return super.getPreferredSize();
  186.         }
  187.     }
  188.     
  189.     /**
  190.      * Overriden to paint the image on the panel
  191.      */
  192.     protected void paintComponent(Graphics g) {
  193.         super.paintComponent(g);
  194. //        Insets insets = getInsets();
  195. //        g.fillRect(insets.left, insets.top, getWidth() - insets.right - insets.left, getHeight() - insets.bottom - insets.top);
  196.         Graphics2D g2 = (Graphics2D)g;
  197.         if (img != null) {
  198.             switch (style) {
  199.                 case CENTERED:
  200.                     Rectangle clipRect = g2.getClipBounds();
  201.                     int imageX = (getWidth() - img.getWidth()) / 2;
  202.                     int imageY = (getHeight() - img.getHeight()) / 2;
  203.                     Rectangle r = SwingUtilities.computeIntersection(imageX, imageY, img.getWidth(), img.getHeight(), clipRect);
  204.                     if (r.x == 0 && r.y == 0 && (r.width == 0 || r.height == 0)) {
  205.                         return;
  206.                     }
  207.                     //I have my new clipping rectangle "r" in clipRect space.
  208.                     //It is therefore the new clipRect.
  209.                     clipRect = r;
  210.                     //since I have the intersection, all I need to do is adjust the
  211.                     //x & y values for the image
  212.                     int txClipX = clipRect.x - imageX;
  213.                     int txClipY = clipRect.y - imageY;
  214.                     int txClipW = clipRect.width;
  215.                     int txClipH = clipRect.height;
  216.                     
  217.                     g2.drawImage(img, clipRect.x, clipRect.y, clipRect.x + clipRect.width, clipRect.y + clipRect.height,
  218.                             txClipX, txClipY, txClipX + txClipW, txClipY + txClipH, null);
  219.                     break;
  220.                 case TILED:
  221.                 case SCALED:
  222.                     Image temp = img.getScaledInstance(getWidth(), getHeight(), BufferedImage.SCALE_SMOOTH);
  223.                     g2.drawImage(temp, (getWidth() - temp.getWidth(null)) / 2,
  224.                             (getHeight() - temp.getHeight(null)) / 2, null);
  225.                     break;
  226.                 default:
  227.                     System.err.println("unimplemented");
  228.                     g2.drawImage(img, null, 0, 0);
  229.                     break;
  230.             }
  231.         }
  232.     }
  233.     
  234.     /**
  235.      * Handles click events on the component
  236.      */
  237.     private class MouseHandler extends MouseAdapter {
  238.         private Cursor oldCursor;
  239.         private JFileChooser chooser;
  240.         
  241.         public void mouseClicked(MouseEvent evt) {
  242.             if (chooser == null) {
  243.                 chooser = new JFileChooser();
  244.             }
  245.             int retVal = chooser.showOpenDialog(JXImagePanel.this);
  246.             if (retVal == JFileChooser.APPROVE_OPTION) {
  247.                 File file = chooser.getSelectedFile();
  248.                 try {
  249.                     setImage((BufferedImage)new ImageIcon(file.toURL()).getImage());
  250.                 } catch (Exception ex) {
  251.                 }
  252.             }
  253.         }
  254.         
  255.         public void mouseEntered(MouseEvent evt) {
  256.             JLabel label = (JLabel)evt.getSource();
  257.             if (oldCursor == null) {
  258.                 oldCursor = label.getCursor();
  259.                 label.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
  260.             }
  261.         }
  262.         
  263.         public void mouseExited(MouseEvent evt) {
  264.             JLabel label = (JLabel)evt.getSource();
  265.             if (oldCursor != null) {
  266.                 label.setCursor(oldCursor);
  267.                 oldCursor = null;
  268.             }
  269.         }
  270.     }
  271. }