Coverage Report - wjhk.jupload2.gui.image.PicturePanel
 
Classes in this File Line Coverage Branch Coverage Complexity
PicturePanel
0 %
0/78
0 %
0/26
1,933
 
 1  
 //
 2  
 // $Id: PicturePanel.java 95 2007-05-02 03:27:05 +0000 (mer., 02 mai 2007)
 3  
 // /C=DE/ST=Baden-Wuerttemberg/O=ISDN4Linux/OU=Fritz
 4  
 // Elfert/CN=svn-felfert@isdn4linux.de/emailAddress=fritz@fritz-elfert.de $
 5  
 //
 6  
 // jupload - A file upload applet.
 7  
 // Copyright 2007 The JUpload Team
 8  
 // Copyright 2002 Guillaume Chamberland-Larose
 9  
 //
 10  
 // Created: ?
 11  
 // Creator: William JinHua Kwong
 12  
 // Last modified: $Date: 2011-01-19 16:16:33 +0100 (mer., 19 janv. 2011) $
 13  
 //
 14  
 // This program is free software; you can redistribute it and/or modify it under
 15  
 // the terms of the GNU General Public License as published by the Free Software
 16  
 // Foundation; either version 2 of the License, or (at your option) any later
 17  
 // version. This program is distributed in the hope that it will be useful, but
 18  
 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 19  
 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 20  
 // details. You should have received a copy of the GNU General Public License
 21  
 // along with this program; if not, write to the Free Software Foundation, Inc.,
 22  
 // 675 Mass Ave, Cambridge, MA 02139, USA.
 23  
 
 24  
 package wjhk.jupload2.gui.image;
 25  
 
 26  
 import java.awt.Canvas;
 27  
 import java.awt.Cursor;
 28  
 import java.awt.Graphics;
 29  
 import java.awt.Image;
 30  
 import java.awt.event.ComponentEvent;
 31  
 import java.awt.event.ComponentListener;
 32  
 import java.awt.event.MouseEvent;
 33  
 import java.awt.event.MouseListener;
 34  
 
 35  
 import javax.swing.AbstractButton;
 36  
 
 37  
 import wjhk.jupload2.exception.JUploadException;
 38  
 import wjhk.jupload2.filedata.PictureFileData;
 39  
 import wjhk.jupload2.policies.UploadPolicy;
 40  
 
 41  
 /**
 42  
  * This panel is used to preview picture, when PictureUploadPolicy (or one of
 43  
  * its inherited policy) is used. Manages the panel where pictures are
 44  
  * displayed. <BR>
 45  
  * Each time a user selects a file in the panel file, the PictureUploadPolicy
 46  
  * calls
 47  
  * {@link #setPictureFile(PictureFileData, AbstractButton, AbstractButton)}. I
 48  
  * did an attempt to store the Image generated for the Panel size into the
 49  
  * PictureFileData, to avoid to calculate the offscreenPicture each time the
 50  
  * user select the same file again. But it doesn't work: the applet quickly runs
 51  
  * out of memory, even after numerous calls of System.gc and finalize. <BR>
 52  
  * <BR>
 53  
  * This file is taken from the PictureApplet ((C) 2002 Guillaume
 54  
  * Chamberland-Larose), available here: To contact Guillaume Chamberland-Larose
 55  
  * for bugs, patches, suggestions: Please use the forums on the sourceforge web
 56  
  * page for this project, located at:
 57  
  * http://sourceforge.net/projects/picture-applet/ Updated : 2006 etienne_sf<BR>
 58  
  * This program is free software; you can redistribute it and/or modify it under
 59  
  * the terms of the GNU General Public License as published by the Free Software
 60  
  * Foundation; either version 2 of the License, or (at your option) any later
 61  
  * version. <BR>
 62  
  * This program is distributed in the hope that it will be useful, but WITHOUT
 63  
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 64  
  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 65  
  * details. <BR>
 66  
  * You should have received a copy of the GNU General Public License along with
 67  
  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 68  
  * Place - Suite 330, Boston, MA 02111-1307, USA.
 69  
  */
 70  
 
 71  
 public class PicturePanel extends Canvas implements MouseListener,
 72  
         ComponentListener {
 73  
 
 74  
     /** A generated serialVersionUID, to avoid warning during compilation */
 75  
     private static final long serialVersionUID = -3439340009940699981L;
 76  
 
 77  
     private PictureFileData pictureFileData;
 78  
 
 79  
     /**
 80  
      * offscreenImage contains an image, that can be asked by
 81  
      * {@link PictureFileData#getImage(Canvas, boolean)}. It is used to preview
 82  
      * this picture.
 83  
      */
 84  0
     private Image offscreenImage = null;
 85  
 
 86  
     /**
 87  
      * Indicates if the offscreen image should be calculated once and stored, to
 88  
      * avoid to calculate it again. <BR>
 89  
      * Indications: the offscreen image should be calculate only once for the
 90  
      * picturePanel on the applet, and for each display when the user ask to
 91  
      * display the fulscreen picture (by a click on the picturePanel).
 92  
      */
 93  0
     private boolean hasToStoreOffscreenPicture = false;
 94  
 
 95  
     /**
 96  
      * The current upload policy.
 97  
      */
 98  
     protected UploadPolicy uploadPolicy;
 99  
 
 100  
     /**
 101  
      * Standard constructor.
 102  
      * 
 103  
      * @param hasToStoreOffscreenPicture
 104  
      * @param uploadPolicy The current upload policy
 105  
      */
 106  
     public PicturePanel(boolean hasToStoreOffscreenPicture,
 107  
             UploadPolicy uploadPolicy) {
 108  0
         super();
 109  
 
 110  0
         this.hasToStoreOffscreenPicture = hasToStoreOffscreenPicture;
 111  0
         this.uploadPolicy = uploadPolicy;
 112  
 
 113  
         // We want to trap the mouse actions on this picture.
 114  0
         addMouseListener(this);
 115  
 
 116  
         // We want to know when a resize event occurs (to recalculate
 117  
         // offscreenImage)
 118  0
         addComponentListener(this);
 119  0
     }
 120  
 
 121  
     /**
 122  
      * This setter is called by {@link PictureFileData} to set the picture that
 123  
      * is to be previewed.
 124  
      * 
 125  
      * @param pictureFileData The FileData for the image to be displayed. Null
 126  
      *            if no picture should be displayed.
 127  
      * @param button1 A button that will be activated or not, depending of the
 128  
      *            pictures was correctly set into the panel. May be null, if not
 129  
      *            button is to be enabled.
 130  
      * @param button2 Another button that will be activated or not. May also be
 131  
      *            null.
 132  
      */
 133  
     public void setPictureFile(PictureFileData pictureFileData,
 134  
             AbstractButton button1, AbstractButton button2) {
 135  
         // First : reset current picture configuration.
 136  0
         this.pictureFileData = null;
 137  0
         if (this.offscreenImage != null) {
 138  0
             this.offscreenImage.flush();
 139  0
             this.offscreenImage = null;
 140  
         }
 141  
 
 142  
         // Ask for an immediate repaint, to clear the panel (as offscreenImage
 143  
         // is now null).
 144  0
         repaint();
 145  
 
 146  
         // Then, we store the new picture data, get the offscreen picture and
 147  
         // ask for a repaint.
 148  0
         boolean enableButton = false;
 149  0
         if (pictureFileData != null && pictureFileData.canRead()) {
 150  0
             this.pictureFileData = pictureFileData;
 151  
 
 152  
             // A picture has been selected. The buttons must be enabled.
 153  0
             enableButton = true;
 154  
 
 155  
             // Now, we display this picture.
 156  0
             calculateOffscreenImage();
 157  0
             repaint();
 158  
         }
 159  
 
 160  
         // Let's activate the given button ... if any.
 161  0
         if (button1 != null) {
 162  0
             button1.setEnabled(enableButton);
 163  
         }
 164  0
         if (button2 != null) {
 165  0
             button2.setEnabled(enableButton);
 166  
         }
 167  0
     }
 168  
 
 169  
     /**
 170  
      * @see java.awt.Canvas#paint(java.awt.Graphics)
 171  
      */
 172  
     @Override
 173  
     public void paint(Graphics g) {
 174  
         // First : clear the panel area.
 175  0
         g.clearRect(0, 0, getWidth(), getHeight());
 176  
 
 177  
         /*
 178  
          * The picture is calculated outside of the paint() event. See:
 179  
          * calculateOffscreenImage() and componentResized. //Then, check if we
 180  
          * must calculate the picture. if (pictureFileData != null) { //Now, we
 181  
          * calculate the picture if we don't already have one. if
 182  
          * (offscreenImage == null) { calculateOffscreenImage(); } }
 183  
          */
 184  
 
 185  
         // Then, display the picture, if any is defined.
 186  0
         if (this.offscreenImage != null) {
 187  
             // Let's center this picture
 188  0
             int hMargin = (getWidth() - this.offscreenImage.getWidth(this)) / 2;
 189  0
             int vMargin = (getHeight() - this.offscreenImage.getHeight(this)) / 2;
 190  0
             g.drawImage(this.offscreenImage, hMargin, vMargin, this);
 191  
             // Free the used memory.
 192  0
             this.offscreenImage.flush();
 193  
         }
 194  0
     }
 195  
 
 196  
     /**
 197  
      * This function adds a quarter rotation to the current picture.
 198  
      * 
 199  
      * @param quarter Number of quarters (90�) the picture should rotate. 1
 200  
      *            means rotating of 90� clockwise (?). Can be negative
 201  
      *            (counterclockwise), more than 1...
 202  
      */
 203  
     public void rotate(int quarter) {
 204  0
         if (this.pictureFileData != null) {
 205  0
             Cursor previousCursor = this.uploadPolicy.setWaitCursor();
 206  0
             this.pictureFileData.addRotation(quarter);
 207  
             // The previously calculated picture is now wrong.
 208  0
             this.offscreenImage.flush();
 209  0
             this.offscreenImage = null;
 210  0
             calculateOffscreenImage();
 211  
 
 212  0
             repaint();
 213  0
             this.uploadPolicy.setCursor(previousCursor);
 214  0
         } else {
 215  0
             this.uploadPolicy
 216  0
                     .displayWarn("Hum, this is really strange: there is no pictureFileData in the PicturePanel! Command is ignored.");
 217  
         }
 218  0
     }
 219  
 
 220  
     /**
 221  
      * This method get the offscreenImage from the current pictureFileData. This
 222  
      * image is null, if pictureFileData is null. In this case, the repaint will
 223  
      * only clear the panel rectangle, on the screen.
 224  
      */
 225  
     private void calculateOffscreenImage() {
 226  0
         if (this.pictureFileData == null) {
 227  
             // Nothing to do. offscreenImage should be null.
 228  0
             if (this.offscreenImage != null) {
 229  0
                 this.offscreenImage = null;
 230  0
                 this.uploadPolicy
 231  0
                         .displayWarn("PicturePanel.calculateOffscreenImage(): pictureFileData is null (offscreenImage set to null");
 232  
             }
 233  0
         } else if (this.offscreenImage == null) {
 234  0
             this.uploadPolicy
 235  0
                     .displayDebug(
 236  
                             "PicturePanel.calculateOffscreenImage(): trying to calculate offscreenImage (PicturePanel.calculateOffscreenImage()",
 237  
                             30);
 238  
             try {
 239  0
                 this.offscreenImage = this.pictureFileData.getImage(this,
 240  
                         this.hasToStoreOffscreenPicture);
 241  0
             } catch (JUploadException e) {
 242  0
                 this.uploadPolicy.displayErr(e);
 243  
                 // We won't try to display the picture for this file.
 244  0
                 this.pictureFileData = null;
 245  0
                 this.offscreenImage = null;
 246  0
             }
 247  
         }
 248  0
     }
 249  
 
 250  
     /**
 251  
      * Is it really useful ??
 252  
      */
 253  
     @Override
 254  
     protected void finalize() throws Throwable {
 255  
         // super.finalize();
 256  0
         this.uploadPolicy.displayDebug("Within PicturePanel.finalize()", 10);
 257  
 
 258  0
         if (this.offscreenImage != null) {
 259  0
             this.offscreenImage.flush();
 260  
         }
 261  0
     }
 262  
 
 263  
     // ////////////////////////////////////////////////////////////////////////////////////////////////////
 264  
     // /////////////////////// MouseListener interface
 265  
     // ////////////////////////////////////////////////////////////////////////////////////////////////////
 266  
     /** @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent) */
 267  
     public void mouseClicked(MouseEvent arg0) {
 268  0
         if (this.pictureFileData != null) {
 269  
             // Ok, we have a picture. Let's display it.
 270  0
             this.uploadPolicy.onFileDoubleClicked(this.pictureFileData);
 271  
         }
 272  0
     }
 273  
 
 274  
     /** @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent) */
 275  
     public void mouseEntered(MouseEvent arg0) {
 276  
         // Nothing to do.
 277  0
     }
 278  
 
 279  
     /** @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent) */
 280  
     public void mouseExited(MouseEvent arg0) {
 281  
         // Nothing to do.
 282  0
     }
 283  
 
 284  
     /** @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent) */
 285  
     public void mousePressed(MouseEvent arg0) {
 286  
         // Nothing to do.
 287  0
     }
 288  
 
 289  
     /** @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent) */
 290  
     public void mouseReleased(MouseEvent arg0) {
 291  
         // Nothing to do.
 292  0
     }
 293  
 
 294  
     // ////////////////////////////////////////////////////////////////////////////////////////////////////
 295  
     // /////////////////////// ComponentListener interface
 296  
     // ////////////////////////////////////////////
 297  
     // ////////////////////////////////////////////////////////////////////////////////////////////////////
 298  
     /**
 299  
      * @see java.awt.event.ComponentListener#componentHidden(java.awt.event.ComponentEvent)
 300  
      */
 301  
     public void componentHidden(ComponentEvent arg0) {
 302  
         // No action
 303  0
     }
 304  
 
 305  
     /**
 306  
      * @see java.awt.event.ComponentListener#componentMoved(java.awt.event.ComponentEvent)
 307  
      */
 308  
     public void componentMoved(ComponentEvent arg0) {
 309  
         // No action
 310  0
     }
 311  
 
 312  
     /**
 313  
      * @see java.awt.event.ComponentListener#componentResized(java.awt.event.ComponentEvent)
 314  
      */
 315  
     public void componentResized(ComponentEvent arg0) {
 316  0
         if (this.offscreenImage != null) {
 317  0
             this.offscreenImage.flush();
 318  0
             this.offscreenImage = null;
 319  
         }
 320  
 
 321  
         // Then we calculate a new image for this panel.
 322  0
         calculateOffscreenImage();
 323  0
         repaint();
 324  0
     }
 325  
 
 326  
     /**
 327  
      * @see java.awt.event.ComponentListener#componentShown(java.awt.event.ComponentEvent)
 328  
      */
 329  
     public void componentShown(ComponentEvent arg0) {
 330  
         // No action
 331  0
     }
 332  
 }