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  */
  64 public class ProgressMonitorInputStream extends FilterInputStream
  65 {
  66     private ProgressMonitor monitor;
  67     private int             nread = 0;
  68     private int             size = 0;
  69 
  70 
  71     /**
  72      * Constructs an object to monitor the progress of an input stream.
  73      *
  74      * @param message Descriptive text to be placed in the dialog box
  75      *                if one is popped up.
  76      * @param parentComponent The component triggering the operation
  77      *                        being monitored.
  78      * @param in The input stream to be monitored.
  79      */
  80     public ProgressMonitorInputStream(Component parentComponent,
  81                                       Object message,
  82                                       InputStream in) {
  83         super(in);
  84         try {
  85             size = in.available();
  86         }
  87         catch(IOException ioe) {
  88             size = 0;
  89         }
  90         monitor = new ProgressMonitor(parentComponent, message, null, 0, size);
  91     }
  92 
  93 
  94     /**
  95      * Get the ProgressMonitor object being used by this stream. Normally
  96      * this isn't needed unless you want to do something like change the
  97      * descriptive text partway through reading the file.
  98      * @return the ProgressMonitor object used by this object
  99      */
 100     public ProgressMonitor getProgressMonitor() {
 101         return monitor;
 102     }
 103 
 104 
 105     /**
 106      * Overrides <code>FilterInputStream.read</code>
 107      * to update the progress monitor after the read.
 108      */
 109     public int read() throws IOException {
 110         int c = in.read();
 111         if (c >= 0) monitor.setProgress(++nread);
 112         if (monitor.isCanceled()) {
 113             InterruptedIOException exc =
 114                                     new InterruptedIOException("progress");
 115             exc.bytesTransferred = nread;
 116             throw exc;
 117         }
 118         return c;
 119     }
 120 
 121 
 122     /**
 123      * Overrides <code>FilterInputStream.read</code>
 124      * to update the progress monitor after the read.
 125      */
 126     public int read(byte b[]) throws IOException {
 127         int nr = in.read(b);
 128         if (nr > 0) monitor.setProgress(nread += nr);
 129         if (monitor.isCanceled()) {
 130             InterruptedIOException exc =
 131                                     new InterruptedIOException("progress");
 132             exc.bytesTransferred = nread;
 133             throw exc;
 134         }
 135         return nr;
 136     }
 137 
 138 
 139     /**
 140      * Overrides <code>FilterInputStream.read</code>
 141      * to update the progress monitor after the read.
 142      */
 143     public int read(byte b[],
 144                     int off,
 145                     int len) throws IOException {
 146         int nr = in.read(b, off, len);
 147         if (nr > 0) monitor.setProgress(nread += nr);
 148         if (monitor.isCanceled()) {
 149             InterruptedIOException exc =
 150                                     new InterruptedIOException("progress");
 151             exc.bytesTransferred = nread;
 152             throw exc;
 153         }
 154         return nr;
 155     }
 156 
 157 
 158     /**
 159      * Overrides <code>FilterInputStream.skip</code>
 160      * to update the progress monitor after the skip.
 161      */
 162     public long skip(long n) throws IOException {
 163         long nr = in.skip(n);
 164         if (nr > 0) monitor.setProgress(nread += nr);
 165         return nr;
 166     }
 167 
 168 
 169     /**
 170      * Overrides <code>FilterInputStream.close</code>
 171      * to close the progress monitor as well as the stream.
 172      */
 173     public void close() throws IOException {
 174         in.close();
 175         monitor.close();
 176     }
 177 
 178 
 179     /**
 180      * Overrides <code>FilterInputStream.reset</code>
 181      * to reset the progress monitor as well as the stream.
 182      */
 183     public synchronized void reset() throws IOException {
 184         in.reset();
 185         nread = size - in.available();
 186         monitor.setProgress(nread);
 187     }
 188 }