這篇文章給大家介紹怎么分析SwingWorker與Swing程序,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。
創(chuàng)新互聯(lián)是一家專(zhuān)注于做網(wǎng)站、成都網(wǎng)站建設(shè)與策劃設(shè)計(jì),西塞山網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專(zhuān)注于網(wǎng)站建設(shè)十多年,網(wǎng)設(shè)計(jì)領(lǐng)域的專(zhuān)業(yè)建站公司;建站業(yè)務(wù)涵蓋:西塞山等地區(qū)。西塞山做網(wǎng)站價(jià)格咨詢(xún):18980820575
某些人一拍腦袋的事,讓我有機(jī)會(huì)跟Swing干上了,因?yàn)轫?xiàng)目組沒(méi)人用這玩意整過(guò)這東西,那就只能我硬著頭皮上了!有時(shí)候人是要有點(diǎn)壓力才行的。
第一階段的開(kāi)發(fā):
準(zhǔn)備階段:工具的選擇。用了Netbeans 6,試用了下,感覺(jué)畫(huà)界面還比較容易,但是生成的代碼很長(zhǎng),剛開(kāi)始對(duì)Swing很陌生 ,看著netbeans 生成代碼很頭痛,感覺(jué)不是我想要的東西,然后放棄了。然后是VE,因?yàn)橐仓皇堑跪v了下,沒(méi)細(xì)看。選擇了Jigloo ,但是用了之后才知道他生成的代碼也很惡劣......
開(kāi)發(fā)階段:別熟悉swing 邊開(kāi)發(fā),其中遇到亂七八遭事情一堆,但是因?yàn)檫@個(gè)軟件的功能是比較簡(jiǎn)單的,***終于是拿了出來(lái),雖然BUG一堆,但是也算是我的***swing作品,客戶(hù)感覺(jué)效果很不理想(有軟件設(shè)計(jì)方面的,也有技術(shù)運(yùn)用方面的),也就有了下面繼續(xù)開(kāi)發(fā)的經(jīng)歷了。
主要技術(shù)方面問(wèn)題是,線程的亂用造成死鎖,經(jīng)常造成莫名的假死。
第二階段的開(kāi)發(fā):
因?yàn)榈谝浑A段的開(kāi)發(fā)比較痛苦,所以決定換個(gè)語(yǔ)言開(kāi)發(fā)。因?yàn)樽罱黂IA比較熱,RIA里面的adoble的air也算比較熱門(mén)的,UI給人感覺(jué)很華麗,也自己嘗試做過(guò)一些DEMO。項(xiàng)目中用的webservice,加密解密操作,文件上傳下載都有解決的辦法,但是要命的是這個(gè)項(xiàng)目中要調(diào)用外部程序,air在這方面比較脆弱,google了一把 as 的 fscommand 能調(diào)用其他程序,但是 air 竟然不支持這個(gè),后來(lái)還是塌塌實(shí)實(shí)用SWING 吧。
然后又試用了一把VE,感覺(jué)現(xiàn)在比上次我用的時(shí)候好多了,后來(lái)就把Jigloo換 VE了。
擺在眼前的就是如何運(yùn)用好線程了。又google了一把,找到了swingworker 這個(gè)東西拉。從Java SE 6開(kāi)始引進(jìn)的SwingWorker能幫你輕松的編寫(xiě)多線程Swing程序,改善你Swing程序的結(jié)構(gòu),提高界面響應(yīng)的靈活性,這正是我要的東西。
一個(gè)Swing程序中一般有下面三種類(lèi)型的線程:
◆初始化線程(Initial Thread)
◆UI事件調(diào)度線程(EDT)
◆任務(wù)線程(Worker Thread)
Swing程序只有一個(gè)用EDT,該線程負(fù)責(zé)GUI組件的繪制和更新,通過(guò)調(diào)用程序的事件處理器來(lái)響應(yīng)用戶(hù)交互。所有事件處理都是在EDT上進(jìn)行的,程序同UI組件和其基本數(shù)據(jù)模型的交互只允許在EDT上進(jìn)行,所有運(yùn)行在EDT上的任務(wù)應(yīng)該盡快完成,以便UI能及時(shí)響應(yīng)用戶(hù)輸入。
Swing編程時(shí)應(yīng)該注意以下幾點(diǎn):
1.從其他線程訪問(wèn)UI組件及其事件處理器會(huì)導(dǎo)致界面更新和繪制錯(cuò)誤。
2.在EDT上執(zhí)行耗時(shí)任務(wù)會(huì)使程序失去響應(yīng),這會(huì)使GUI事件阻塞在隊(duì)列中得不到處理。
3.應(yīng)使用獨(dú)立的任務(wù)線程來(lái)執(zhí)行耗時(shí)計(jì)算或輸入輸出密集型任務(wù),比如同數(shù)據(jù)庫(kù)通信、訪問(wèn)網(wǎng)站資源、讀寫(xiě)大樹(shù)據(jù)量的文件。
而我第一階段開(kāi)發(fā)的正是由于沒(méi)有注意到這點(diǎn)導(dǎo)致整個(gè)程序效果不佳。程序中有個(gè)事件處理都要訪問(wèn)Web服務(wù),這些服務(wù)通常要許多秒后才能響應(yīng),在此期間,如果程序在EDT上進(jìn)行Web服務(wù)交互,用戶(hù)就不能取消搜索或者同界面交互,像這兩種都不應(yīng)該在EDT上運(yùn)行。
javax.swing.SwingWorker類(lèi)是Java SE 6中新出現(xiàn)的類(lèi),使用SwingWorker,程序能啟動(dòng)一個(gè)任務(wù)線程來(lái)異步查詢(xún),并馬上返回EDT線程。顯示了使用SwingWorker后,事件處理立即返回,允許EDT繼續(xù)執(zhí)行后續(xù)的UI事件。原先就是都放在EDT上了,效果勉強(qiáng)也就難免了。而使用Swingworker啟動(dòng)一個(gè)任務(wù)線程就可以靈活響應(yīng)界面。
下面講講他的用法:
SwingWorker的定義如下:public abstract class SwingWorker
SwingWorker是抽象類(lèi),因此必須繼承它才能執(zhí)行所需的特定任務(wù)。注意該類(lèi)有兩個(gè)類(lèi)型參數(shù):T及V。T是doInBackground和get方法的返回類(lèi)型,V是publish和process方法要處理的數(shù)據(jù)類(lèi)型。
SwingWorker實(shí)現(xiàn)以下接口方法:
◆boolean cancel(boolean mayInterruptIfRunning)
◆T get()
◆T get(long timeout, TimeUnit unit)
◆boolean isCancelled()
◆boolean isDone()
SwingWorker實(shí)現(xiàn)了所有的接口方法,實(shí)際上你僅需要實(shí)現(xiàn)以下SwingWorker的抽象方法:protected T doInBackground() throws Exception
doInBackground方法作為任務(wù)線程的一部分執(zhí)行,它負(fù)責(zé)完成線程的基本任務(wù),并以返回值來(lái)作為線程的執(zhí)行結(jié)果。繼承類(lèi)須覆蓋該方法并確保包含或代理任務(wù)線程的基本任務(wù)。不要直接調(diào)用該方法,應(yīng)使用任務(wù)對(duì)象的execute方法來(lái)調(diào)度執(zhí)行。
在獲得執(zhí)行結(jié)果后應(yīng)使用SwingWorker 的get方法獲取doInBackground方法的結(jié)果。可以在EDT上調(diào)用get方法,但該方法將一直處于阻塞狀態(tài),直到任務(wù)線程完成。***只有在知道結(jié)果時(shí)才調(diào)用get方法,這樣用戶(hù)便不用等待。為防止阻塞,可以使用isDone方法來(lái)檢驗(yàn)doInBackground是否完成。另外調(diào)用方法 get(long timeout, TimeUnit unit)將會(huì)一直阻塞直到任務(wù)線程結(jié)束或超時(shí)。獲取任務(wù)結(jié)果的***地方是在done方法內(nèi):protected void done()
在doInBackground方法完成之后,SwingWorker調(diào)用done方法。如果任務(wù)需要在完成后使用線程結(jié)果更新GUI組件或者做些清理工作,可覆蓋done方法來(lái)完成它們。這兒是調(diào)用get方法的***地方,因?yàn)榇藭r(shí)已知道線程任務(wù)完成了,SwingWorker在EDT上激活done方法,因此可以在此方法內(nèi)安全地和任何GUI組件交互。
沒(méi)必要等到線程完成就可以獲得中間結(jié)果。中間結(jié)果是任務(wù)線程在產(chǎn)生***結(jié)果之前就能產(chǎn)生的數(shù)據(jù)。當(dāng)任務(wù)線程執(zhí)行時(shí),它可以發(fā)布類(lèi)型為V的中間結(jié)果,覆蓋process方法來(lái)處理中間結(jié)果。后文還將提供這些方法的更多詳細(xì)信息。當(dāng)屬性改變時(shí),SwingWorker實(shí)例能通知處理器,SwingWorker有兩個(gè)重要的屬性:狀態(tài)和進(jìn)程。任務(wù)線程有幾種狀態(tài),以下面SwingWorker.StateValue枚舉值來(lái)表示:
◆PENDING
◆STARTED
◆DONE
任務(wù)線程一創(chuàng)建就處于PENDING狀態(tài),當(dāng)doInBackground方法開(kāi)始時(shí),任務(wù)線程就進(jìn)入STARTED狀態(tài),當(dāng)doInBackground方法完成后,任務(wù)線程就處于DONE狀態(tài),隨著線程進(jìn)入各個(gè)階段,SwingWorker超類(lèi)自動(dòng)設(shè)置這些狀態(tài)值。你可以添加處理器,當(dāng)這些屬性發(fā)生變化來(lái)接收通知。
最后,任務(wù)對(duì)象有一個(gè)進(jìn)度屬性,隨著任務(wù)進(jìn)展時(shí),可以將這個(gè)屬性從0更新到100標(biāo)識(shí)任務(wù)進(jìn)度,當(dāng)該屬性發(fā)生變化時(shí),任務(wù)通知處理器進(jìn)行處理。
我的使用感覺(jué)就是,象I/O操作,數(shù)據(jù)操作,網(wǎng)絡(luò)操作等耗時(shí)的操作放到 doInBackground()中處理,任務(wù)執(zhí)行中而非任務(wù)結(jié)束時(shí)發(fā)布數(shù)據(jù),要調(diào)用publish方法.
publish方法時(shí),SwingWorker類(lèi)調(diào)度process方法。有意思的是process方法是在EDT上面執(zhí)行,這意味著可以同Swing組件和其模型直接交互??梢詫?shí)現(xiàn)你在處理任務(wù)時(shí),給個(gè)進(jìn)度條提示。
關(guān)于怎么分析SwingWorker與Swing程序就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。