我有一个小的Java应用程序有效地“尾巴”在ini文件中定义的任意文件集合。我的“LogReader”类扩展了JFrame,并完成了繁重的工作。将文件路径的集合读入向量,然后遍历向量,读取每个文件并将每个文件的最后X行添加到JTabbedPane选项卡上的文本区域。通过点击一个JButton,通过一个ActionListener来启动构建向量并遍历文件的过程。Swing“阻塞”,我想我需要线程,但不知道多少
对文件的读取工作正常(但仍然有效),但是读取20个文件的过程需要一些时间,其中一些文件增长到30MB。为了帮助消磨时间,我决定添加一个进度屏幕,其中显示“正在读取文件#3/26:c:\ logs \ superduper1.log”等。所以我创建了另一个类“SplashScreen”,它也扩展了JFrame,并添加了一个JLabel来指示进度。 SplashScreen类有一个update()方法,它只是在JLabel上执行setText()。
上的JButton的ActionListener的调用RefreshLogs(),它看起来像:
vctFileStrings.clear();
tpMain.removeAll();
frmSplash.update("Loading Configuration"); //Update the label on the Splash Screen instance
BuildVectorOfLogs(strConfFile); //Read the collection of files into the vector
frmSplash.update("Reading Logs");
ReadLogs(); //read the files, updating the Splash Screen as we go
,然后ReadLogs()在矢量迭代,读取文件和建设的TabbedPane。
但我注意到,当从ActionListener中调用RefreshLogs()时,Splash Screen不会更新。但是,如果将RefreshLogs()添加到第一帧的构造函数中,则初始屏幕将按预期工作(每个文件都会更新进度)。经过一些实验和阅读后,我认为我需要创建一个读取文件的工作线程,同时更新事件派发队列中的启动画面。
我的问题是:
- 我的想法是否正确?是否有一些简单的替代方案来实现线程,这将允许我从ActionListener调用的方法更新启动画面?
- 如果使用线程可以最好地完成此操作,那么我需要线程的活动范围是什么?我需要将所有的文件I/O活动放到他们自己的线程中吗?我应该将GUI活动(标签更新)放在他们自己的线程中,以便它们与JButton单击事件分开进行吗?