千家信息网

怎么分析SwingWorker与Swing程序

发表于:2024-11-20 作者:千家信息网编辑
千家信息网最后更新 2024年11月20日,这篇文章给大家介绍怎么分析SwingWorker与Swing程序,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。某些人一拍脑袋的事,让我有机会跟Swing干上了,因为项目组没人用这
千家信息网最后更新 2024年11月20日怎么分析SwingWorker与Swing程序

这篇文章给大家介绍怎么分析SwingWorker与Swing程序,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

某些人一拍脑袋的事,让我有机会跟Swing干上了,因为项目组没人用这玩意整过这东西,那就只能我硬着头皮上了!有时候人是要有点压力才行的。
第一阶段的开发:
准备阶段:工具的选择。用了Netbeans 6,试用了下,感觉画界面还比较容易,但是生成的代码很长,刚开始对Swing很陌生 ,看着netbeans 生成代码很头痛,感觉不是我想要的东西,然后放弃了。然后是VE,因为也只是倒腾了下,没细看。选择了Jigloo ,但是用了之后才知道他生成的代码也很恶劣......

开发阶段:别熟悉swing 边开发,其中遇到乱七八遭事情一堆,但是因为这个软件的功能是比较简单的,***终于是拿了出来,虽然BUG一堆,但是也算是我的***swing作品,客户感觉效果很不理想(有软件设计方面的,也有技术运用方面的),也就有了下面继续开发的经历了。
主要技术方面问题是,线程的乱用造成死锁,经常造成莫名的假死。

第二阶段的开发:
因为第一阶段的开发比较痛苦,所以决定换个语言开发。因为最近RIA比较热,RIA里面的adoble的air也算比较热门的,UI给人感觉很华丽,也自己尝试做过一些DEMO。项目中用的webservice,加密解密操作,文件上传下载都有解决的办法,但是要命的是这个项目中要调用外部程序,air在这方面比较脆弱,google了一把 as 的 fscommand 能调用其他程序,但是 air 竟然不支持这个,后来还是塌塌实实用SWING 吧。
然后又试用了一把VE,感觉现在比上次我用的时候好多了,后来就把Jigloo换 VE了。

摆在眼前的就是如何运用好线程了。又google了一把,找到了swingworker 这个东西拉。从Java SE 6开始引进的SwingWorker能帮你轻松的编写多线程Swing程序,改善你Swing程序的结构,提高界面响应的灵活性,这正是我要的东西。
一个Swing程序中一般有下面三种类型的线程:
◆初始化线程(Initial Thread)
◆UI事件调度线程(EDT)
◆任务线程(Worker Thread)

Swing程序只有一个用EDT,该线程负责GUI组件的绘制和更新,通过调用程序的事件处理器来响应用户交互。所有事件处理都是在EDT上进行的,程序同UI组件和其基本数据模型的交互只允许在EDT上进行,所有运行在EDT上的任务应该尽快完成,以便UI能及时响应用户输入。

Swing编程时应该注意以下几点:
1.从其他线程访问UI组件及其事件处理器会导致界面更新和绘制错误。
2.在EDT上执行耗时任务会使程序失去响应,这会使GUI事件阻塞在队列中得不到处理。
3.应使用独立的任务线程来执行耗时计算或输入输出密集型任务,比如同数据库通信、访问网站资源、读写大树据量的文件。
而我第一阶段开发的正是由于没有注意到这点导致整个程序效果不佳。程序中有个事件处理都要访问Web服务,这些服务通常要许多秒后才能响应,在此期间,如果程序在EDT上进行Web服务交互,用户就不能取消搜索或者同界面交互,像这两种都不应该在EDT上运行。

javax.swing.SwingWorker类是Java SE 6中新出现的类,使用SwingWorker,程序能启动一个任务线程来异步查询,并马上返回EDT线程。显示了使用SwingWorker后,事件处理立即返回,允许EDT继续执行后续的UI事件。原先就是都放在EDT上了,效果勉强也就难免了。而使用Swingworker启动一个任务线程就可以灵活响应界面。

下面讲讲他的用法:
SwingWorker的定义如下:public abstract class SwingWorkerextends Object implements RunnableFuture

SwingWorker是抽象类,因此必须继承它才能执行所需的特定任务。注意该类有两个类型参数:T及V。T是doInBackground和get方法的返回类型,V是publish和process方法要处理的数据类型。

SwingWorker实现以下接口方法:
◆boolean cancel(boolean mayInterruptIfRunning)
◆T get()
◆T get(long timeout, TimeUnit unit)
◆boolean isCancelled()
◆boolean isDone()

SwingWorker实现了所有的接口方法,实际上你仅需要实现以下SwingWorker的抽象方法:protected T doInBackground() throws Exception

doInBackground方法作为任务线程的一部分执行,它负责完成线程的基本任务,并以返回值来作为线程的执行结果。继承类须覆盖该方法并确保包含或代理任务线程的基本任务。不要直接调用该方法,应使用任务对象的execute方法来调度执行。

在获得执行结果后应使用SwingWorker 的get方法获取doInBackground方法的结果。可以在EDT上调用get方法,但该方法将一直处于阻塞状态,直到任务线程完成。***只有在知道结果时才调用get方法,这样用户便不用等待。为防止阻塞,可以使用isDone方法来检验doInBackground是否完成。另外调用方法 get(long timeout, TimeUnit unit)将会一直阻塞直到任务线程结束或超时。获取任务结果的***地方是在done方法内:protected void done()

在doInBackground方法完成之后,SwingWorker调用done方法。如果任务需要在完成后使用线程结果更新GUI组件或者做些清理工作,可覆盖done方法来完成它们。这儿是调用get方法的***地方,因为此时已知道线程任务完成了,SwingWorker在EDT上激活done方法,因此可以在此方法内安全地和任何GUI组件交互。

没必要等到线程完成就可以获得中间结果。中间结果是任务线程在产生***结果之前就能产生的数据。当任务线程执行时,它可以发布类型为V的中间结果,覆盖process方法来处理中间结果。后文还将提供这些方法的更多详细信息。当属性改变时,SwingWorker实例能通知处理器,SwingWorker有两个重要的属性:状态和进程。任务线程有几种状态,以下面SwingWorker.StateValue枚举值来表示:
◆PENDING
◆STARTED
◆DONE

任务线程一创建就处于PENDING状态,当doInBackground方法开始时,任务线程就进入STARTED状态,当doInBackground方法完成后,任务线程就处于DONE状态,随着线程进入各个阶段,SwingWorker超类自动设置这些状态值。你可以添加处理器,当这些属性发生变化来接收通知。

最后,任务对象有一个进度属性,随着任务进展时,可以将这个属性从0更新到100标识任务进度,当该属性发生变化时,任务通知处理器进行处理。

我的使用感觉就是,象I/O操作,数据操作,网络操作等耗时的操作放到 doInBackground()中处理,任务执行中而非任务结束时发布数据,要调用publish方法.
publish方法时,SwingWorker类调度process方法。有意思的是process方法是在EDT上面执行,这意味着可以同Swing组件和其模型直接交互。可以实现你在处理任务时,给个进度条提示。

关于怎么分析SwingWorker与Swing程序就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

0