闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閻愵剙鍔ゆ繝鈧柆宥呯劦妞ゆ帒鍊归崵鈧柣搴㈠嚬閸欏啫鐣峰畷鍥ь棜閻庯絻鍔嬪Ч妤呮⒑閸︻厼鍔嬮柛銊ョ秺瀹曟劙鎮欏顔藉瘜闂侀潧鐗嗗Λ妤呭锤婵犲洦鐓曢悗锝庡亝鐏忕増绻涢懝閭﹀殭闁宠鍨归埀顒婄秵閸嬧偓闁归攱妞藉缁樼瑹閸パ傜敖闂佺ǹ顑嗛惄顖炲箠閻旂⒈鏁嶆繛鎴炵懄閻濈兘姊洪崷顓℃闁哥姵顨婇幃鈥斥槈閵忊€斥偓鍫曟煟閹邦厼绲婚柍閿嬫閺屾洟宕卞Ο鐑樿癁闂佸搫鑻粔鐑铰ㄦ笟鈧弻娑㈠箻閸楃偛顬嬬紓浣戒含閸嬨倕鐣烽崡鐐╂婵☆垳銆嬬槐閬嶆⒒娴e憡鍟炲〒姘殜瀹曘垺銈i崘銊﹁緢闂佹寧妫冮弫顕€宕戦幘璇茬濠㈣泛锕f竟鏇㈡⒒娴e憡鍟炴繛璇х畵瀹曟粌鈽夐姀鐘插亶闂佸綊妫块悞锕傚磹閻㈠憡鐓曢煫鍥ㄦ惄濡茬ǹ霉濠婂牏鐣烘慨濠冩そ閺屽懘鎮欓懠璺侯伃婵犫拃鍐惧殶闁逞屽墲椤煤閹达箑纭€闁告劕妯婇崵鏇灻归悩宸剾闁轰礁娲︾换婵婎槼闁稿氦娅曠粋宥夊箚椤€崇秺閺佹劙宕堕埞搴撳亾婵犲啩绻嗛柟缁樺笧婢ф稑菐閸パ嶈含妞ゃ垺绋戦~婵嬵敆娴e洠鏅犲铏圭磼濮楀棙鐣烽悗鍏夊亾缂佸顑欏ḿ鏍ㄧ箾瀹割喕绨荤€瑰憡绻傞埞鎴︽偐閹绘巻鍋撻幖渚婄稏閹兼番鍔嶉埛鎴犵磼鐎n偒鍎ラ柛搴㈠姍閺岀喖宕ㄦ繝鍕啓濡炪倧绲块崑鎾舵崲濠靛顫呴柨婵嗘閵嗘劕顪冮妶鍡楃仴閻庢凹鍣i獮鎴﹀閵堝懎鑰垮┑鐐村灦閻熝囧储娴犲鈷戦悷娆忓缁舵煡鏌涘锝呬壕缂傚倷闄嶉崝宀勨€﹂悜钘夎摕鐎广儱鐗滃銊╂⒑閸涘﹥灏扮€光偓缁嬭法鏆︾憸鐗堝笒閸ㄥ倹銇勯弮鍌氫壕婵炲牓绠栧娲传閸曨剙绐涢梺鍝ュУ閹告儳顕h閸┾偓妞ゆ巻鍋撻柍瑙勫灴椤㈡瑩寮妶鍕繑闂備礁鎲¢幐濠氭儎椤栫偑鈧礁鈻庨幘鍐茶€垮┑鐐村灦閻熴垽骞忓ú顏呯厽闁绘ê鍘栭懜顏堟煕閺傝儻瀚伴柍璇茬Ч楠炲洭鎮ч崼銏犲箥闂備礁鎲¢崹顖炲磹閺嶎偀鍋撳鐐 (0) +1 闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤濠€閬嶅焵椤掑倹鍤€閻庢凹鍙冨畷宕囧鐎c劋姹楅梺鍦劋閸ㄥ綊宕愰悙鐑樺仭婵犲﹤鍟扮粻鑽も偓娈垮枟婵炲﹪寮崘顔肩<婵炴垶鑹鹃獮鍫熶繆閻愵亜鈧倝宕㈡禒瀣瀭闁割煈鍋嗛々鍙夌節闂堟侗鍎愰柣鎾存礃缁绘盯宕卞Δ鍐唺缂備胶濮垫繛濠囧蓟瀹ュ牜妾ㄩ梺鍛婃尰閻熝呭垝鐠囧樊鍚嬪璺猴功閿涚喖姊绘笟鍥у缂佸顕划濠氼敍閻愭潙鈧敻鏌ㄥ┑鍡涱€楅柡瀣洴閹嘲鈻庡▎鎴犳殼闂佽鍠楅〃濠囧极閹邦厽鍎熼柍鈺佸暟娴滃爼姊绘担铏瑰笡闁规瓕顕х叅闁绘梻鍘ч拑鐔衡偓骞垮劚椤︻垶鎮″☉妯忓綊鏁愰崨顔兼殘闂佽绻戦幐鎼佸煘閹达附鍊烽柤纰卞墮椤e爼姊洪幖鐐插缂傚秴锕ら敃銏℃媴閾忓湱锛滅紓鍌欓檷閸ㄧ懓顕i鈧弻锟犲焵椤掍焦缍囬柍瑙勫劤娴滅偓鎱ㄥΟ鐓庝壕閻庢熬鎷� (0) +1 闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閻愵剙鍔ょ紓宥咃躬瀵鎮㈤崗灏栨嫽闁诲酣娼ф竟濠偽i鍓х<闁绘劦鍓欓崝銈囩磽瀹ュ拑韬€殿喖顭烽幃銏ゅ礂鐏忔牗瀚介梻浣告贡閾忓酣宕板Δ鍜佹晛闁哄稁鍘介埛鎴犵磼鐎n偒鍎ラ柛搴㈠姍閺屾盯濡搁妷锕€浠村Δ鐘靛仜閸燁偉鐏冮梺閫炲苯澧撮柛鈹垮劜瀵板嫭绻涢悙顒傗偓濠氭煟鎼搭垳绉甸柛鎾寸〒缁絽螖娴i绠氶梺缁樺姦娴滄粓鍩€椤掍礁濮嶇€殿喗褰冮オ浼村醇閻旇渹绨甸梻浣芥硶閸犳挻鎱ㄩ幘顔藉珔闁绘柨鍚嬮悡銉︾節闂堟稒锛嶆俊鎻掓憸缁辨帡鎮崨顖溞滈梺鍝勮閸斿矂鍩為幋锕€骞㈡慨妤€鐗忕粈濠冪節绾版ɑ顫婇柛瀣閳ь剚鍑归崰姘i幇鏉跨閻庢稒锚椤庢捇姊洪崨濠勭畵閻庢氨鍏橀崺鈧い鎺嗗亾闁活厼鍊垮璇测槈閵忕姈鈺呮煏婢诡垰鍟伴崢浠嬫煟鎼淬埄鍟忛柛鐘崇墵閳ワ箓鏌ㄧ€b晝绠氶梺褰掓?缁€渚€鎮″☉銏$厱閻忕偛澧介悡顖滅磼閵娿倗鐭欐慨濠勭帛閹峰懘宕ㄩ棃娑氱Ш鐎殿喚鏁婚、妤呭磼濠婂懐鍘梻浣侯攰閹活亞鈧潧鐭傚顐﹀磼閻愬鍙嗛梺缁樻礀閸婂湱鈧熬鎷� (0) +1
闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閻愵剙鍔ゆ繝鈧柆宥呯劦妞ゆ帒鍊归崵鈧柣搴㈠嚬閸欏啫鐣峰畷鍥ь棜閻庯絻鍔嬪Ч妤呮⒑閸︻厼鍔嬮柛銊ョ秺瀹曟劙鎮欏顔藉瘜闂侀潧鐗嗗Λ妤呭锤婵犲洦鐓曢悗锝庡亝鐏忕増绻涢懝閭﹀殭闁宠鍨归埀顒婄秵閸嬧偓闁归攱妞藉缁樼瑹閸パ傜敖闂佺ǹ顑嗛惄顖炲箠閻旂⒈鏁嶆繛鎴炵懄閻濈兘姊洪崷顓℃闁哥姵顨婇幃鈥斥槈閵忊€斥偓鍫曟煟閹邦厼绲婚柍閿嬫閺屾洟宕卞Ο鐑樿癁闂佸搫鑻粔鐑铰ㄦ笟鈧弻娑㈠箻閸楃偛顬嬬紓浣戒含閸嬨倕鐣烽崡鐐╂婵☆垳銆嬬槐閬嶆⒒娴e憡鍟炲〒姘殜瀹曘垺銈i崘銊﹁緢闂佹寧妫冮弫顕€宕戦幘璇茬濠㈣泛锕f竟鏇㈡⒒娴e憡鍟炴繛璇х畵瀹曟粌鈽夐姀鐘插亶闂佸綊妫块悞锕傚磹閻㈠憡鐓曢煫鍥ㄦ惄濡茬ǹ霉濠婂牏鐣烘慨濠冩そ閺屽懘鎮欓懠璺侯伃婵犫拃鍐惧殶闁逞屽墲椤煤閹达箑纭€闁告劕妯婇崵鏇灻归悩宸剾闁轰礁娲︾换婵婎槼闁稿氦娅曠粋宥夊箚椤€崇秺閺佹劙宕堕埞搴撳亾婵犲啩绻嗛柟缁樺笧婢ф稑菐閸パ嶈含妞ゃ垺绋戦~婵嬵敆娴e洠鏅犲铏圭磼濮楀棙鐣烽悗鍏夊亾缂佸顑欏ḿ鏍ㄧ箾瀹割喕绨荤€瑰憡绻傞埞鎴︽偐閹绘巻鍋撻幖渚婄稏閹兼番鍔嶉埛鎴犵磼鐎n偒鍎ラ柛搴㈠姍閺岀喖宕ㄦ繝鍕啓濡炪倧绲块崑鎾舵崲濠靛顫呴柨婵嗘閵嗘劕顪冮妶鍡楃仴閻庢凹鍣i獮鎴﹀閵堝懎鑰垮┑鐐村灦閻熝囧储娴犲鈷戦悷娆忓缁舵煡鏌涘锝呬壕缂傚倷闄嶉崝宀勨€﹂悜钘夎摕鐎广儱鐗滃銊╂⒑閸涘﹥灏扮€光偓缁嬭法鏆︾憸鐗堝笒閸ㄥ倹銇勯弮鍌氫壕婵炲牓绠栧娲传閸曨剙鍋嶉梺鎼炲妼缂嶅﹪骞忛幋锔藉亜闁稿繗鍋愰崢顏呯節閵忥絾纭鹃柣妤€妫濆畷婵嗩潩閼哥數鍘介柟鍏兼儗閸犳牕顕i鑺ュ弿濠电姴鎳忛鐘电磼椤旇姤顥堢€规洖宕灃闁逞屽墴椤㈡梻鈧稒岣跨粻楣冩煕椤愩倕鏋戞い銉ョ墦閺屸€崇暆鐎n剛鏆ら悗瑙勬礃閿曘垽銆侀弮鍫濈妞ゆ帒鍊烽柇顖炴⒒閸屾瑧顦﹂柟纰卞亰閹本寰勫畝鈧粈濠偯归敐鍛棌闁搞倖娲橀妵鍕即濡も偓娴滈箖鎮楃憴鍕闁绘牕鍚嬫穱濠囨倻閽樺娼婇梺缁樏畷顒勊夊鑸碘拻濞撴埃鍋撻柍褜鍓涢崑娑㈡嚐椤栨稒娅犻柟缁㈠枟閻撴盯鎮橀悙鎻掆挃闁靛棙甯¢弻宥堫檨闁告挶鍔庣槐鐐哄幢濞戞ḿ锛涢梺鍛婁緱閸垶鎮炴繝鍐︿簻闁规儳宕悘顏堟煟閹惧啿鏆i柡宀嬬畱铻e〒姘煎灡閳绘挸鈹戦垾鍐茬骇闁诡喖鍊垮璇差吋閸ャ劌鐝伴梺鑲┾拡閸庣柉顦抽柕鍥у婵偓闁愁厼绻愮紞濠呮闁哄鐗冮弲婵堝婵傚憡鐓忓┑鐐茬仢閸旀﹢鏌涚€c劌鐏查柡灞糕偓宕囨殕闁逞屽墴瀹曚即骞囬鍓х暥闂佺粯姊婚崢褔宕归崒娑栦簻闁哄啫鍊甸幏鈩冪箾閻撳酣鍙勯柡宀嬬稻閹棃濡舵惔銏㈢Х婵犵數鍋涘鍫曟晝閵忕姷鏆﹂柡鍥╁枔闂勫嫰鏌℃径濠冾棞婵炲樊鍙冮妴浣割潩鐠鸿櫣鍔﹀銈嗗笒鐎氼剟鎷戦悢鍏肩叆闁绘柨鎼瓭闂佺粯甯掗悘姘跺Φ閸曨垰绠抽柟瀛樼箥娴犻箖姊洪幖鐐测偓鏇犵矓瑜版帒钃熼柡鍥╁枎缁剁偞绻涢幋鐐跺妞ゆ洝浜槐鎾存媴闂堟稑顬堝銈庡幖閸㈡煡锝炶箛鎾佹椽顢旈崟顏嗙倞闂備礁鎲″ú锕傚礈濞嗘垹鐜绘繛鎴欏灪閳锋垹绱掔€n偒鍎ラ柛搴㈠灴閺屾稓鈧絻鍔岄埀顒佺☉铻為柕蹇嬪€栭埛鎴犵磽娴e顏呮叏婢舵劖鐓曢幖瀛樼☉閳ь剚绻傞悾鐑藉箛閺夊灝鐎銈嗗姧缁茶棄顕i崹顔规斀闁宠棄妫楅悘锝夋煕濡姴瀚々鎻捨旈敐鍛殲闁稿﹤鐏氶幈銊ノ熼悡搴濆闁诲孩鐔幏锟�闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閹冣挃闁硅櫕鎹囬垾鏃堝礃椤忎礁浜鹃柨婵嗙凹缁ㄥジ鏌熼惂鍝ョМ闁哄矉缍侀、姗€鎮欓幖顓燁棧闂備線娼уΛ娆戞暜閹烘缍栨繝闈涱儐閺呮煡鏌涘☉鍗炲妞ゃ儲鑹鹃埞鎴炲箠闁稿﹥顨嗛幈銊╂倻閽樺锛涢梺缁樺姉閸庛倝宕戠€n喗鐓熸俊顖濆吹濠€浠嬫煃瑜滈崗娑氭濮橆剦鍤曢柟缁㈠枛椤懘鏌eΟ鑽ゅ灩闁搞儯鍔庨崢閬嶆⒑閺傘儲娅呴柛鐔村妽缁傛帡鏁傞崜褏锛滃銈嗘⒒閹虫挻鏅堕幓鎹涘酣宕惰闊剟鏌熼鐣屾噰妞ゃ垺妫冨畷鐔煎Ω閵夈倕顥氶梻浣告惈缁嬩線宕㈤懖鈺冪焼濠㈣泛鏈崰鎰扮叓閸ャ劍绀€闁搞劍绻傞埞鎴︽偐鐎圭姴顥濈紓浣哄缂嶄線寮婚敐鍛傜喖鎮滃Ο閿嬬亞婵犵妲呴崑鍛垝閹炬剚娼栭柧蹇撴贡閻捇鏌涢埄鍐炬當妞ゅ繐鐡ㄧ换娑㈠醇閻斿摜顦伴梺鍝勭焿缂嶄線鐛Ο灏栧亾濞戞瑡缂氭い锔垮嵆濮婃椽宕崟顓犱紘闂佸摜濮甸悧鐘差嚕婵犳艾鐐婃い鎺嶇劍濞呭洭姊洪柅鐐茶嫰婢ф挳鏌熼鏂よ€块柡灞芥椤撳ジ宕卞▎蹇撶疄闂傚倷绶氬ḿ褔鎮ч崱娑樼閻庯綆鍠栫壕鍧楁煛閸愩劎澧涢柣鎾寸洴閹﹢鎮欐0婵嗘闂侀€炲苯澧紒璇插€块、姘舵晲婢跺﹪鍞堕梺鍝勬川閸嬬喖顢欓崶顒佺厵闁兼祴鏅炶棢闂侀€炲苯澧€殿喛娉涜灒濠电姴娲﹂埛鎺楁煕鐏炲墽鎳呮い锔肩畵閺岀喓鍠婇崡鐐板枈閻庢鍠氶弫濠氥€佸Δ鍛<婵犲﹤鎳愰崢顖炴⒒娴d警鏀伴柟娲讳簽缁骞嬮敂钘変簵闂佺偨鍎查崜姘舵偄閸℃稒鍋i柛婵嗗婵炲洭鏌涢鐘插姎闁告垹濞€楠炴牕菐椤掆偓婵′粙鏌i幘瀵告噰婵﹥妞介、姗€濡歌閺嗙娀姊洪崫鍕靛剭闁稿﹥绻堝璇差吋閸ャ劌鐝伴梺鑲┾拡閸撴盯顢欐繝鍕=濞达絼绮欓崫娲煙閻熺増鎼愰柣锝囧厴楠炴帡骞嬮鐔峰厞婵$偑鍊栭崹鐓幬涢崟顒傤洸闁诡垎灞惧瘜闁诲函缍嗘禍婊堫敆閵忕姭鏀芥い鏍ㄥ搸閸嬨垽鏌″畝瀣?濞寸媴濡囬幏鐘诲箵閹烘埈娼涢梻鍌欑劍閻綊宕愬┑鍫笉闁哄稁鍘奸拑鐔兼煥濠靛棙鍟掗柣鏂跨殱閺嬪酣鏌熼鍡楀閸炴煡姊婚崒娆愮グ婵☆偄瀚板畷顖涘閺夋垹鐛ラ梺鍝勭▉閸樺ジ鎷戦悢鍏肩叆婵犻潧妫Σ鍝ョ磼椤愩垻效闁哄本绋撴禒锔剧磼閵忥紕鏆﹂梺璇插绾板秹鎯勯姘兼綎闁绘垶蓱婵粓鏌熷▓鍨珮婵″樊鍠氱槐鎾存媴閸撳弶楔闂佽桨鐒﹂幃鍌炵嵁閹达箑顫呴柣姗嗗亝閺傗偓闂備焦鎮堕崕顕€寮插┑瀣剨闁割偁鍎查埛鎴犵磼鐎n偄顕滄繝鈧幍顔炬/闁哄娉曟晥闂佽鍠楅敃銏ょ嵁濡偐纾兼俊顖炴敱鐎氬ジ姊绘担鍛婂暈缂佽鍊婚埀顒佸嚬閸欏啴寮鍜佸悑濠㈣泛顑囬崢鍗炩攽閳藉棗鐏″ù婊€绮欏畷鎴﹀閵堝棛鍘撻梺闈涱檧闂勫嫰藟閸懇鍋撶憴鍕闁挎洏鍨介妴浣糕枎閹惧啿绨ユ繝銏n嚃閸ㄦ澘煤閿曞倹鍋傞柡鍥ュ灪閻撴瑩鏌熸担鍐╃彧婵炲懎鎳庨埞鎴︽晬閸曨偄浠橀梺瀹狀潐閸ㄥ潡銆佸▎鎾崇畾鐟滃秹鐛€n亖鏀芥い鏃傘€嬮弨缁樹繆閻愭壆鐭欐鐐插暣閹粓鎸婃径宀勭崜闂備礁婀辨灙閻庡灚甯″畷顒勫Ω閳哄倵鎷绘繛杈剧悼閸庛倝宕甸埀顒勬⒑閹肩偛鈧牠鎮ч悩鑽ゅ祦闊洦绋掗弲鎼佹煥閻曞倹瀚�>>

