1 /*
   2  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 
  27 
  28 package javax.swing;
  29 
  30 
  31 
  32 import java.io.*;
  33 import java.awt.Component;
  34 
  35 
  36 
  37 /**
  38  * Monitors the progress of reading from some InputStream. This ProgressMonitor
  39  * is normally invoked in roughly this form:
  40  * <pre>
  41  * InputStream in = new BufferedInputStream(
  42  *                          new ProgressMonitorInputStream(
  43  *                                  parentComponent,
  44  *                                  "Reading " + fileName,
  45  *                                  new FileInputStream(fileName)));
  46  * </pre><p>
  47  * This creates a progress monitor to monitor the progress of reading
  48  * the input stream.  If it's taking a while, a ProgressDialog will
  49  * be popped up to inform the user.  If the user hits the Cancel button
  50  * an InterruptedIOException will be thrown on the next read.
  51  * All the right cleanup is done when the stream is closed.
  52  *
  53  *
  54  * <p>
  55  *
  56  * For further documentation and examples see
  57  * <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/progress.html">How to Monitor Progress</a>,
  58  * a section in <em>The Java Tutorial.</em>
  59  *
  60  * @see ProgressMonitor
  61  * @see JOptionPane
  62  * @author James Gosling
  63  * @since 1.2
  64  */
  65 public class ProgressMonitorInputStream extends FilterInputStream
  66 {
  67     private ProgressMonitor monitor;
  68     private int             nread = 0;
  69     private int             size = 0;
  70 
  71 
  72     /**
  73      * Constructs an object to monitor the progress of an input stream.
  74      *
  75      * @param message Descriptive text to be placed in the dialog box
  76      *                if one is popped up.
  77      * @param parentComponent The component triggering the operation
  78      *                        being monitored.
  79      * @param in The input stream to be monitored.
  80      */
  81     public ProgressMonitorInputStream(Component parentComponent,
  82                                       Object message,
  83                                       InputStream in) {
  84         super(in);
  85         try {
  86             size = in.available();
  87         }
  88         catch(IOException ioe) {
  89             size = 0;
  90         }
  91         monitor = new ProgressMonitor(parentComponent, message, null, 0, size);
  92     }
  93 
  94 
  95     /**
  96      * Get the ProgressMonitor object being used by this stream. Normally
  97      * this isn't needed unless you want to do something like change the
  98      * descriptive text partway through reading the file.
  99      * @return the ProgressMonitor object used by this object
 100      */
 101     public ProgressMonitor getProgressMonitor() {
 102         return monitor;
 103     }
 104 
 105 
 106     /**
 107      * Overrides <code>FilterInputStream.read</code>
 108      * to update the progress monitor after the read.
 109      */
 110     public int read() throws IOException {
 111         int c = in.read();
 112         if (c >= 0) monitor.setProgress(++nread);
 113         if (monitor.isCanceled()) {
 114             InterruptedIOException exc =
 115                                     new InterruptedIOException("progress");
 116             exc.bytesTransferred = nread;
 117             throw exc;
 118         }
 119         return c;
 120     }
 121 
 122 
 123     /**
 124      * Overrides <code>FilterInputStream.read</code>
 125      * to update the progress monitor after the read.
 126      */
 127     public int read(byte b[]) throws IOException {
 128         int nr = in.read(b);
 129         if (nr > 0) monitor.setProgress(nread += nr);
 130         if (monitor.isCanceled()) {
 131             InterruptedIOException exc =
 132                                     new InterruptedIOException("progress");
 133             exc.bytesTransferred = nread;
 134             throw exc;
 135         }
 136         return nr;
 137     }
 138 
 139 
 140     /**
 141      * Overrides <code>FilterInputStream.read</code>
 142      * to update the progress monitor after the read.
 143      */
 144     public int read(byte b[],
 145                     int off,
 146                     int len) throws IOException {
 147         int nr = in.read(b, off, len);
 148         if (nr > 0) monitor.setProgress(nread += nr);
 149         if (monitor.isCanceled()) {
 150             InterruptedIOException exc =
 151                                     new InterruptedIOException("progress");
 152             exc.bytesTransferred = nread;
 153             throw exc;
 154         }
 155         return nr;
 156     }
 157 
 158 
 159     /**
 160      * Overrides <code>FilterInputStream.skip</code>
 161      * to update the progress monitor after the skip.
 162      */
 163     public long skip(long n) throws IOException {
 164         long nr = in.skip(n);
 165         if (nr > 0) monitor.setProgress(nread += nr);
 166         return nr;
 167     }
 168 
 169 
 170     /**
 171      * Overrides <code>FilterInputStream.close</code>
 172      * to close the progress monitor as well as the stream.
 173      */
 174     public void close() throws IOException {
 175         in.close();
 176         monitor.close();
 177     }
 178 
 179 
 180     /**
 181      * Overrides <code>FilterInputStream.reset</code>
 182      * to reset the progress monitor as well as the stream.
 183      */
 184     public synchronized void reset() throws IOException {
 185         in.reset();
 186         nread = size - in.available();
 187         monitor.setProgress(nread);
 188     }
 189 }