1. /*
  2. * @(#)ProgressMonitorInputStream.java 1.18 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing;
  8. import java.io.*;
  9. import java.awt.Component;
  10. /**
  11. * Monitors the progress of reading from some InputStream. This ProgressMonitor
  12. * is normally invoked in roughly this form:
  13. * <pre>
  14. * InputStream in = new BufferedInputStream(
  15. * new ProgressMonitorInputStream(
  16. * parentComponent,
  17. * "Reading " + fileName,
  18. * new FileInputStream(fileName)));
  19. * </pre><p>
  20. * This creates a progress monitor to monitor the progress of reading
  21. * the input stream. If it's taking a while, a ProgressDialog will
  22. * be popped up to inform the user. If the user hits the Cancel button
  23. * an InterruptedIOException will be thrown on the next read.
  24. * All the right cleanup is done when the stream is closed.
  25. *
  26. *
  27. * <p>
  28. *
  29. * For further documentation and examples see
  30. * <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/progress.html">How to Monitor Progress</a>,
  31. * a section in <em>The Java Tutorial.</em>
  32. *
  33. * @see ProgressMonitor
  34. * @see JOptionPane
  35. * @author James Gosling
  36. * @version 1.18 01/23/03
  37. */
  38. public class ProgressMonitorInputStream extends FilterInputStream
  39. {
  40. private ProgressMonitor monitor;
  41. private int nread = 0;
  42. private int size = 0;
  43. /**
  44. * Constructs an object to monitor the progress of an input stream.
  45. *
  46. * @param message Descriptive text to be placed in the dialog box
  47. * if one is popped up.
  48. * @param parentComponent The component triggering the operation
  49. * being monitored.
  50. * @param in The input stream to be monitored.
  51. */
  52. public ProgressMonitorInputStream(Component parentComponent,
  53. Object message,
  54. InputStream in) {
  55. super(in);
  56. try {
  57. size = in.available();
  58. }
  59. catch(IOException ioe) {
  60. size = 0;
  61. }
  62. monitor = new ProgressMonitor(parentComponent, message, null, 0, size);
  63. }
  64. /**
  65. * Get the ProgressMonitor object being used by this stream. Normally
  66. * this isn't needed unless you want to do something like change the
  67. * descriptive text partway through reading the file.
  68. * @return the ProgressMonitor object used by this object
  69. */
  70. public ProgressMonitor getProgressMonitor() {
  71. return monitor;
  72. }
  73. /**
  74. * Overrides <code>FilterInputStream.read</code>
  75. * to update the progress monitor after the read.
  76. */
  77. public int read() throws IOException {
  78. int c = in.read();
  79. if (c >= 0) monitor.setProgress(++nread);
  80. if (monitor.isCanceled()) {
  81. InterruptedIOException exc =
  82. new InterruptedIOException("progress");
  83. exc.bytesTransferred = nread;
  84. throw exc;
  85. }
  86. return c;
  87. }
  88. /**
  89. * Overrides <code>FilterInputStream.read</code>
  90. * to update the progress monitor after the read.
  91. */
  92. public int read(byte b[]) throws IOException {
  93. int nr = in.read(b);
  94. if (nr > 0) monitor.setProgress(nread += nr);
  95. if (monitor.isCanceled()) {
  96. InterruptedIOException exc =
  97. new InterruptedIOException("progress");
  98. exc.bytesTransferred = nread;
  99. throw exc;
  100. }
  101. return nr;
  102. }
  103. /**
  104. * Overrides <code>FilterInputStream.read</code>
  105. * to update the progress monitor after the read.
  106. */
  107. public int read(byte b[],
  108. int off,
  109. int len) throws IOException {
  110. int nr = in.read(b, off, len);
  111. if (nr > 0) monitor.setProgress(nread += nr);
  112. if (monitor.isCanceled()) {
  113. InterruptedIOException exc =
  114. new InterruptedIOException("progress");
  115. exc.bytesTransferred = nread;
  116. throw exc;
  117. }
  118. return nr;
  119. }
  120. /**
  121. * Overrides <code>FilterInputStream.skip</code>
  122. * to update the progress monitor after the skip.
  123. */
  124. public long skip(long n) throws IOException {
  125. long nr = in.skip(n);
  126. if (nr > 0) monitor.setProgress(nread += nr);
  127. return nr;
  128. }
  129. /**
  130. * Overrides <code>FilterInputStream.close</code>
  131. * to close the progress monitor as well as the stream.
  132. */
  133. public void close() throws IOException {
  134. in.close();
  135. monitor.close();
  136. }
  137. /**
  138. * Overrides <code>FilterInputStream.reset</code>
  139. * to reset the progress monitor as well as the stream.
  140. */
  141. public synchronized void reset() throws IOException {
  142. in.reset();
  143. nread = size - in.available();
  144. monitor.setProgress(nread);
  145. }
  146. }