正在阅读:用Java事件处理机制实现录制回放功能用Java事件处理机制实现录制回放功能

2005-08-25 10:02 出处: 作者:宋荆汉 责任编辑:moningfeng

  目前在一些Java应用程序的GUI测试工具,可以提供捕获用户操作的能力并在代码被修改之后能够自动回放用户的操作。文章将分析Java的事件处理模型及其原理,介绍了基于事件源识别的捕获/回放所需要了解的关键技术并给出了两种实现方式。

  1、 Java事件介绍

  1.1什么是事件

  首先我们来回答"什么是事件"这一基本问题。其实事件本身就是一个抽象的概念,他是表现另一对象状态变化的对象。在面向对象的程序设计中,事件消息是对象间通信的基本方式。

  在图形用户界面程序中,GUI组件对象根据用户的交互产生各种类型的事件消息,这些事件消息由应用程序的事件处理代码捕获,在进行相应的处理后驱动消息响应对象做出反应。我们在GUI上进行叫化操作的时候,在点击某个可响应的对象时如,按钮,菜单,我们都会期待某个事件的发生。

  其实围绕GUI的所有活动都会发生事件,但Java事件处理机制却可以让您挑选出您需要处理的事件。事件在Java中和其他对象基本是一样的,但有一点不同的是,事件是由系统自动生成自动传递到适当的事件处理程序。

  1.2Java事件处理的演变

  当Java的开发者开始解决用Java创建应用程序这一问题时,他们就认识到Java事件模型的必要性。下面对Java事件处理的发展做简要的概括。

  在JDK1.0的版本采用用的事件模型,提供了基本的事件处理功能。这是一种包容模型,所有事件都封装在单一的类Event中,所有事件对象都由单一的方法 handleEvent来处理,这些定义都在Component类中。

  为此,只有Component类的子类才能充当事件处理程序,事件处理传递到组件层次结构,如果目标组件不能完全处理事件,事件被传递到目标组件的容器。

  JDK1.1是编程界的一次革命,修正了前面版本的一些缺陷,同时增加了一些重要的新功能如,RMI、JNI、JDBC、JavaBean。在事件模型上基本框架完全重写,并从Java1.0模型迁移到委托事件模型,在委托模型中事件源生成事件,然后事件处理委托给另一段代码。

  从JDK1.2开始,引入了Swing包事件处理模型功能更强大,更加可定制GUI组件与他们相关联的支持类。在后面的版本基本保持了整个事件模型,但加入了一些附加事件类和接口。在1.3版本开始引入Rebot类,它能模拟鼠标和键盘事件,并用于自动化测试、自动运行演示、以及其他要求鼠标和键盘控制的应用程序。

  我们把JDK1.0事件处理模型成为Java1.0事件模型,而从jdk1.1后的版本事件处理模型称为Java 2事件处理模型。


  2、Java 2事件处理模型

  在Java1.0事件处理模型中事件处理是以如下方法执行的。deliverEvent()用于决定事件的目标,目标是处理事件的组件或容器,此过程开始于GUI层的最外部而向内运作。

  当按一个button时,如果检测到是该按钮激发的事件,该按钮会访问它的deliverEvent()方法,这一操作由系统完成。一旦识别目标组件,正确事件类型发往组件的postEvent()方法,该方法依次把事件送到handleEvent()方法并且等待方法的返回值。

  "true"表明事件完全处理,"false"将使postEvent()方法联系目标容器,希望完成事件处理。

  下面给一个实例:

