Java Swing";封锁;,我想我需要穿线,但不知道多少

Java Swing";封锁;,我想我需要穿线,但不知道多少,java,swing,multithreading,Java,Swing,Multithreading,我有一个小java应用程序,可以有效地“跟踪”ini文件中定义的任意文件集合。我的“LogReader”类扩展了JFrame,并执行重载操作;将文件路径集合读入向量,然后在向量上迭代,读取每个文件并将每个文件的最后X行添加到JTabbedPane选项卡上的文本区域。通过ActionListener单击JButton,可以启动构建向量和迭代文件的过程 文件的读取工作正常(现在仍然如此),但读取20多个文件的过程需要一些时间,有些文件的大小增长到30MB。为了打发时间,我决定添加一个进度屏幕,上面写

我有一个小java应用程序,可以有效地“跟踪”ini文件中定义的任意文件集合。我的“LogReader”类扩展了JFrame,并执行重载操作;将文件路径集合读入向量,然后在向量上迭代,读取每个文件并将每个文件的最后X行添加到JTabbedPane选项卡上的文本区域。通过ActionListener单击JButton,可以启动构建向量和迭代文件的过程

文件的读取工作正常(现在仍然如此),但读取20多个文件的过程需要一些时间,有些文件的大小增长到30MB。为了打发时间,我决定添加一个进度屏幕,上面写着“正在阅读26:c:\logs\superduper1.log中的第3个文件”,以此类推。因此,我创建了另一个类“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()遍历向量,读取文件并构建选项卡窗格

不过,我注意到,当从ActionListener中调用RefreshLogs()时,启动屏幕不会更新。但是,如果我将RefreshLogs()添加到第一帧的构造函数中,启动屏幕将按预期工作(更新每个文件的进度)。经过一些实验和阅读,我认为我需要创建一个工作线程来读取文件,同时更新事件调度队列中的初始屏幕

我的问题是:
-我的想法正确吗?是否有一些简单的替代方法来实现线程化,从而允许我从ActionListener调用的方法更新初始屏幕?

-若这是使用线程实现的最佳方式,那个么我需要线程的活动范围是什么?我是否需要将所有文件I/O活动放入它们自己的线程中?我是否应该将GUI活动(标签更新)放在它们自己的线程中,以便它们与JButton click事件分开发生?

要想知道如何做,并且在您使用NetBeans或访问NetBeans的情况下,建议您查看默认值。它创建了一个预连线的桌面应用程序,在状态栏中内置了进度条,当执行任何“操作”代码时,该进度条将自动更新。它利用了动作API,动作API也是预先连接到后台线程中运行的


通过查看自动生成的代码,您将能够正确、轻松地在自己的代码中实现它。

是的,您应该将您的时间密集型阅读放在单独的线程中。现在,您可以在事件调度线程(EDT)中执行所有操作,该线程将更新GUI,但正在忙于读取数据


你可以用这个。看看哪个看起来像您需要的。

我想说:是的,您关于将读取大文件的任务转移到单独的线程上的想法是正确的。您永远不应该在事件调度线程上执行长任务,因为当该线程繁忙时,GUI将无响应,并且您的应用程序将感觉很慢

这听起来是一个很好的例子。此类允许您在单独的线程上执行慢速请求(如磁盘或网络访问),并通过EDT将进度更新反馈给GUI
SwingWorker
负责处理线程之间切换的所有复杂性。您所要做的就是在适当的位置实现您的业务逻辑

太阳有