ProgressMonitorInputStream类表示一个输入流过滤器,这个输入流过滤器使用ProgressMonitor来检测一个输入流的读取。如果读取需要较长的时间完成,则会显示ProgressMonitor,且用户可以选择弹出窗口中的Cancel按钮,从而使得读取被中断并且输入流会抛出一个InterruptedIOException。
类似于其他的过滤器流,ProgressMonitorInputStream是使用一个到需要过滤的流的引用来创建的。除了到这个过滤器的引用,ProgressMonitorInputStream的构造函数还需要其ProgressMonitor的两个参数:父组件以及一个消息。正如在这里所看到的,构造函数首先需要ProgressMonitor参数:
public ProgressMonitorInputStream(
Component parentComponent, Object message, InputStream inputStream)
与JOptionPane与ProgressMonitor类似,消息参数是一个Object,而不是一个String,所以我们可以在多行上显示一个组件数组或是字符串。下面的代码创建了一个ProgressMonitorInputStream。
FileInputStream fis = new FileInputStream(filename); ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(parent, "Reading " + filename, fis);
与所有的输入流一样,一旦我们创建了ProgressMonitorInputStream,我们需要由其中进行读取。如果输入流的读取不够快,底层的ProgressMonitor会使得进程弹出窗口显示。一旦这个窗口显示,用户可以监视进程或是通过选择Cancel按钮关闭读取。如果Cancel按钮被选中,则InterruptedIOException会被抛出,而异常的bytesTransferred或会被设置为已经成功读取的字节数。
图9-7显示了一个ProgressMonitorInputStream弹出窗口的样子。略为不同的是,弹出窗口在消息区域使用两个JLabel组件,而不是一个。
列表9-6显示了完整的源代码示例。其中粗体显示的代码行是使用ProgressMonitorInputStream的关键。他们设置对话框的消息并且创建输入流。程序使用一个由命令行指定的文件名,读取文件,并且将文件拷贝到标准输出。如果文件足够大,进程监视器将会显示。如果我们按下Cancel按钮,读取停止,并且Canceled会被输出到标准错误。
package swingstudy.ch09; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.InterruptedIOException; import javax.swing.JLabel; import javax.swing.ProgressMonitorInputStream; public class ProgressInputSample { public static final int NORMAL = 0; public static final int BAD_FILE = 1; public static final int CANCELED = NORMAL; public static final int PROBLEM = 2; /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int returnValue = NORMAL; if(args.length != 1) { System.err.println("Usage:"); System.err.println("java ProgressInputSample filename"); } else { try { FileInputStream fis = new FileInputStream(args[0]); JLabel filenameLabel = new JLabel(args[0], JLabel.RIGHT); Object message[] = {"Reading:", filenameLabel}; ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(null, message, fis); InputStreamReader isr = new InputStreamReader(pmis); BufferedReader br = new BufferedReader(isr); String line; while((line = br.readLine()) != null) { System.out.println(line); } br.close(); } catch(FileNotFoundException exception) { System.err.println("Bad File "+exception); returnValue = BAD_FILE; } catch(InterruptedIOException exception) { System.err.println("Canceled"); returnValue = CANCELED; } catch(IOException exception) { System.err.println("I/O Exception "+exception); returnValue = PROBLEM; } } System.exit(returnValue); } }
表9-7显示了ProgressMonitorInputStream的属性。ProgressMonitor在输入流创建时创建。我们不需要修改ProgressMonitor。然而我们也许需要在弹出窗口显示之前提供一个或长或短的时延(ProgressMonitor的millisToDecideToPopup属性)。