import java.applet.*;
import java.awt.*;

public class Button1Applet
extends Applet{
public void init()
{
add(new Button("Red"));
add(new Button("Blue"));
}
public boolean action
(Enent evt,Object whatAction)
{
if( !( evt.target
instanceof Button))return false;
String buttonlabel=
(String)whatAction;
if(buttonlabel=="Red")
setBackground(Color.red);
if(buttonlabel==" Blue")
setBackground(Color.blue);
repaint();
return true;
}

}



  在Java2处理事件时,没有采用dispatchEvent()-postEvent()-handleEvent()方式,采用了监听器类,每个事件类都有相关联的监听器接口。事件从事件源到监听者的传递是通过对目标监听者对象的Java方法调用进行的。

  对每个明确的事件的发生,都相应地定义一个明确的Java方法。这些方法都集中定义在事件监听者(EventListener)接口中,这个接口要继承 java.util.EventListener。 实现了事件监听者接口中一些或全部方法的类就是事件监听者。

  伴随着事件的发生,相应的状态通常都封装在事件状态对象中,该对象必须继承自java.util.EventObject。事件状态对象作为单参传递给应响应该事件的监听者方法中。发出某种特定事件的事件源的标识是:遵从规定的设计格式为事件监听者定义注册方法,并接受对指定事件监听者接口实例的引用。

  有时,事件监听者不能直接实现事件监听者接口,或者还有其它的额外动作时,就要在一个源与其它一个或多个监听者之间插入一个事件适配器类的实例,来建立它们之间的联系。我们来看下面一个简单的实例:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class SimpleExample extends JFrame
{
JButton jButton1 = new JButton();

public SimpleExample()
{
try {
jbInit();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public static void
main(String[] args)
{
SimpleExample simpleExample
= new SimpleExample();
}
private void jbInit()
throws Exception {
jButton1.setText
("jButton1");
jButton1.addActionListener(new SimpleExample_jButton1_actionAdapter(this));
jButton1.addActionListener(new SimpleExample_jButton1_actionAdapter(this));
this.getContentPane().add
(jButton1, BorderLayout.CENTER);
this.setVisible(true);
}

void jButton1_actionPerformed
(ActionEvent e)
{
System.exit(0);
}
}

class SimpleExample_jButton1_
actionAdapter implements
java.awt.event.ActionListener
{
SimpleExample adaptee;

SimpleExample_jButton1_actionAdapter
(SimpleExample adaptee)
{
this.adaptee = adaptee;
}
public void actionPerformed(ActionEvent e)
{
adaptee.jButton1_actionPerformed(e);
}
}



  3、事件捕获与回放

  3.1 Java事件生命周期

  Java事件和万事一样有其生命周期,会出生也会消亡。下图3.1给出了Java事件生命周期的示意图:


  事件最初由事件源产生,事件源可以是GUI组件Java Bean或由生成事件能力的对象,在GUI组件情况下,事件源或者是组件的同位体(对于Abstract Window Toolkit[awt]GUI组件来说)或组件本身(对于Swing组件来说)。

  事件生成后放在系统事件队列内部。现在事件处于事件分发线程的控制下。事件在队列中等待处理,然后事件从事件队列中选出,送到dispatchEvent()方法,dispatchEvent()方法调用processEvent()方法并将事件的一个引用传递给processEvent()方法。

  此刻,系统会查看是否有送出事件的位置,如果没有这种事件类型相应的已经注册的监听器,或者如果没有任何组件受到激活来接收事件类型,事件就被抛弃。当然上图显示的是AWTEvent类的子类的生命周期。 dispatchEvent()方法和processEvent()方法把AWTEvent作为一个参数。但对,javax.swing.event并不是AWTEvent子类,而是从EventObject直接继承过来,生成这些事件的对象也会定义fireEvent()方法,此方法将事件送到包含在对象监听器列表内的那种类型的任何监听器。

  3.2 Java事件捕获

  从上面的分析我们知道,任何事件产生到dispatchEvent()方法分发方法前,所有的事件都是存放在系统事件的队列中,而且所有的事件都由dispatchEvent()方法来分派。所以只要能重载dispatchEvent()方法就可以获取系统的所有事件,包括用户输入事件。一般来说,系统事件队列的操作对用户来说是可以控制。它在后台自动完成所要完成的事情,使用EventQueue类可以查看甚至操纵系统事件队列。

  Java提供了EventQueue类来访问甚至操纵系统事件队列。EventQueue类中封装了对系统事件队列的各种操作,除dispatchEvent()方法外,其中最关键的是提供了push()方法,允许用特定的EventQueue来代替当前的EventQueue。

  只要从EventQueue类中派生一个新类,然后通过push()方法用派生类来代替当前的EventQueue类即可。这样,所有的系统事件都会转发到派生EventQueue类。

  然后,再在派生类中重载dispatchEvent()方法就可以截获所有的系统事件,包括用户输入事件。下面一段代码给出一个操纵EventQueue的实例:

import java.awt.*;
import java.awt.event.*;

public class GenerateEventQueue
extends Frame implements ActionListener
{
Button button1 = new Button();
TextField textField1 = new TextField();

public GenerateEventQueue()
{
try {
jbInit();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
GenerateEventQueue generateEventQueue
= new GenerateEventQueue();
}
private void jbInit() throws Exception
{
button1.setLabel("button1");
button1.addActionListener(this) ;
textField1.setText("textField1");

this.add(button1,
BorderLayout.SOUTH);
this.add(textField1,
BorderLayout.CENTER);
EventQueue
eq=getToolkit().getSystemEventQueue() ;
eq.postEvent(new ActionEvent(button1,
ActionEvent.ACTION_PERFORMED,"test" )) ;
addWindowListener(new WinListener());
setBounds(100,100,300,200);
setVisible(true);
}

public void actionPerformed(ActionEvent e)
{
textField1.setText("event is
:"+e.getActionCommand()) ;
}

}

class WinListener extends WindowAdapter
{
public void windowClosing(WindowEvent we)
{
System.exit(0) ;
}
}



  运行结果如下图所示:



  在文本域中首先出现的是"event is:test",这是因为首先得到处理的是EventQueue对象发送到系统事件队列上的ActionEvent。

  下面的代码简单说明了如何捕获事件:

import java.awt.EventQueue;
import java.awt.*;
import java.util.*;
public class MyQueueEvent extends EventQueue
{
//定义EventQueue的子类
public MyQueueEvent()
{
}
public static void main(String[] args)
{
SimpleExample.main(new String[]{null}) ;
MyQueueEvent myQueueEvent1
= new MyQueueEvent();
Toolkit.getDefaultToolkit().
getSystemEventQueue().push(myQueueEvent1) ;
}
//在这里重载事件分发的方法
public void dispatchEvent(AWTEvent ae)
{

if(ae.getSource()
instanceof javax.swing.JButton)
System.out.println
("My apture:"+((javax.swing.JButton)
ae.getSource()).getText()) ;
super.dispatchEvent(ae);
}


  这个程序可以打印出当前应用的所有的事件,可以将这些事件中选出你需要的事件保存当然你还需要解析该控件的特征。在上面加黑部分的代码,打印事件源控件的名称。

  除此之外,还可以通过实现java.awt.event. AWTEventListener接口实现对事件的捕获。这个侦听器接口可以接收Component or MenuComponent以及它们的派生类在整个系统范围内所分发的事件,AWTEventListeners只是被动的监控这些事件。

  如果要监控系统事件,除了要实现接口,还要用Toolkit的addAWTEventListener方法注册这个侦听器。

  下面我们来看一个实例:

import java.awt.AWTEvent;
import java.awt.Frame;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.AWTEventListener;
import java.awt.event.WindowEvent;

import java.util.ArrayList;
import java.lang.ref.WeakReference;
public class MyAWTEventListener
implements AWTEventListener
{
private static MyAWTEventListener
s_singleton = null;
//保证该类只被初始化一次
public static
MyAWTEventListener getInstance()
{
if(s_singleton==null)
{
s_singleton=new MyAWTEventListener();
}
return s_singleton;
}
private MyAWTEventListener()
{
//注意下面这行代码,如果没有这行代码,
将无法接收到系统分发的事件
// 下面代码在注册时,
只请求了接收WINDOW_EVENT_MASK事件
//但实际上,
你可以接收其他AWTEvent中定义的事件类型
Toolkit.getDefaultToolkit().addAWTEventListener
(this,
AWTEvent.COMPONENT_EVENT_MASK
);
}
/*
这就是接口方法的实现
*/
public void eventDispatched
(final AWTEvent theEvent)
{
processEvent(theEvent);
}
private static void processEvent
(final AWTEvent theEvent)
{
System.out.println
(theEvent.getSource() ) ;
//打印事件源
switch (theEvent.getID())
{
case WindowEvent.WINDOW_OPENED:
//System.out.println
(((Frame)theEvent.getSource()).getTitle() ) ;
case WindowEvent.WINDOW_ACTIVATED:
case WindowEvent.WINDOW_DEACTIVATED:
case WindowEvent.WINDOW_CLOSING:
default: break;
}
}
}



  3.3 Java事件回放

  事件的回放其实比较简单了,比如我们现在记录的是frame1下的jButton1点击事件回放。看下面一段简单的程序,只要点一下jButton1,就在控制台打印一次"click me"的字符串。

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class Frame1 extends JFrame
{
private JButton jButton1
= new JButton();

public Frame1()
{
try {
jbInit();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public static void
main(String[] args)
{
Frame1 frame1 = new Frame1();
frame1.setVisible(true) ;

}
private void jbInit()
throws Exception
{
jButton1.setText("jButton1");
jButton1.addActionListener
(new java.awt.event.ActionListener()
{
public void actionPerformed
(ActionEvent e)
{
jButton1_actionPerformed(e);
}
});
this.setTitle("Test");
this.getContentPane().add(jButton1,
BorderLayout.CENTER);
}

void jButton1_actionPerformed
(ActionEvent e)
{
System.out.println("click me") ;
}
}


  下面是回放的程序,在下面的程序中用到了java.awt.Robot类,这个类通常用来在自动化测试或程序演示中模拟系统事件,在某些需要控制鼠标或键盘的应用程序中这个类也是很有用,这个类主要的目的就是为方便的实现Java的GUI自动化测试平台。

  在事件回放时,我们同样需要该类来模拟生成系统的事件,完成记录的操作的回放,在下面的代码中,给出了一个简单的例子。

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class TestReplay extends Thread
{
public static void
main(String[] args)
{
try{
//启动要回放的应用程序
Frame1.main(new String[]{null}) ;
//等应用程序启动后延迟3秒再进行回放
Thread.currentThread().sleep(3000) ;
Robot robottest=new Robot();
robottest.waitForIdle();
//根据标题名获取当前应用的主窗体,
在本例中为"test"
Frame jframe=getFrame("test");;
//根据给定的窗体和窗体中要
find的控件的名称来获取控件的引用
JButton jbtn=getButton(jframe,"jButton1");
//将鼠标移到控件所在的位置
robottest.mouseMove
(jbtn.getLocationOnScreen().
x+jbtn.getWidth()/2
,jbtn.getLocationOnScreen().
y+jbtn.getHeight()/2) ;
//在控件所在位置,生成鼠标点击事件
robottest.mousePress
(InputEvent.BUTTON1_MASK ) ;
robottest.mouseRelease
(InputEvent.BUTTON1_MASK ) ;
}catch(Exception ee){
ee.printStackTrace() ;
}
}
//获得标题为title的frame
private static Frame
getFrame(String title)
{
Frame[] jframes=(Frame[])
JFrame.getFrames();
for(int i=0;i i++)
{
if(jframes[i].getTitle().
equalsIgnoreCase(title))return jframes[i];
}
return null;

}
//获取某一个frame下的某个名为jButton1的控件
private static JButton
getButton(Frame jf,String text)
{
/*注意下面这行代码,因为实例比较简单
只有ContentPane一个Container类型的控件,
如果在JFrame中有多个Container控件
//的话,必须进行递归处理,搜索出所有的控件
*/
Component[] coms=((JFrame)jf).
getContentPane().getComponents();
for(int i=0;i i++)
{
if(!(coms[i] instanceof
JButton))continue;
if(((JButton)coms[i]).
getText().equalsIgnoreCase(text))
return (JButton)coms[i];
}
return null;
}
public void run(){

}
}


  该程序运行完,你会发现在控制台同样打印出了:

  "click me"的字符串说明事件被正确回放了。

  当然还可以通过直接操纵系统事件队列实现输入事件的回放。先通过记录下的窗口/组件名获得对应窗口引用,然后重构鼠标/键盘事件,最后将重构的事件直接放入系统事件队列,由分派线程执行后续的事件分派工作。

  还需要解决关键问题如何能根据窗口名称获得其引用。这里还是可以通过系统事件队列来实现的,因为Java程序在新建/删除一个容器时都会向系统事件队列发出一个Containerevent事件,其中包含了对该容器的引用。

  所以,事件回放器在载入被测测试程序后便监视系统队列,截获所有的Containerevent事件。如果新建容器,便获得新建Container的引用。因为所有的Container都实现了getComponets(),可以返回所有该容器所包含的组件或容器,只需要保存到一个HashMap结构中,需要时检索出来就可以了。

  该过程所用到的知识,其实在上面都有提到而且在实际引用中,既然Robot已经帮我们完成许多事情,也没有必要自己再去重构一个鼠标或键盘事件了,不过有兴趣的朋友也可以去试试。

  4、结束语

  随着我国软件业的发展,软件测试技术作为软件质量保证的重要环节越来越受到重视,而在基于GUI的应用中采用自动化测试工具可以提高软件测试的有效性和效率,特别在回归测试中可以大大减少人力投入,还可以提高测试脚本的复用。

  因此,软件自动测试平台开发已经成为软件测试的一个重要领域。本文介绍了基于Java的GUI应用的自动测试平台开发需要的基本但关键的捕获、回放功能,所有相关系统开发其实都离不开本文说的方法。

关注我们

最新资讯离线随时看 聊天吐槽赢奖品
闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閹冣挃闁硅櫕鎹囬垾鏃堝礃椤忎礁浜鹃柨婵嗙凹缁ㄥジ鏌熼惂鍝ョМ闁哄矉缍侀、姗€鎮欓幖顓燁棧闂傚倸娲らˇ鐢稿蓟閵娿儮鏀介柛鈩冪懃椤も偓婵$偑鍊曠换鎺撴叏妞嬪孩顫曢柟鐑橆殔閻掑灚銇勯幒宥堝厡缂佲檧鍋撻梻浣呵归張顒勩€冮崱娑樻闁逞屽墴濮婄粯鎷呴搹鐟扮闁藉啳浜幉鎼佸级閸喗娈婚梺绯曟杹閸嬫挸顪冮妶鍡楀潑闁稿鎸婚妵鍕即閵娿儱绠诲┑鈥冲级閸旀瑩鐛鈧獮鍥ㄦ媴閻熸澘鍘為梻浣告惈椤︻垶鎮ч崟顖氱鐎光偓閸曨偄鍤戦梺纭呮彧闂勫嫰鍩涢幋锔界厱婵犻潧妫楅鈺呮煛閸℃ḿ鎳囬柡宀嬬到铻栭柍褜鍓涢埀顒佺煯閸楀啿鐣峰ú顏勭劦妞ゆ帊闄嶆禍婊堟煙鏉堝墽绋荤痪顓炲缁辨帡骞囬鐔叉嫽闂侀€炲苯澧い鏃€鐗犲畷浼村即閻樻彃鐏婂┑鐐叉閹稿爼鍩€椤戣法顦︽い顐g矒閸┾偓妞ゆ帒瀚粻鏍ㄧ箾閸℃ɑ灏伴柛銈嗗灴閺屾盯濡搁敂閿婵炲瓨绮撶粻鏍蓟濞戔懇鈧箓骞嬪┑鍥╀簮闂備浇銆€閸嬫挸霉閻樺樊鍎愰柣鎾卞劜缁绘盯骞嬮悘娲讳邯椤㈡棃鍩℃导鍗炵秺閹晛鈻庤箛鏂挎缂佺偓鍎抽崥瀣Φ閸曨垰鍗抽柣鎰綑濞咃綁姊虹拠鏌ョ崪濠碘€虫喘閸┾偓妞ゆ帊绶¢崯蹇涙煕閿濆骸娅嶇€规洘鍨剁换婵嬪炊瑜忛悾娲⒑閸愬弶鎯堥柛鐔稿婢规洟宕楅梻瀵哥畾濡炪倖鐗滈崑鐐哄极闁秵鍊垫慨姗嗗厵閸嬨垺鎱ㄦ繝鍌ょ吋鐎规洘甯掗埢搴ㄥ箣閿濆洨宕堕梻鍌欒兌鏋い鎴濇噹铻炴繝闈涙閺嗭箓鏌熺€涙ḿ濡囨俊鎻掔墦閺屾洝绠涙繛鎯т壕闁惧浚鍋掗崥鍛攽閿涘嫬浜奸柛濠冪墵閹兾旈崘顏嗙厯闂佸湱鍎ら崹鐔煎几瀹ュ鐓熸俊顖濆亹鐢盯鏌i幘瀵告噮缂佽鲸鎸婚幏鍛存濞戞矮鎮i梻浣告惈椤戝洭宕伴弽顓炶摕闁挎繂顦粻濠氭倵闂堟稒鍟為柛锝庡弮濮婃椽妫冨☉娆愭倷闁诲孩纰嶅姗€顢氶敐澶樻晪闁逞屽墴瀹曟椽鍩€椤掍降浜滈柟鐑樺灥椤忔挳鏌℃担绋款仾缂佺粯鐩畷鍗炍旈崘顏嗘毉缂傚倸鍊搁崐鐟扮暆閹间礁钃熼柣鏃傚帶缁犮儲銇勯弮鍌楁嫛闁哄棭鍙冨铏圭磼濡闉嶉梺鑽ゅ暀閸パ呭姦濡炪倖甯掗崐褰掑吹閳ь剟鏌f惔銏犲毈闁哥姵顨婂鑼崉娴f洘妫冨畷銊╊敇閻愭潙鍔掗梻鍌欑劍閹爼宕曢鈧顒佺瑹閳ь剙鐣烽幋锕€绠婚柤鎼佹涧閺嬪倿姊洪崨濠冨闁告挻鐩弫宥咁潨閳ь剙顫忓ú顏勫窛濠电姴鍟伴崣鍡欑磽娴e壊妲搁柣鏍с偢閻涱噣骞嬮敃鈧~鍛存煟濮楀棗浜濋柡鍌楀亾闂備浇顕ч崙鐣岀礊閸℃ḿ顩查柣鎰劋閺咁剚绻濇繝鍌氭殜闁衡偓娴犲鐓熼柟閭﹀墮缁狙勩亜閵壯冧槐闁哄本鐩顕€鍩€椤掑嫭鍋嬮柣妯款嚙閺勩儵鏌曡箛瀣偓鏇㈠础閹惰姤鐓熼柡鍐ㄦ处椤忕娀鏌i敃鈧悧鎾愁潖閸濆嫅褔宕惰娴煎牆鈹戦悙鏉垮皟闁告劏鏅滈惁搴㈢節绾板纾块柛瀣灴瀹曟劘顦寸紒杈╁仱閸┾偓妞ゆ帊妞掔换鍡樸亜閹扳晛鐏╂い蹇婃櫇閳ь剝顫夐幐鍝モ偓姘緲椤繐煤椤忓嫬绐涙繝鐢靛Т鐎氀勬叏閸パ€鏀介柣鎰絻閹垿鏌i悢婵嗗閻濆爼鏌¢崶鈺佹灁缂佲檧鍋撴繝娈垮枟閿曗晠宕㈡ィ鍐ㄥ偍闁汇垹鎲¢埛鎴犵棯椤撶偞濯兼繛鍏煎姍閺屾盯寮幘鍓佹殼閻庤娲熷ḿ褔鍩㈡惔銊ョ闁绘ḿ顣槐鏌ユ⒒娴h櫣甯涢柣鐔村灲瀹曟垿骞樼紒妯煎幈闂侀潧枪閸庢娊宕洪敐鍥e亾濞堝灝鏋涙い顓㈡敱娣囧﹪骞栨担鍝ュ幐闂佺ǹ鏈惌顔捐姳娴犲鈷掑ù锝呮嚈瑜版帒瀚夋い鎺戝€婚惌娆撴煙鏉堟儳鐦滈柡浣稿€块弻銊╂偆閸屾稑顏�闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閻愵剙鍔ょ紓宥咃躬瀵鏁愭径濠勵吅闂佹寧绻傞幉娑㈠箻缂佹ḿ鍘辨繝鐢靛Т閸婂綊宕戦妷鈺傜厸閻忕偠顕ф慨鍌溾偓娈垮枟閹告娊骞冨▎寰濆湱鈧綆浜欐竟鏇㈡⒑閸涘﹦缂氶柛搴ゆ珪缁嬪顓兼径瀣幐閻庡箍鍎辨鎼佺嵁濡ゅ懏鐓熼柟鎯х摠缁€鍐煏閸パ冾伃妤犵偛娲畷婊勬媴閼介攱鍨圭槐鎾存媴閹绘帊澹曢梻渚€鈧偛鑻晶鎵磼鏉堛劌娴柟顔界懇椤㈡鍩€椤掑嫬绀夐柕鍫濇缁犲墽鐥銏╂缂佲檧鍋撻柣搴㈩問閸犳牠鈥﹂悜钘夌畺闁靛繈鍊栭崑鍌炲箹鏉堝墽鎮奸柡鍡曞嵆濮婄粯鎷呴搹鐟扮濡炪們鍔岄幊姗€骞冭楗即宕楅悙顒傛创鐎规洜鍠栭、姗€鎮╃喊澶屽簥闂傚倷娴囬鏍垂鎼淬劌绀冮柨婵嗘閻﹁京绱撻崒姘偓椋庢閿熺姴闂い鏇楀亾鐎规洖缍婇獮搴ㄦ寠婢跺矈鍞归梻渚€娼х换鎺撴叏椤撶倣锝夊醇閵夛妇鍘棅顐㈡处濞叉牕鏆╂俊鐐€栭幐鎼佸箹椤愶箑鐓橀柟杈鹃檮閸婄兘鏌涘▎蹇f▓婵☆偆鍋熺槐鎾存媴閾忕懓绗¢柣銏╁灡椤ㄥ牏鍒掔€n喖绠抽柟鎯х埣濡绢噣姊洪崨濠勨槈閼瑰矂鏌熼柨瀣仢婵﹥妞藉畷銊︾節閸曨厾鏆ら梺璇插閸戝綊宕滈悢绗衡偓渚€寮崼婢劑鏌嶉崫鍕偓濠氬储闁秵鐓欓柤鍦瑜把呯磼閺屻儳鐣虹€殿喗濞婇、妤佺瑹閸ヮ煈鍟嶉梻浣虹帛閸旀牞銇愰崘顔兼辈婵炲棙鍔戞禍婊勩亜閹板墎鎮奸柣顓熷浮閺屾盯鍩為幆褌澹曞┑锛勫亼閸婃牜鏁幒鏂哄亾濮樼厧澧扮紒顔碱煼瀵粙濡歌椤旀洟姊虹化鏇炲⒉閽冮亶鎮樿箛锝呭箻缂佽鲸甯¢幃顏勨枎韫囨柨顦╅梺缁樻尰濞叉﹢濡甸崟顖f晣闁绘棃顥撴禒鎾⒑閸濆嫷鍎嶉柛濠冾殜楠炲骞栨担鐟颁罕闂佸壊鍋呯换鍕閹绢喗鈷戦悗鍦濞兼劙鏌涢妸銉﹀仴妤犵偛鍟埢搴ㄥ箻閺夋垶顓绘俊鐐€栫敮濠囨倿閿曞倸绐楅柡宥庡亞绾句粙鏌涚仦鍓ф噮閻犳劒鍗抽弻娑㈡偐瀹曞洤鈷堢紓渚囧枟濡啫鐣锋總绋垮嵆闁绘劖顔栧Σ鎾⒒娴e憡璐¢柛搴涘€濋妴鍐川椤栨粈绗夋繝鐢靛У绾板秹宕戦敐澶嬬厱闁靛鍠曠花濠氭煢閸曨偁鍋㈤柡宀€鍠栭幊鐐哄Ψ閿旂虎妲梻浣哥枃椤宕归崸妤€绠栨繛鍡樻尭缁狙囨煙鐎电ǹ小闁瑰鍏樺缁樻媴閾忓箍鈧﹪鏌¢崨顔俱€掗柍褜鍓氱喊宥咁熆濮椻偓椤㈡岸鏁愭径妯绘櫇闂佹寧娲嶉崑鎾剁磼閳ь剟宕橀埞澶哥盎闂佸搫鍟崐鐟扳枍閺囥垺鐓曟繛鍡楃箲椤ユ粓鏌嶇憴鍕伌闁诡喒鏅濈槐鎺懳熸繝姘殬濠电姷顣藉Σ鍛村磻閸涘瓨鍋¢柍鍝勫閿涘倿姊绘担铏瑰笡瀹€锝呮健瀹曟垿濡搁敂缁㈡锤濠电姴锕ら悧濠囨偂閵夆晜鐓涢柛灞剧☉椤曟粓鏌熼姘卞ⅵ闁哄本鐩顕€骞樼紒姗嗏偓宥夋⒑闁稓鈹掗柛鏂跨Ф閹广垹鈹戠€n亞顦ㄩ梺宕囨嚀閵囨﹢鎼规惔銊︾厽閹兼番鍊ゅḿ鎰箾閹绘帞绠荤€规洘绻傞濂稿炊閵娿儱绨ユ繝鐢靛█濞佳囶敄閸涱垳鐭嗛柛鎰靛枟閻撶喖鏌熸导瀛樻锭濠⒀呯帛娣囧﹪顢曢敐鍥╃杽濠殿喖锕ら…宄扮暦閹烘垟鏋庨柟鐑樺灥鐢垶姊绘担渚敯婵炲懏娲熼獮鎴﹀炊瑜忛弳锕傛煟閵忊懚褰掑礃閳ь剙顪冮妶鍡樺暗闁稿鍠栭、娆撳幢濞戞瑢鎷洪柣鐘充航閸斿苯鈻嶉幇鐗堢厵闁告垯鍊栫€氾拷