闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閹冣挃闁硅櫕鎹囬垾鏃堝礃椤忎礁浜鹃柨婵嗙凹缁ㄥジ鏌熼惂鍝ョМ闁哄矉缍侀、姗€鎮欓幖顓燁棧闂備線娼уΛ娆戞暜閹烘缍栨繝闈涱儐閺呮煡鏌涘☉鍗炲妞ゃ儲鑹鹃埞鎴炲箠闁稿﹥顨嗛幈銊╂倻閽樺锛涢梺缁樺姉閸庛倝宕戠€n喗鐓熸俊顖濆吹濠€浠嬫煃瑜滈崗娑氭濮橆剦鍤曢柟缁㈠枛椤懘鏌eΟ鑽ゅ灩闁搞儯鍔庨崢閬嶆煟韫囨洖浠滃褌绮欓幃锟狀敍濮樿偐鍞甸柣鐔哥懃鐎氼厾绮堥埀顒勬⒑鐎圭媭娼愰柛銊ユ健閵嗕礁鈻庨幋鐘碉紲闂佽鍎虫晶搴g玻濡ゅ懏鈷掑ù锝呮啞閸熺偞銇勯鐐搭棦鐎规洘锕㈤弫鎰板幢濞嗗苯浜炬繛宸簼閸婂灚顨ラ悙鑼虎闁告梹纰嶇换娑㈡嚑椤掆偓閳诲牏鈧娲橀崹鍧楃嵁濮椻偓閹虫粓妫冨☉娆戔偓顓㈡⒒娴e憡鍟炴繛璇х畵瀹曟粌鈽夐埗鍝勬喘椤㈡﹢鎮㈤搹鍦闂備礁鍟块惃婵嬪磻閹剧粯鐓曢柡鍥╁仧娴犳盯鏌i妶鍕槮閾绘牠鏌e鈧ḿ褎绂掑⿰鍕箚妞ゆ劧绲跨粻鎾淬亜閺囶亞绉い銏″哺閸┾偓妞ゆ巻鍋撻柣锝囧厴閹剝鎯旈鎯ф暩婵$偑鍊曠换瀣倿閿曗偓閳诲秵绻濋崶銊у幍濡炪倖姊婚悺鏂库枔濠婂牊鐓涘ù锝囨嚀婵牓鏌熼娑欑叆闁宠鍨垮畷鐓庘攽閸℃ḿ妲楅梻鍌欐祰椤曆兠归悜钘夌疇闁规崘顕х粻鐔兼煥濞戞ê顏€规洘鐓¢弻娑㈠即閵娿儱绠哄銈庡亝濞茬喖寮婚悢鍏煎€绘俊顖濐嚙闂夊秶绱撻崒姘毙㈡繛宸弮瀵寮撮悢铏诡啎闂佸壊鐓堥崰鏍ㄦ叏閵忋倖鈷戦柤濮愬€曢弸鍌炴煕閺傝法鐒搁柍銉︽瀹曟﹢顢欓崲澹洤绠圭紒顔煎帨閸嬫捇鎳犻鈧崵顒傜磽閸屾艾鈧娆㈤敓鐘茬獥婵°倕鎳庣粻浼存煙闂傚鍔嶉柛瀣ф櫊閺岋綁骞嬮敐鍡╂缂佺虎鍘搁崑鎾绘⒒娴h櫣甯涢柛鏃€娲滅划鏃堝醇閺囩偟鐛ラ梺鍝勭▉閸樿偐绮婚弽銊х闁糕剝蓱鐏忣厾绱掗悪鍛ɑ缂佺粯绻堝Λ鍐ㄢ槈濞嗘劖鍊锋俊鐐€ч懙褰掑疾閻樺樊娼栨繛宸簻缁狀噣鏌ら幁鎺戝姕闁哄棛濞€濮婃椽骞栭悙鎻掝瀳濠电姭鍋撻柛妤冨€i敐澶婄疀闁哄娉曢鎺楁煟鎼淬垻鈯曢柨姘亜鎼淬垺灏扮紒缁樼箓閳绘捇宕归鐣屼憾闂備胶纭堕弲娑㈡偋婵犲嫮鐭夌€广儱鎳夐弨浠嬫倵閿濆簼绨介柣銈呭濮婃椽妫冨ù銉ョ墦瀵彃鈽夐姀鈥斥偓宄扳攽閻樺弶澶勯柣鎾崇箰閳规垿鎮欓懠顑胯檸闂侀€炲苯澧い銊ョ墢閸掓帞鎷犲顔藉兊濡炪倖甯掗ˇ鎵偓闈涚焸濮婃椽妫冨☉姘暫濠碘槅鍋呯粙鎺楀疾閸洦鏁嗛柛鏇ㄥ墰閸樹粙姊洪崫鍕殲闁搞劌鐏氶弲鍫曞箻椤旂晫鍘介梺鐟扮仢閸燁偅鏅剁€涙ǜ浜滈柕蹇婃濞堟粎鈧娲樼敮鎺曠亙闂侀€炲苯澧紒鍌氱У閵堬綁宕橀埡浣风敾婵犵數鍋涘Λ妤冩崲閹伴偊鏁傛い蹇撴濡垶鏌i幇闈涘闁稿﹥鍔欓弻锛勪沪閸撗€濮囬梺璇″灡濡啴寮幇鏉垮耿婵☆垵宕靛Σ妤呮⒑鐠囨彃顒㈡い鏃€鐗犲畷鎶筋敋閳ь剙鐣烽幋鐐电瘈闁搞儮鏅涚粊锕€鈹戦埥鍡楃仴闁稿鍔楁竟鏇㈠礂闂傚绠氬銈嗙墬缁海鏁☉娆嶄簻闊洦娲栭弸娑欐叏婵犲嫮甯涢柟宄版嚇閹崇偤濡疯閳ь剙锕娲閳哄啰肖缂備胶濮甸幑鍥偘椤旇法鐤€婵炴垶鐟﹀▍銏ゆ⒑鐠恒劌娅愰柟鍑ゆ嫹濠电姷鏁告慨鐑藉极閸涘﹥鍙忛柣鎴f閺嬩線鏌涘☉姗堟敾闁告瑥绻橀弻锝夊箣閿濆棭妫勯梺鍝勵儎缁舵岸寮诲☉妯锋婵鐗婇弫楣冩⒑閸涘﹦鎳冪紒缁橈耿瀵鏁愭径濠勵吅闂佹寧绻傚Λ顓炍涢崟顖涒拺闁告繂瀚烽崕搴g磼閼搁潧鍝虹€殿喖顭烽幃銏ゅ礂鐏忔牗瀚介梺璇查叄濞佳勭珶婵犲伣锝夘敊閸撗咃紲闂佺粯鍔﹂崜娆撳礉閵堝棎浜滄い鎾跺Т閸樺鈧鍠栭…鐑藉极閹邦厼绶炲┑鐘插閺夊憡淇婇悙顏勨偓鏍暜婵犲洦鍊块柨鏇炲€哥壕鍧楁煙閹冾暢缁炬崘妫勯湁闁挎繂鎳忛幆鍫焊韫囨稒鈷戦柛娑樷看濞堟洖鈹戦悙璇у伐妞ゆ洩绲剧换婵嗩潩椤撶偘绨婚梻浣呵圭换鎰版儍閻戣棄绠┑鐘崇閻撶喖骞栧ǎ顒€濡芥繛鎳峰喚鐔嗛柣鐔峰簻瀹搞儵宕℃潏銊d簻闁哄倸鐏濋埛鏃傜棯閹规劖顥夐棁澶愭煥濠靛棙鍣洪柟顖氱墦瀹曨垶骞栨担鍏夋嫼闂佸憡绺块崕杈ㄧ墡闂備胶绮〃鍫熸叏閹绢噮鏁嬮柨婵嗘缁♀偓濠殿喗锕╅崕鐢稿煛閸涱喚鍘撻梺鍛婄箓鐎氼剟鍩€椤掆偓閹诧紕绮嬪鍛牚闁割偆鍟块幏娲⒑閸涘﹦鈽夐柨鏇缁骞樼紒妯衡偓鍨叏濮楀棗澧柛銈呮搐閳规垿顢欓悷棰佸闂傚倷绶氬ḿ褔鎮ч崱妞㈡稑鈽夐姀鐘插亶闂備緡鍓欑粔鐢稿煕閹达附鈷掗柛顐ゅ枙閸庢劗鎲搁悧鍫濈瑨缁炬儳娼″娲敆閳ь剛绮旈幘顔藉€块柛顭戝亖娴滄粓鏌熼崫鍕棞濞存粍鍎抽埞鎴︽偐椤愵澀澹曢梻鍌欑贰閸撴瑧绮旂€靛摜涓嶉柡灞诲劜閻撳繘鐓崶銊︾鐞氥儱鈹戦埄鍐ㄧ祷闁绘鎹囧濠氬即閿涘嫮鏉搁梺鍝勬川閸婎偊濮€閵堝棛鍘鹃梺鍝勵槼濞夋洘绂掗姀銈嗙厓閻熸瑥瀚悘鎾煕閳瑰灝鍔︾€规洖宕灃闁告剬鍕枙婵犵绱曢崑鎴﹀磹閺嵮€鏋栭柨鏇炲€搁悙濠冦亜椤撶喎鐏︽い銉ヮ樀閺岋絾鎯旈敍鍕殯闂佺ǹ閰f禍鎯版婵炴潙鍚嬪ḿ娆撴偂閺囥垺鐓欓悗鐢登瑰暩缂佺偓鍎抽妶鎼佸箖濡ゅ懏鏅查幖绮光偓鑼跺焻闂備胶枪缁ㄦ椽宕曢悽绋胯摕婵炴垶鐟﹂崕鐔兼煏韫囨洖孝妞ゎ偄娴风槐鎾存媴娴犲鎽甸柣銏╁灣閸嬨倝鐛箛娑欏亹閻犲洩灏欓宀勬⒑閸︻厼鍔嬮柟绋款煼椤㈡瑩骞掗幋鏃€鏂€闂佺粯蓱椤旀牠寮冲⿰鍛<閺夊牄鍔嶇粈瀣偓娈垮櫘閸嬪棝骞忛悩缁樺殤妞ゆ帊鐒﹂鏇㈡⒒娴h櫣甯涙慨濠傤煼閸╂盯宕奸妷銉︾€悗骞垮劚濡瑩宕h箛鏂剧箚妞ゆ牗鍝庢禒鎺楁煕濮樼厧浜伴柡灞稿墲瀵板嫮鈧綆鍋勯埀顒佸姈閹便劍绻濋崟顓炵闂佺懓鍢查幊妯虹暦椤愶箑唯闁挎棃鏁崑鎾活敊鐏忔牗鏂€闂佹枼鏅涢崯銊︾閻樼粯鐓曢柡鍌氭健閸欏嫭顨ラ悙鑼闁逞屽墾缂嶅棝宕伴弽顓熷珔闁绘柨鍚嬮悡蹇擃熆鐠鸿櫣澧曢柛鏂诲€濋弻銊モ槈濞嗘垶鍒涘┑顔硷龚濞咃綁骞夐幘顔肩妞ゆ劑鍊ゅΣ鐗堜繆閻愵亜鈧牕鈻旈敃鍌氱倞鐟滃繘藝閵娾晜鈷戦梺顐ゅ仜閼活垱鏅堕幘顔界厵妞ゆ梻鍘уΣ缁橆殰椤忓啫宓嗙€规洘锕㈤幃娆擃敄閼恒儳鈧即姊虹拠鎻掝劉妞ゆ梹鐗犲畷鏉课旈崨顓犵暫闂佺ǹ鏈崙褰掑吹閺囩喆浜滈柡鍥殔娴滈箖鎮楃憴鍕闁靛牊鎮傞獮鍐閵堝懍绱堕梺鍛婃处閸嬪懏娼忛崼銉︹拻闁稿本鑹鹃埀顒傚厴閹虫宕滄担绋跨亰濡炪倖鐗楅銏犆洪鍕敤濡炪倖鎸鹃崑鐔兼晬濞嗘挻鈷戦梻鍫氭櫅閻︽粓鏌涘Ο缁樺€愮€规洘鍨块獮姗€骞囨担鐟板厞闂備胶绮崝锕傚礈濞嗘搩鏁傞柨鐕傛嫹
开发学院软件开发Java Eclipse 向导机制扩展 -- 实现可定制的向导 阅读

Eclipse 向导机制扩展 -- 实现可定制的向导

 2010-05-31 00:00:00 来源:WEB开发网 闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閹冣挃闁硅櫕鎹囬垾鏃堝礃椤忎礁浜鹃柨婵嗙凹缁ㄧ粯銇勯幒瀣仾闁靛洤瀚伴獮鍥敍濮f寧鎹囬弻鐔哥瑹閸喖顬堝銈庡亝缁挸鐣烽崡鐐嶆棃鍩€椤掑嫮宓佸┑鐘插绾句粙鏌涚仦鎹愬闁逞屽墰閹虫捇锝炲┑瀣╅柍杞拌兌閻ゅ懐绱撴担鍓插剱妞ゆ垶鐟╁畷銉р偓锝庡枟閻撴洘銇勯幇闈涗簼缂佽埖姘ㄧ槐鎾诲礃閳哄倻顦板┑顔硷工椤嘲鐣烽幒鎴旀瀻闁规惌鍘借ⅵ濠电姷鏁告慨顓㈠磻閹剧粯鈷戞い鎺嗗亾缂佸鏁婚獮鍡涙倷閸濆嫮顔愬┑鐑囩秵閸撴瑦淇婇懖鈺冪<闁归偊鍙庡▓婊堟煛鐏炵硶鍋撻幇浣告倯闁硅偐琛ラ埀顒冨皺閺佹牕鈹戦悙鏉戠仸闁圭ǹ鎽滅划鏃堟偨缁嬭锕傛煕閺囥劌鐏犻柛鎰ㄥ亾婵$偑鍊栭崝锕€顭块埀顒佺箾瀹€濠侀偗婵﹨娅g槐鎺懳熺拠鑼舵暱闂備胶枪濞寸兘寮拠宸殨濠电姵纰嶉弲鎻掝熆鐠虹尨宸ョ€规挸妫濆铏圭磼濡搫顫嶇紓浣风劍閹稿啿鐣烽幋锕€绠婚悹鍥у级瀹撳秴顪冮妶鍡樺鞍缂佸鍨剁粋宥夋倷椤掍礁寮垮┑鈽嗗灣閸樠勭妤e啯鍊垫慨妯煎亾鐎氾拷闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閹冣挃闁硅櫕鎹囬垾鏃堝礃椤忎礁浜鹃柨婵嗙凹缁ㄥジ鏌熼惂鍝ョМ闁哄矉缍侀、姗€鎮欓幖顓燁棧闂備線娼уΛ娆戞暜閹烘缍栨繝闈涱儐閺呮煡鏌涘☉鍗炲妞ゃ儲鑹鹃埞鎴炲箠闁稿﹥顨嗛幈銊╂倻閽樺锛涘┑鐐村灍閹崇偤宕堕浣镐缓缂備礁顑嗙€笛囨倵椤掑嫭鈷戦柣鐔告緲閳锋梻绱掗鍛仸鐎规洘鍨块獮鍥偋閸垹骞嶇紓鍌氬€烽悞锕傛晪缂備焦銇嗛崶銊у帗閻熸粍绮撳畷婊堟晝閸屾氨鐓戦梺鍛婂姦閻撳牆岣块弽顓熺厱婵犻潧妫楅悵鏃傛喐閺傝法鏆﹂柟顖炲亰濡茬偓绻涚€电ǹ孝闁靛牏枪椤繘鎼圭憴鍕彴闂佽偐鈷堥崜娑㈩敊婢舵劖鈷戦柣鎾虫捣缁夎櫣绱掗悩宕囧⒌妤犵偛鍟妶锝夊礃閳轰讲鍋撴繝姘參婵☆垯璀﹀Σ濂告煙閼恒儲绀嬫慨濠冩そ濡啫鈽夋潏顭戔偓鍡樼節绾版ǚ鍋撻搹顐㈡灎閻庤娲忛崹浠嬪箖娴犲宸濆┑鐐靛亾鐎氬ジ姊洪懡銈呮瀾闁荤喆鍎抽埀顒佹皑閸忔ê鐣烽婵堢杸婵炴垶鐟ч崢閬嶆⒑缂佹◤顏嗗椤撶喐娅犻柣銏犳啞閻撳繘鏌涢埄鍐炬當闁逞屽墮濠€杈╃磽閹惧顩烽悗锝庝簻缁愭稒绻濋悽闈浶㈤悗姘煎墴閻涱噣宕奸妷锔规嫼缂佺虎鍘奸幊搴ㄋ夊澶嬬厵婵炶尪顔婄花鑺ヤ繆閸欏濮嶇€殿喗鎸抽幃銏ゅ传閸曘劌褰忛梻鍌氬€搁崐鎼佸磹妞嬪孩顐芥慨姗嗗厳缂傛氨鎲稿鍥у疾闂備線娼ч悧鍡椕洪悩璇茬;闁圭偓鍓氬ḿ鈺傘亜閹扳晛鐏╃紒渚囧櫍濮婅櫣绱掑Ο鍦箒闂侀潻缍囩紞渚€鎮伴鈧獮鎺楀箠閾忣偅顥堥柛鈹惧亾濡炪倖甯掗崐缁樼▔瀹ュ鐓ユ繝闈涙椤ョ姷绱掗埦鈧崑鎾绘⒒閸屾艾鈧悂鎮ф繝鍕煓闁硅揪绠戝Ч鍙夌箾閸℃璐╅柣鐔稿閸亪鏌涢鐘茬伄闁哄棭鍋婂娲传閸曨厾鍔圭紓鍌氱С閻掞箓骞堥妸鈺佺劦妞ゆ帒瀚悡鍐煙椤栨粌顣肩痪顓犲亾缁绘繈鍩€椤掍焦缍囬柕濞у懎楠勯梻浣告惈濞层劑宕伴幘璺哄К闁逞屽墮閳规垿顢欓弬銈勭返闂佸憡锕㈢粻鏍х暦閵忋倖鍋ㄩ柛娑樑堥幏铏圭磽閸屾瑧鍔嶉柨姘攽椤曞棛鐣甸柡灞剧洴楠炴﹢寮堕幋婵囨嚈闂備浇顕栭崰妤勬懌濠电偟鍘х换妯讳繆閹间礁围闁搞儮鏅濋弳浼存⒒閸屾瑧顦︽繝鈧潏鈺佸灊妞ゆ牗绮嶉弳婊堟煟閹邦剛鎽犳繛鍛У缁绘盯骞嬮悙瀵告缂佺偓宕橀崑鎰閹惧瓨濯撮悹鎰靛灣缁辨澘鈹戦悙鏉戠祷妞ゆ洦鍙冮崺鈧い鎺戝枤濞兼劖绻涢崣澶屽ⅹ闁伙絿鍏橀、妤呭礃椤忓啰鑳洪梻鍌氬€风粈渚€骞夐敓鐘茬闁哄洢鍨归悿顕€鏌eΟ娆惧殭缂佲偓閸喓绡€闂傚牊绋撴晶娑氣偓瑙勬礀瀵墎鎹㈠☉銏犵闁绘劑鍔庣槐浼存⒑閸濆嫭顥滄俊顐n殜閸╃偤骞嬮敂钘変汗闁哄鐗滈崑鍕储閿熺姵鈷戦弶鐐村閸斿秹鏌eΔ浣虹煂婵″弶鍔欓獮妯尖偓娑櫭鎾寸箾鐎电ǹ孝妞ゆ垵鎳橀獮妤呮偨閸涘ň鎷洪梺闈╁瘜閸樹粙宕甸埀顒€鈹戦悙鑼勾闁稿﹥绻堥獮鍐┿偅閸愨晛鈧鏌﹀Ο渚Ш妞ゆ柨锕铏规喆閸曨剙鍓归梺鍛娒肩划娆忕暦閹剧粯鍋ㄩ柛娑樑堥幏娲⒑閼姐倕鏋戞繝銏★耿楠炲啯绗熼埀顒勫蓟閿濆绠抽柣鎰暩閺嗐倝姊虹拠鈥虫灍妞ゃ劌锕悰顕€寮介妸锕€顎撻梺绋跨箰椤︽壆鈧俺妫勯埞鎴︽倷閼搁潧娑х紓浣瑰絻濞尖€崇暦閺囥垹围濠㈣泛锕ら幆鐐烘⒑闁偛鑻晶瀛樻叏婵犲啯銇濇鐐寸墵閹瑥霉鐎n亙澹曢梺鍝勭▉閸樹粙宕戠€n喗鐓熸俊顖氱仢閸氬湱鈧鎸风欢姘舵偂椤愶箑鐐婇柕濞р偓婵洭姊洪崫鍕櫤闁诡喖鍊垮濠氬Ω閳哄倸浜為梺绋挎湰缁嬫垿顢旈敓锟�婵犵數濮烽弫鍛婃叏閻戣棄鏋侀柛娑橈攻閸欏繘鏌i幋锝嗩棄闁哄绶氶弻娑樷槈濮楀牊鏁鹃梺鍛婄懃缁绘﹢寮婚敐澶婄闁挎繂妫Λ鍕⒑閸濆嫷鍎庣紒鑸靛哺瀵鈽夊Ο閿嬵潔濠殿喗顨呴悧濠囧极妤e啯鈷戦柛娑橈功閹冲啰绱掔紒妯虹伌濠碉紕鏁诲畷鐔碱敍濮橀硸鍟嬮梻浣告啞椤ㄥ牓宕戦悢鍝ヮ浄闁兼祴鏅濈壕钘壝归敐鍛儓妞ゅ骸鐭傞弻娑㈠Ω閵壯冪厽閻庢鍠涢褔鍩ユ径鎰潊闁绘ḿ鏁搁弶鎼佹⒒閸屾艾鈧悂鎮ф繝鍕煓闁圭儤顨嗛崐鍫曟煕椤愮姴鍔滈柛濠勬暬閺岋綁鎮㈤崫鍕垫毉闂佸摜鍠撻崑鐔烘閹烘梹瀚氶柟缁樺笚濞堢粯绻濈喊澶岀?闁轰浇顕ч悾鐑芥偄绾拌鲸鏅┑顔斤耿绾悂宕€n喗鈷戦悹鍥ㄧ叀閸欏嫭绻涙担鍐叉搐缁犵儤绻濇繝鍌滃闁稿鏅涢埞鎴﹀磼濮橆厼鏆堥梺鎶芥敱閸ㄥ綊鎯€椤忓牜鏁囬柣鎰綑椤庢稑鈹戦悙鎻掓倯闁告梹鐗滈幑銏犫槈閵忊€虫濡炪倖宸婚崑鎾绘煛鐎n亜顒㈤柕鍥у椤㈡洟濮€閵忋埄鍞虹紓鍌欐祰妞村摜鏁幒鏇犱航闂備礁鍚嬬粊鎾疾濠婂牆鍚圭€光偓閸曨兘鎷绘繛鎾村焹閸嬫捇鏌嶈閸撴盯宕戝☉銏″殣妞ゆ牗绋掑▍鐘炽亜閺冨洤浜归柡鍡楁閺屻劌鈹戦崱娆忣暫闂佸憡鏌ㄩ悘姘跺Φ閸曨垱鏅滈柣锝呰嫰瀵劑姊虹拠鈥虫珯缂佺粯绻冩穱濠囨嚋闂堟稓绐為柣搴秵閸撴瑧鏁ィ鍐┾拻濞达絿枪椤ュ繘鏌涚€n亝鍣介柟骞垮灲瀹曟﹢顢欓懖鈺嬬幢婵$偑鍊曠换鎰板箠閹邦喚涓嶉柛鎾椻偓閸嬫捇鎮烽弶娆炬闂佸摜濮靛ú婊堟嚍鏉堛劎绡€婵﹩鍓涢悾楣冩⒑缂佹ɑ鐓ラ柛姘儔閸╂盯骞嬮敂钘夆偓鐢告煕閿旇骞栭弽锟犳⒑闂堟稒顥滈柛鐔告尦瀵濡舵径濠勵槰闂佽偐鈷堥崜娆撴偂閻斿吋鍊甸悷娆忓缁€鍐磼鐠囪尙澧︾€殿噮鍋婂畷姗€顢欓懖鈺佸Е婵$偑鍊栫敮鎺斺偓姘€鍥х劦妞ゆ帊鐒﹂ˉ鍫⑩偓瑙勬礃閿曘垽銆佸▎鎾冲簥濠㈣鍨板ú锕傛偂閺囥垺鐓冮柍杞扮閺嬨倖绻涢崼鐕傝€块柡宀嬬秮閹垻绮欓崹顕呮綒婵犳鍠栭敃銉ヮ渻娴犲绠栭柍鈺佸暞閸庣喖鏌嶉埡浣告殲闁伙讣缍佸缁樻媴閾忕懓绗¢梺缁橆殕濞茬喐淇婇崜浣虹煓閻犳亽鍔嶅▓楣冩⒑缂佹ê鐏﹀畝锝堟硶瀵囧焵椤掑嫭鈷戦柟鑲╁仜閸斺偓闂佸憡鍔戦崝搴ㄥΧ椤曗偓濮婂宕掑▎鎴犵崲濠电偘鍖犻崟鍨啍闂婎偄娲﹀ú姗€锝為弴銏$厸闁搞儯鍎遍悘鈺呮煕鐏炶濡介柕鍥у缁犳盯骞樼捄渚澑闂備焦濞婇弨閬嶅垂閸ф钃熼柣鏂垮悑閸ゅ啴鏌嶆潪鐗堫樂缂侇喖鐖煎娲川婵犲啠鎷瑰銈冨妼閿曨亜顕f繝姘櫢闁绘ɑ褰冪粣娑橆渻閵堝棙顥堥柡渚囧枟閹便劑宕堕埡鍐紳婵炶揪绲挎灙闁逞屽墮濠€閬嶅极椤曗偓閹垺淇婇幘铏窛闁逞屽墴濞佳囧箺濠婂懎顥氬┑鍌溓圭痪褔鏌涢锝団槈濠德ゅ亹缁辨帒螖娴d警鏆$紓浣虹帛閻╊垶骞冮埄鍐╁劅闁挎繂娴傞崯瀣⒒娴h櫣銆婇柡鍌欑窔瀹曟粌鈹戠€n亞顔嗛梺鍛婄☉閻°劑鎮¢妷鈺傚€甸柨婵嗘噽娴犳稓绱撳鍡╂疁婵﹤顭峰畷鎺戭潩椤戣棄浜剧€瑰嫭鍣磋ぐ鎺戠倞鐟滄粌霉閺嶎厽鐓忓┑鐐靛亾濞呭棝鏌涙繝鍌涘仴闁哄被鍔戝鎾倷濞村浜鹃柛婵勫劤娑撳秹鏌$仦璇插姕闁绘挻娲熼弻鏇熷緞濡儤鐏堟繝鈷€灞芥珝闁哄矉绱曢埀顒婄岛閺呮繄绮i弮鍫熺厸鐎光偓閳ь剟宕伴弽褏鏆︽繝濠傛-濡查箖鏌i姀鈺佺仭闁烩晩鍨跺濠氭晸閻樻彃绐涘銈嗘濡嫰鍩€椤掍礁濮嶉柡宀嬬磿娴狅妇鎷犻幓鎺濇綆闂備浇顕栭崰鎾诲磹濠靛棛鏆﹂柟鐑樺灍濡插牊鎱ㄥΔ鈧Λ鏃傛閿燂拷闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閹冣挃闁硅櫕鎹囬垾鏃堝礃椤忎礁浜鹃柨婵嗙凹缁ㄧ粯銇勯幒瀣仾闁靛洤瀚伴獮鍥敍濮f寧鎹囬弻鐔哥瑹閸喖顬堝銈庡亝缁挸鐣烽崡鐐嶆棃鍩€椤掑嫮宓佸┑鐘插绾句粙鏌涚仦鎹愬闁逞屽墰閹虫捇锝炲┑瀣╅柍杞拌兌閻ゅ懐绱撴担鍓插剱妞ゆ垶鐟╁畷銉р偓锝庡枟閻撴洘銇勯幇闈涗簼缂佽埖姘ㄧ槐鎾诲礃閳哄倻顦板┑顔硷工椤嘲鐣烽幒鎴旀瀻闁规惌鍘借ⅵ濠电姷鏁告慨顓㈠磻閹剧粯鈷戞い鎺嗗亾缂佸鏁婚獮鍡涙倷閸濆嫮顔愬┑鐑囩秵閸撴瑦淇婇懖鈺冪<闁归偊鍙庡▓婊堟煛鐏炵硶鍋撻幇浣告倯闁硅偐琛ラ埀顒冨皺閺佹牕鈹戦悙鏉戠仸闁圭ǹ鎽滅划鏃堟偨缁嬭锕傛煕閺囥劌鐏犻柛鎰ㄥ亾婵$偑鍊栭崝锕€顭块埀顒佺箾瀹€濠侀偗婵﹨娅g槐鎺懳熺拠鑼舵暱闂備胶枪濞寸兘寮拠宸殨濠电姵纰嶉弲鎻掝熆鐠虹尨宸ョ€规挸妫濆铏圭磼濡搫顫嶇紓浣风劍閹稿啿鐣烽幋锕€绠婚悹鍥у级瀹撳秴顪冮妶鍡樺鞍缂佸鍨剁粋宥夋倷椤掍礁寮垮┑鈽嗗灣閸樠勭妤e啯鍊垫慨妯煎亾鐎氾拷  闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閻愵剙鍔ょ紓宥咃躬瀵鏁愭径濠勵吅闂佹寧绻傞幉娑㈠箻缂佹ḿ鍘遍梺闈涚墕閹冲酣顢旈銏$厸閻忕偠顕ч埀顒佺箓閻g兘顢曢敃鈧敮闂佹寧妫佹慨銈夋儊鎼粹檧鏀介柣鎰▕閸ょ喎鈹戦鈧ḿ褔锝炲┑瀣╃憸搴綖閺囥垺鐓欓柟瑙勫姦閸ゆ瑧鐥幆褍鎮戠紒缁樼洴瀹曞崬螣閾忓湱鎳嗛梻浣告啞閿曨偆妲愰弴鐘愁潟闁规儳顕悷褰掓煕閵夋垵瀚ぐ顖炴⒒娴h鍋犻柛鏂跨焸閹儵宕楅梻瀵哥畾闂佸湱铏庨崰鏍矆閸愨斂浜滈柡鍐ㄥ€哥敮鍓佺磼閹邦厾娲存慨濠冩そ瀹曨偊宕熼崹顐嵮囨⒑閹肩偛濡肩紓宥咃工閻g兘濮€閻樺棙妞介、鏃堝川椤撴稑浜鹃柛顭戝亽濞堜粙鏌i幇顖氱毢濞寸姰鍨介弻娑㈠籍閳ь剛鍠婂澶娢﹂柛鏇ㄥ灡閺呮粓鎮归崶顏勭毢濞寸姵鎮傞幃妤冩喆閸曨剛鈹涚紓浣虹帛缁诲牓鎮伴鑺ュ劅闁靛⿵绠戝▓鐔兼⒑闂堟冻绱¢柛鎰╁妼椤╊剟姊婚崒姘偓鎼併偑閹绢喖纾婚柛鏇ㄥ€嬪ú顏呮櫇闁逞屽墰閸欏懘姊洪崫鍕犻柛鏂垮閺呭爼鏁撻悩鏂ユ嫽闂佺ǹ鏈悷锔剧矈閻楀牄浜滈柡鍥ф閹冲宕戦幘璇插瀭妞ゆ劑鍨虹拠鐐烘倵鐟欏嫭绀冪紒顔芥崌楠炲啴濮€閿涘嫰妾繝銏f硾椤戝洨绮欐笟鈧缁樻媴閻熸澘濮㈢紓浣虹帛閸旀洟鏁冮姀鈩冪秶闁宠桨绶″Λ婊堟⒑缁嬭法绠绘俊顐ユ硶閹广垽宕卞Ο闀愮盎闂佸搫绉查崝搴ㄣ€傞弻銉︾厵妞ゆ牗姘ㄦ晶娑㈡煏閸パ冾伃妞ゃ垺娲熸慨鈧柕蹇嬪灩婵鲸绻濆▓鍨灈闁挎洏鍎遍—鍐寠婢跺本娈鹃梺缁樺灩閻℃棃寮崶銊х闁瑰鍋熼幊鍐煟濠靛鎲炬慨濠勭帛閹峰懘宕ㄩ棃娑氱Ш妞ゃ垺鐗犲畷銊╊敇閸ャ劎鈽夐柍瑙勫灩閳ь剨缍嗘禍鐐烘偩妤e啯鈷戦梺顐ゅ仜閼活垱鏅堕鐐寸厪闁搞儜鍐句紓缂備胶濮甸惄顖炵嵁濡皷鍋撻崹顐e仩闁稿鍔栫换婵堝枈濡椿娼戦梺鎼炲妽婢瑰棝鍩€椤掍胶顣叉繝銏★耿閿濈偠绠涢幘浣规そ椤㈡棃宕熼鍡欏€為梻鍌欑閹测€趁洪敃鍌氱婵ǹ娉涚粻顖炴煕濡ゅ啫浜归柡鈧禒瀣厽闁归偊鍘肩徊鑽ょ磼閻欐瑥鍟伴弳鍡涙煥濠靛棙鍣洪柛瀣ㄥ劜椤ㄣ儵鎮欓弶鎴犱紝婵犳鍠掗崑鎾绘⒑缂佹﹫渚涢柛瀣嚇瀵剟鍩€椤掆偓閳规垿鎮╅崹顐f瘎婵犳鍠栭顓㈠焵椤掍礁鍤柛锝忕到椤曪綁宕奸弴鐐殿啇婵炶揪绲介崢婊堝箯濞差亝鈷戦柛娑橈功缁犳捇鎮楀鐓庡箹妞ゆ柨绻愰埞鎴﹀幢韫囨梹鏉告俊鐐€栧褰掑磿閹惰棄鍌ㄩ柟缁㈠枟閻撴瑦銇勯弮鍥跺殭鐎规挸妫楅埞鎴︽晬閸曨偄骞嬮梺绯曟櫔缁绘繂鐣烽幒鎳虫梹鎷呴崜韫床婵犵數濮烽弫鎼佸磻閻樿绠垫い蹇撴缁躲倕霉閻樺樊鍎忕紒鐘侯潐閵囧嫰骞囬埡浣插亾閺嶎厼姹叉繝濠傜墛閸嬶綁寮堕悙鏉戭€滄い鎺斿枛閺岋綁寮幐搴&闂佸搫鐭夌紞渚€骞冮姀鐘垫殝闁规鍠氬▔鍧楁⒒娴e鈧偓闁稿鎹囬弻銈嗘叏閹邦兘鍋撳Δ鍐棜濠靛倸鎲¢悡鏇㈡倶閻愰潧浜鹃柣銊﹀灩閳ь剚绋掔换鍌濈亙濠德板€曢敃锝囪姳閻戣姤鐓曟俊銈傚亾闁哥喎娼¢幃楣冩倻閼恒儱浜楅柟鍏兼儗閸犳宕撻悽鍛娾拺闁圭ǹ娴风粻鎾绘煙閸愯尙校缂佹梻鍠栧鎾閳锯偓閹锋椽姊洪崨濠勭畵閻庢凹鍓熷鍐测枎閹惧鍘藉┑掳鍊愰崑鎾翠繆椤愶絿銆掗柛鎺撳浮瀹曞ジ濡烽妷褜妲伴梻浣哥-閹虫捇濡靛Ο鑹板С濠电姵纰嶉ˉ濠冦亜閹扳晛鐏柟鍏煎姈缁绘稓鈧數枪閸樻挳鎸婂┑瀣叆闁哄洦顨呮禍楣冩⒒閸パ屾Ч缂佺粯绻冪换婵嬪磼濠婂啠鍙¢梻浣风串缁叉儳顪冩禒瀣摕闁挎稑瀚▽顏堟偣閸ャ劌绲绘い顒€鐗撳铏光偓鍦濞兼劙鏌涢妸銉т虎闁伙絿鍏樺畷锟犳倷閳哄偆娼旈梻浣烘嚀閸氣偓缂佲偓娴e湱顩查柣鎰靛厸缁诲棝鏌曢崼婵嗏偓鍛婄閹屾富闁靛牆楠稿銊╂煕鎼粹槅鐓肩弧鎾炽€掑锝呬壕闂佸搫鏈惄顖炲箖閳轰胶鏆﹂柛銉戔偓閹风増绻濋悽闈浶涢柛瀣尭閵嗘帒顫濋敐鍛婵犳鍠栭敃銊モ枍閿濆洦顫曢柟鐑樺殾閻旂厧鍗抽柣鏃堫棑娴煎矂姊虹拠鈥虫灓闁稿繑蓱娣囧﹪鎮块锝喰ラ梻浣呵归鍡涘箰閹间緤缍栨繝闈涱儐閸嬪倿骞栧ǎ顒€鐏ù婊冨⒔缁辨捇宕掑▎鎴g獥闂佸摜濮靛銊╁礆閹烘鏁嶉柣鎰棘瑜旈弻銊モ攽閸♀晜笑缂備讲鍋撻柛鎰靛枟閻撳啴鏌涘┑鍡楊仼闁哄棙鐟﹂〃銉╂倷閼碱剙顤€婵烇絽娲ら敃顏堝箖濞嗘搩鏁傞柛鏇樺妼娴滈箖鏌″搴″箹缂佲偓婢舵劖鐓欓弶鍫濆⒔閻h京鐥幆褏绉洪柡宀嬬節瀹曞爼濡烽妷褌鎮i梻浣告啞閸ㄨ绻涢埀顒侇殽閻愬澧懣鎰亜閹哄棗浜炬繝纰樷偓鑼煓闁哄矉缍侀獮妯兼崉閻戞ḿ浜梻浣虹帛閹尖晠宕戞繝鍌滄殾闁诡垶鍋婂銊╂⒑缁嬪潡顎楃紒缁橈耿瀵鈽夐姀鐘电潉闂侀€炲苯澧伴柛鎺撳浮楠炴ḿ鎷犻懠鑸垫啺闂備礁鎼ú銏ゅ垂瑜版帗鍊峰┑鐘插閸犳劗鈧箍鍎遍ˇ浠嬪极閸屾稏浜滈柟鎹愭硾琚ラ梺绋款儐閹告悂鍩㈤幘璇插瀭妞ゆ梻鏅禍鑸电節閻㈤潧浠滈柛姘儔閹兘濡搁埡鍌氣偓鍫曟煙閻戞﹩娈曢柍閿嬪灴閺屾稑鈽夊鍫濆缂備胶濮甸幑鍥箖濡も偓椤繈鎮℃惔鈾€鎷ゆ俊鐐€戦崐鏇㈠磹閸︻厽宕叉繝闈涚墕閺嬪牆顭跨捄铏圭伇闁挎稓鍠栧铏圭矙濞嗘儳鍓遍梺鎼炲妼閻忔繈鎮鹃悜钘夌疀闁哄娉曢娲⒑閹稿孩纾甸柛瀣崌閺屾盯濡搁妷銉㈠亾閸︻厽宕叉繛鎴烇供閸熷懏銇勯弮鍥у惞闁告垵缍婂铏圭矙濞嗘儳鍔€缂備胶绮换鍫濐嚕鐠囧樊鍚嬪璺猴梗缁卞爼姊洪崨濠冨闁告挻鐟ラ埢宥夋晲閸モ晝锛濇繛杈剧到閹碱偅鐗庨梻浣虹帛椤ㄥ牊绻涢埀顒傗偓娈垮枦椤曆囶敇閸忕厧绶炲┑鐘插楠炴劕鈹戦悙鑸靛涧缂佽弓绮欓獮澶愬灳閺傘儲鐏侀梺鍝勮閸庢煡鍩涢幋鐘电<閻庯綆鍋勯婊堟煙閻у摜绉柡灞剧洴閹晛鐣烽崶褉鎷伴柣搴㈩問閸犳牠鈥﹀畡閭﹀殨闁圭虎鍠栭~鍛存煟濮椻偓濞佳囧焵椤掑倸浠遍柟顔煎槻楗即宕橀顖樺€濋弻銈嗐偊閸ф鎽电紓浣虹帛缁诲倿锝炲┑瀣垫晣闁绘ɑ褰冪粻銉╂⒒閸屾瑧顦﹂柟璇х節瀹曞綊顢涢悙鑼紮闂佸搫绋侀崑鈧柛瀣尭椤繈鎮欓鈧锟�
核心提示:本文首先剖析了 Eclipse 向导机制的实现原理,包括页面的加载和注销,Eclipse 向导机制扩展 -- 实现可定制的向导,页面校验,向导执行流程,基于这两种扩展,用户可以快速编写复杂的 Eclipse 向导实现,向导目标操作等,目前

本文首先剖析了 Eclipse 向导机制的实现原理,包括页面的加载和注销,页面校验,向导执行流程,向导目标操作等。目前,Eclipse 向导页面内容是固定的,向导一经创建,其内容和顺序就无法改变。然而,在现实世界中,我们面对的逻辑往往是复杂多变的,固定的顺序的 Eclipse 向导经常无法满足用户需要,因而,文章从两个方面对当前 Eclipse 向导机制进行了扩展:具有动态页数的 Eclipse 向导以及树状拓扑结构的 Eclipse 向导。扩展后的 Eclipse 向导,可以很方便地被开发人员重用,进而提高开发效率。

引言

文章将对现有 Eclipse 向导机制进行一系列的扩展,并提供相应的参考实现,用户只需要在扩展的基础上增加自己的业务逻辑,便可以快捷地创建功能更为复杂的 Eclipse 向导。

如不做特殊说明,本文默认的开发和运行环境是:IBM JDK 1.6,Eclipse 3.4.x

Eclipse 向导机制介绍

在 Eclipse 中,向导是一种很好的辅助用户操作的机制,通常用于指导用户完成特定的业务操作,例如:创建一个 Java 工程,导入一个文件,导出一个 JAR 文件等等,在 Eclipse 中都有相应的向导辅助用户完成。此外,在 Eclipse 插件开发中,向导也用得非常普遍,Eclipse 提供的向导框架可以帮助用户快速创建自己的向导。

向导基本操作和运行机制

开始之前,我们先来了解一下 Eclipse 向导的实现机制。只有对 Eclipse 向导的实现机制有深入了解,才能实现合理的扩展。 Eclipse 向导由一系列的向导页组成,通常用户的操作会被分散到各个向导页,每个向导页用于配置操作所需的某一方面的信息,当所有向导页的配置完成之后,整个向导便可以执行最后的操作并结束。此外,在向导设计中,用户需要将当前向导页所有必需信息填好,“Next”按钮才生效,从而进入下一个向导页。当所有向导页的内容填充完毕并且到达最后一个向导页时,向导的“Finish”按钮才能有效,这时候点击“Finish”按钮开始执行向导的目标操作。

以 Eclipse 中创建一个工程的向导为例,打开 Eclipse 开发环境,选择“File->New->Project”,便会弹出一个创建新工程的向导,如图 1 所示。可以看到,该向导中有两个页面,第一个页面用于选择需要创建的工程类型,我们选择“General”中的“Project”创建一个 Eclipse 普通工程,第二个页面用于配置创建 Eclipse 普通工程所需要的信息:包括工程名,工程位置以及工程所属的工作集。只有在第一页中选好需要创建的工程类型之后,“Next”按钮才有效,进而进入第二页,当第二页中所有必填信息填完之后,“Finish”按钮才有效,点击它将开始创建一个 Eclipse 工程的操作。

图 1. Eclipse 中创建普通工程向导

  查看原图(大图)

在 Eclipse 中,向导必须实现接口 org.eclipse.jface.wizard.IWizard,Eclipse 提供的 org.eclipse.jface.wizard.Wizard 是 IWizard 的一个抽象实现。向导页必须实现接口 org.eclipse.jface.wizard.IWizardPage,org.eclipse.jface.wizard.WizardPage 是 IWizardPage 的一个抽象实现。用户如果想使用 Eclipse 提供的框架创建自己的向导,那么向导和向导页需要分别继承 Wizard 类和 WizardPage 类并重写相应方法。
创建一个 Eclipse 向导后台发生的操作顺序大致如下,在这个过程中,我们需要重写第一步中向导的构造函数,以及第三步中添加向导页操作。
1. 使用 IWizard 子类的构造函数创建 Eclipse 向导;
2. 创建向导所在的 Shell;
3. 添加向导页:addPages(),重写该方法给向导插入的向导页;
4. 创建向导页容器:WizardDialog.createPageContainer(Composite parent);
5. 创建每个向导页对应的 Control:IWizard.createPageControls(Composite pageContainer)。Eclipse 调用它来实例化所有的向导页面。重写它给向导添加持续可视的窗体小部件;
6. 显示起始向导页:调用 WizardDialog.showStartingPage():重写该方法以获取向导第一个页面。

向导页定制

下面我们来看一下向导页的定制,向导页扩展了 WizardPage 类。开发人员为了定制自己的页面,必须重写下面一些方法:

Constructor:实例化向导页面。

dispose():向导关闭时调用该方法清除向导页相关对象。

createControl(Composite parent):重写它来创建向导页控件。

IWizard getWizard():获取向导页所在的向导对象。

setPageComplete:当该向导页中的所有必须的设置都完成之后,可以将该页的状态设置为结束,然后用户可以进入下一页。

setTitle(String title):设置向导页标题。

setDescription(String description):设置向导页的描述。

setImageDescriptor(ImageDescriptor image):提供页面右上方出现的图片。

setMessage(String message):设置向导页中的提示信息。

setErrorMessage(String error): 设置向导页中的错误提示信息。

performHelp():设置向导页的帮助信息。

当向导中有多个向导页时,我们可以在向导对话框最下方看到“Back”,“Next”,“Finish”和“Cancel”四个按钮。 “Back”,“Next”按钮用于在多个向导页间进行跳转,当向导中只有一个向导页时,只有“Finish”和“Cancel”两个按钮。

“Back”按钮:用于返回到前一个向导页。点击该按钮,将调用函数 IWizardPage getPreviousPage(IWizardPage previousPage),返回前一个页面。

“Next” 按钮:用于进入下一个向导页。对于一个设计合理的向导,只有当前向导页中所有必填的信息设置完成之后,“Next”按钮才能变成有效状态,然后用户才被允许进入下一个页面。当用户填完页面中的必须信息时,程序将执行 setPageComplete(true) 方法将当前向导页状态设为完成状态;之后用户点击“Next”按钮,向导页 IWizardPage 的方法 getNextPage(IWizardPage nextPage) 被调用,返回下一个向导页。默认情况下,用户将进入向导类 Wizard 的 addPages() 方法所提供的数组中的下一个页面。如果我们要实现下一页有多种方案,必须重写该方法来计算后一个页面。

“Finish” 按钮:当所有向导页中的信息已经配好之后,用户点击 Finish 按钮,调用 performFinish() 函数来执行向导目标操作,用户需要重写它来实现向导的业务逻辑,如果 performFinish() 执行业务逻辑失败,则应该返回 false。

“Cancel”按钮:在向导运行过程中,用户可以随时点击该按钮,退出向导。点击该按钮,将会调用 performCancel() 函数,取消当前向导操作,并将之前所做的操作回滚。

Eclipse 向导扩展

从对 Eclipse 向导机制分析可知,Eclipse 向导页的添加是线性的,向导页的内容也是固定的,页面内容和顺序一旦确定就无法改变。在实际应用中,我们面对的需求往往是复杂的,用户的操作步骤经常是有分支的,向导页的内容有时候根据用户的操作需要动态变化。下面我们从两个方面对当前 Eclipse 向导机制进行扩展:动态页数的 Eclipse 向导以及树状拓扑结构的 Eclipse 向导。

动态页数的 Eclipse 向导

实际中,我们经常遇到的一类问题是:某个向导页的存在与否依赖于用户在前面向导页中所做的选择。

举个例子:我们需要给某电影院实现一个电影票购票系统,观众能够通过该系统远程连接到电影院的服务器进行订票,订购电影票的用户有三种类型:普通用户,会员用户,以及 VIP 会员,不同的用户其订票流程是不同的。根据需求,我们使用 Eclipse 的 RCP 来实现该电影票购票系统,观众订票操作将通过 Eclipse 向导辅助完成,我们设计了四个向导页:A、B、C、D。向导页 A 供用户选择其用户类型:普通用户,普通会员或者 VIP 会员。假如观众是普通用户则直接进入向导页 B 填写其基本信息,包括姓名,电话号码等等,之后进入向导页 C 选择电影票,包括电影名字,时间,座位号等,然后选择确定,操作结束。假如观众是会员或者 VIP 会员时,观众在向导页 A 输入自己的会员 ID 和密码登录到系统,登录成功之后,直接进入向导页 C 选择电影票,操作和普通用户一样,当电影票选票结束之后,会员还将进入向导页 D,查看其历史记录,剩余余额等信息。四个向导页的具体描述如下:

表 1. 电影订票向导设计

向导页编号标题内容
A用户类型选择选择用户类型:普通用户,普通会员,VIP 会员。如果是会员用户,需要输入自己的会员 ID 和密码进行登录
B普通用户基本信息对于普通用户,填写其基本信息,包括用户名,电话号码
C电影票信息用户选择其想看的电影,选择电影名字,放映时间,以及选择座位号
D历史记录对于会员用户,操作结束之后,将显示其历史纪录

向导页顺序图如下,向导页是动态变化的。当用户为普通用户与,向导页 B 出现,D 不出现,当用户为会员用户,向导页 B 不出现,D 出现。
图 2. 电影订票动态向导顺序图

  查看原图(大图)

对于普通用户:在向导页 A 中选择普通用户类型,然后进入向导页 B,填写其基本信息,然后进入向导页 C 进行选票并结束。 见下图。
图 3. 普通用户电影订票流程

  查看原图(大图)

对于会员或者 VIP 会员用户:在向导页 A 中选择会员用户或者 VIP 会员,跳过向导页 B,直接进入向导页 C,选票结束之后,进入向导页 D,查看其历史纪录。见下图。
图 4. 会员用户以及 VIP 会员用户电影订票流程

  查看原图(大图)

为了实现向导页的动态增加或者减少功能,本文提供了一个动态向导的抽象类 DynamicPageWizard,供广大开发人员使用。用户使用时,只需要继承该抽象类,并重写向导页初始化,增加,修改,以及删除等方法,便可以方便地实现动态向导。该向导类继承了类 org.eclipse.jface.wizard.Wizard,在原 Wizard 的基础上进行扩展,使用变量 List<IWizardPage> pages 来存储向导中的所有向导页,类中所有对向导页的操作都是基于该变量进行,包括向导页的创建、注销、动态增加以及删除。详细的内容见下面清单。由于使用 pages 变量覆盖了原 org.eclipse.jface.wizard.Wizard 中的 pages 变量,因而父类方法中基于该变量的所有方法都需要重写,在下表中省略号部分是重写的代码,读者可以根据自己的 JDK 版本以及扩展需要,将内容补上。

清单 1. 动态页数向导父类 DynamicPageWizard

 public abstract class DynamicPageWizard extends Wizard { 
  /** 
   * 向导中的所有向导页,注意:指的是增加或者减少之后的向导页 
   */ 
  private List<IWizardPage> pages = new ArrayList<IWizardPage>(); 
 
  ... 
   
  /** 
   * 构造函数,创建一个空的向导 
   */ 
  protected DynamicPageWizard() { 
    super(); 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#addPage(org.eclipse.jface.wizard.IWizardPage) 
   */ 
  public void addPage(IWizardPage page) { 
   // 重写父类方法,添加向导页,并将向导页的向导设置为当前对象 
   ... 
  } 
   
  /** 
   * 在指定的向导页前插入向导页 
   * 
   * @param page 
   * @param nextPage 
   * @return 
   */ 
  public boolean addPage(IWizardPage page, IWizardPage nextPage) { 
   for(int i = 0; i < pages.size(); i++) { 
    if(pages.get(i) == nextPage) { 
    return addPage(page, i); 
    } 
   } 
   return false; 
  } 
   
  /** 
   * 在指定的位置插入向导页 
   * 
   * @param page 
   * @param location 
   */ 
  public boolean addPage(IWizardPage page, int location) { 
   // Invalid location 
   if(location < 0 || location > pages.size()) 
    return false; 
   
   // Create the new page list 
   List<IWizardPage> newPages = new ArrayList<IWizardPage>(); 
   for(int i = 0; i < location; i++) { 
    newPages.add(pages.get(i)); 
   } 
   
   page.setWizard(this); 
   newPages.add(page); 
   
   for(int i = location; i < pages.size(); i++) { 
    newPages.add(pages.get(i)); 
   } 
   
   // Set the relationship 
   if(location != pages.size()) 
    ((IWizardPage)newPages.get(location + 1)).setPreviousPage(page); 
   
   ((IWizardPage)page).setPreviousPage((IWizardPage)newPages.get(location - 1)); 
   pages = newPages; 
   return true; 
  } 
 
   
  /** 
   * 删除指定位置的向导页 
   * 
   * @param number 
   */ 
  public void removePage(int number) { 
   if(number < 0) 
    return; 
   if(number > pages.size() - 1) 
    return; 
 
   if(number == 0) 
    pages.remove(0); 
   else if(number == pages.size() - 1) 
    pages.remove(number); 
   else { 
    IWizardPage wizarPage = (IWizardPage)pages.get(number + 1); 
    wizarPage.setPreviousPage((IWizardPage)pages.get(number - 1)); 
    pages.remove(number); 
   } 
  } 
   
  /** 
   * 删除指定的向导页 
   * 
   * @param page 
   */ 
  public void removePage(IWizardPage page) { 
   int number = -1; 
   for(int i = 0; i < pages.size(); i++) { 
    if(pages.get(i) == page) 
    number = i; 
   } 
   
   removePage(number); 
  } 
   
   
  /** 
   * 删除向导中某种类名的所有向导页 
   * 
   * @param number 
   */ 
  public void removePage(String className) { 
    for(int i = 0; i < pages.size(); i++) { 
   if(pages.get(i).getClass().getCanonicalName().equalsIgnoreCase(className)) 
    removePage(i); 
   } 
  } 
   
 /* 
 * (non-Javadoc) 
 * @see org.eclipse.jface.wizard.Wizard#addPages() 
 */ 
  public void addPages() { 
   // 重写父类方法 
   ... 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#canFinish() 
   */ 
  public boolean canFinish() { 
   // 重写父类方法,检测是否所有向导页的设置都结束 
   ... 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#createPageControls 
   * (org.eclipse.swt.widgets.Composite) 
   */ 
  public void createPageControls(Composite pageContainer) { 
   // 重写父类方法 
   ... 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#dispose() 
   */ 
  public void dispose() { 
   // 重写父类方法 
   ... 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#getDefaultPageImage() 
   */ 
  public Image getDefaultPageImage() { 
   // 重写父类方法 
   ... 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#getNextPage 
   * (org.eclipse.jface.wizard.IWizardPage) 
   */ 
  public IWizardPage getNextPage(IWizardPage page) { 
   // 重写父类方法,获取下一个向导页 
   ... 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#getPage(java.lang.String) 
   */ 
  public IWizardPage getPage(String name) { 
   // 重写父类方法,获取指定名字的向导页 
   ... 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#getPageCount() 
   */ 
  public int getPageCount() { 
   // 重写父类方法 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#getPages() 
   */ 
  public IWizardPage[] getPages() { 
   // 重写父类方法 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#getPreviousPage 
   * (org.eclipse.jface.wizard.IWizardPage) 
   */ 
  public IWizardPage getPreviousPage(IWizardPage page) { 
   // 重写父类方法,获取某个向导页之前的向导页 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#getStartingPage() 
   */ 
  public IWizardPage getStartingPage() { 
   // 重写父类方法,获取起始向导页 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#performCancel() 
   */ 
  public boolean performCancel() { 
   // 重写父类方法 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#needsPreviousAndNextButtons() 
   */ 
  public boolean needsPreviousAndNextButtons() { 
   // 重写父类方法 
  } 
   
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#setForcePreviousAndNextButtons(boolean) 
   */ 
  public void setForcePreviousAndNextButtons(boolean b) { 
   // 重写父类方法 
  } 
   
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#performFinish() 
   */ 
  public abstract boolean performFinish(); 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#setDefaultPageImageDescriptor 
   * (org.eclipse.jface.resource.ImageDescriptor) 
   */ 
  public void setDefaultPageImageDescriptor(ImageDescriptor imageDescriptor) { 
   // 重写父类方法 
  } 
 } 

树状拓扑结构的 Eclipse 向导

继续以电影票购票系统为例说明,现在用户对该系统提出了新的需求,要求除了预定电影票之外,订票者还能通过该系统申请成为会员,以及普通会员申请成为 VIP 会员。这样用户的操作出现了分支,我们需要在前面实现的向导基础上增加新的一个向导页,以供用户选择操作类型:电影票预订,申请成为会员或者升级为 VIP 会员。假如用户选择“电影票预订”,便进入上一节中实现的订票界面。假如用户选择“申请成为会员”或者“升级为 VIP 会员”,便分别进入另两条分支,进行相应操作。

根据上面分析,我们需要实现如下向导页。

向导页编号标题内容
A操作类型选择选择用户操作类型:电影票预订,申请成为会员或者升级为 VIP 会员
B用户类型选择选择用户类型:普通用户,普通会员,VIP 会员
C申请成为会员普通用户申请成为会员操作
D升级为 VIP 会员普通会员升级成为 VIP 会员操作
E普通用户基本信息对于普通用户,填写其基本信息,包括用户名,电话号码
F电影票信息用户选择其想看的电影,选择电影名字,放映时间,以及选择座位号
G历史记录对于会员用户,操作结束之后,将显示其历史纪录

该向导的树型拓扑结构如下。需要特别指出的是,电影票预订操作,也就是第二级节点向导页 B 处的实现方式和前面是完全不同的,这里使用的是数状的拓扑结构,而前面采用的是页面动态增加或者减少方式。
图 5. 电影订票树状拓扑结构

首先在向导页 A 中选择操作类型,如果是电影票预订操作,则进入向导页 B,如果是申请成为会员,则进入向导页 C,如果是升级为 VIP 会员,则进入向导页 D,这是第一次分支;当用户选择电影票预订并进入向导页 B 之后,用户再选择其用户类型,这是该向导的第二次分支,如果用户是普通用户,则进入向导页 E 填写普通用户基本信息,然后进入向导页 F 进行选票并结束;如果用户是会员或者 VIP 会员,则直接进入向导页 F,选票结束之后,进入向导页 G,查看其历史纪录。

普通用户预定电影票操作:首先在向导页 A 中,选择电影票预订,进入订票分支;然后在向导页 B 中,选择普通用户,进入普通用户订票分支。见下图。
图 6. 普通用户电影订票流程

  查看原图(大图)

会员用户预定电影票操作:首先在向导页 A 中,选择电影票预订,进入订票分支;然后在向导页 B 中,选择会员用户,输入会员用户名和密码,进入会员用户订票分支。见下图。
图 7. 会员用户电影订票流程

  查看原图(大图)

申请成为会员操作:在向导页 A 中,选择申请成为会员,进入申请成为会员分支。见下图。
图 8. 申请成为会员流程

为了实现树状拓扑结构,文章提供了一个树状向导的抽象类 TreePageWizard,以及向导页类 TreeWizardPage 供开发人员使用。用户使用时,只需要将其向导类继承 TreePageWizard,向导页类继承 TreeWizardPage,重写这两个类中相应的方法,便可以方便地实现树状拓扑结构向导。

向导类 TreePageWizard 继承自类 org.eclipse.jface.wizard.Wizard,在原 Wizard 的基础上进行扩展,使用变量 TreeWizardPage rootPage 来存储树结构的根节点对应的向导页,树结构的根节点即是该向导的起始页。使用变量 Set<TreeWizardPage> pages 来存储树结构中的所有向导页。类中所有操作都是围绕这两个变量进行,包括树结构中节点的添加、删除、树结构分支的选择等等。和动态向导不同的是,pages 里面保存的向导页是向导中所有可能的页面,而 DynamicPageWizard 中存储的是当前向导中的页面,并且 pages 的类型是 Set<TreeWizardPage>,DynamicPageWizard 中类型是 List<IWizardPage>,详细的内容见下面清单。同样,由于 pages 变量覆盖了原 org.eclipse.jface.wizard.Wizard 中的 pages 变量,之前基于该变量的所有方法都需要重写,读者可以根据不同的 JDK 版本以及自己的需要,将必须重写部分内容补上。

清单 2. 树状拓扑向导父类 TreePageWizard

 public abstract class TreePageWizard extends Wizard { 
  /** 
   * 树型向导的起始页 
   * Root page. 
   */ 
  private TreeWizardPage rootPage = null; 
   
  /** 
   * 向导中的所有向导页 
   * All the pages in the wizard. 
   */ 
  private Set <TreeWizardPage> pages = new HashSet <TreeWizardPage>(); 
 
  /** 
   * 构造函数 
   * Creates a new empty wizard. 
   */ 
  protected TreePageWizard () { 
    super(); 
  } 
 
  /** 
   * 构造函数 
   * Creates a new empty wizard. 
   */ 
  protected TreePageWizard (IWizardPage page) { 
    super(); 
   if(page instanceof TreeWizardPage) { 
    rootPage = (TreeWizardPage)page; 
    addPage(rootPage); 
   } 
  } 
   
  /** 
   * 设置树结构的根节点,以及向导的起始页 
   */ 
  public void setRootPage(IWizardPage page) { 
   if(page instanceof TreeWizardPage) { 
    addPage((TreeWizardPage)page); 
    rootPage = (TreeWizardPage)page; 
   } 
  } 
   
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#addPage(org.eclipse.jface.wizard.IWizardPage) 
   */ 
  public void addPage(IWizardPage page) { 
   // 判断是否 TreeWizardPage 类型的向导,如果不是,则返回 
   if(!(page instanceof TreeWizardPage)) 
    return; 
   
   // 添加该向导页 
   pages.add((TreeWizardPage)page); 
   page.setWizard(this); 
   
   // 添加该向导页的所有子向导页 
   List <TreeWizardPage> children = ((TreeWizardPage)page).getChildren(); 
   for(int i = 0; i < children.size(); i++) { 
    addPage(children.get(i)); 
   } 
  } 
   
  /** 
   * 插入向导页,第一个参数为待插入的向导页,第二个参数为插入位置之前的向导页 
   * 
   * @param page 
   * @param prviousPage 
   * @return 
   */ 
  public void addPage(TreeWizardPage page, TreeWizardPage previousPage) { 
   boolean exist = pages.contains(previousPage); 
   if(!exist) 
    return; 
   
   if (previousPage.getChildren().add(page)) 
    addPage(page); 
  } 
   
  /** 
   * 从向导中删除向导页 
   * 
   * @param page 
   * @return 
   */ 
  public void removePage(TreeWizardPage page) { 
   pages.remove(page); 
   List <TreeWizardPage> children = page.getChildren(); 
   for(int i = 0; i < children.size(); i++) { 
    removePage(children.get(i)); 
   } 
  } 
   
  /** 
   * 从向导中删除向导页,第一个参数为待删除的向导页,第二个参数为删除位置之前的向导页 
   * 
   * @param page 
   * @param prviousPage 
   * @return 
   */ 
  public void removePage(TreeWizardPage page, TreeWizardPage previousPage) { 
   boolean exist = pages.contains(previousPage); 
   if(exist) { 
    if (previousPage.getChildren().remove(page)) 
    removePage(page); 
   } 
  } 
   
  /** 
   * 从向导中删除向导页,第一个参数为待删除的向导页的类名,第二个参数为删除位置之前的向导页 
   * 
   * @param className 
   * @param previousPage 
   * @return 
   */ 
  public boolean removePage(String className, TreeWizardPage previousPage) { 
   boolean exist = pages.contains(previousPage); 
   if(!exist) 
    return false; 
   
   List <TreeWizardPage> children = previousPage.getChildren(); 
   for(int i = 0; i < children.size(); i++) { 
    TreeWizardPage temp = children.get(i); 
    if(temp.getClass().getCanonicalName().equalsIgnoreCase(className)) { 
    if (children.remove(temp)) { 
     removePage(temp); 
      return true; 
      } else 
      return false; 
    } 
   } 
   
   return false; 
  } 
   
 /* 
 * (non-Javadoc) 
 * @see org.eclipse.jface.wizard.Wizard#addPages() 
 */ 
  public void addPages() { 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#canFinish() 
   */ 
  public boolean canFinish() { 
   // 检测是否所有向导页的设置都完成,整个向导可以结束 
   TreeWizardPage page = rootPage; 
   while (page != null) { 
    if(!page.isPageComplete()) 
    return false; 
    page = page.getNextPage(); 
   } 
 
    return true; 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#createPageControls 
   * (org.eclipse.swt.widgets.Composite) 
   */ 
  public void createPageControls(Composite pageContainer) { 
   // 重写父类方法 
   ... 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#dispose() 
   */ 
  public void dispose() { 
   // 重写父类方法 
   ... 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#getDefaultPageImage() 
   */ 
  public Image getDefaultPageImage() { 
   // 重写父类方法 
   ... 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#getPreviousPage 
   * (org.eclipse.jface.wizard.IWizardPage) 
   */ 
  public IWizardPage getPreviousPage(IWizardPage page) { 
   // 获取特定向导页之前的页面 
    if(page == null) 
     return null; 
     
    if(!(page instanceof TreeWizardPage)) 
     return null; 
 
    return ((TreeWizardPage)page).getPreviousPage(); 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#getNextPage 
   * (org.eclipse.jface.wizard.IWizardPage) 
   */ 
  public IWizardPage getNextPage(IWizardPage page) { 
   // 获取特定向导页之后的页面 
   if(page == null) 
    return null; 
   
   if(!(page instanceof TreeWizardPage)) 
    return null; 
   
   return page.getNextPage(); 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#getPage(java.lang.String) 
   */ 
  public IWizardPage getPage(String name) { 
   // 根据名字,获取特定向导页 
   Iterator <TreeWizardPage> iter = pages.iterator(); 
   while(iter.hasNext()) { 
      IWizardPage page = (IWizardPage) iter.next(); 
      String pageName = page.getName(); 
      if (pageName.equals(name)) { 
   return page; 
  } 
    } 
    return null; 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#getPageCount() 
   */ 
  public int getPageCount() { 
   // 重写父类方法,获取该树型结构向导中所有的向导页的数目 
   ... 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#getPages() 
   */ 
  public IWizardPage[] getPages() { 
   // 重写父类方法,获取该树型结构向导中所有的向导页 
   ... 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#getStartingPage() 
   */ 
  public IWizardPage getStartingPage() { 
   // 重写父类方法,获取起始向导页 
   ... 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#performCancel() 
   */ 
  public boolean performCancel() { 
   // 重写父类方法 
   ... 
  } 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#needsPreviousAndNextButtons() 
   */ 
  public boolean needsPreviousAndNextButtons() { 
   // 重写父类方法 
   ... 
  } 
   
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#setForcePreviousAndNextButtons(boolean) 
   */ 
  public void setForcePreviousAndNextButtons(boolean b) { 
   // 重写父类方法 
   ... 
  } 
   
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#performFinish() 
   */ 
  public abstract boolean performFinish(); 
 
  /* 
   * (non-Javadoc) 
   * @see org.eclipse.jface.wizard.Wizard#setDefaultPageImageDescriptor 
   * (org.eclipse.jface.resource.ImageDescriptor) 
   */ 
  public void setDefaultPageImageDescriptor(ImageDescriptor imageDescriptor) { 
    // 重写父类方法 
    ... 
  } 
 } 

我们再来看一下向导页类 TreeWizardPage 的实现,该类继承了类 org.eclipse.jface.wizard.WizardPage,树状向导中所有的向导页都必须继承此类,使用变量 List <TreeWizardPage> children 存储该树节点所有的孩子节点,使用变量 TreeWizardPage nextPage 存储当前向导页将要跳转到的下一向导页,nextPage 必须是 children 中的某一个向导页。TreeWizardPage 类中其他方法实现了对该向导页所有孩子节点的增加、删除、获取等操作,以及设置下一向导页等操作,完整内容见下面清单。

清单 3. 树状拓扑向导页父类 TreeWizardPage

public class TreeWizardPage extends WizardPage { 
  /** 
  * 当前向导页所有可能的下一个向导页 
  */ 
  private List <TreeWizardPage> children = new ArrayList <TreeWizardPage>(); 
 
  /** 
  * 当前向导的下一个向导页 
  */ 
  private TreeWizardPage nextPage = null; 
 
  /** 
  * 构造函数 
  * 
  * @param pageName 
  */ 
  protected TreeWizardPage(String pageName) { 
   super(pageName); 
  } 
 
  /** 
  * 构造函数 
  * 
  * @param pageName 
  * @param title 
  * @param titleImage 
  */ 
  protected TreeWizardPage(String pageName, String title, 
     ImageDescriptor titleImage) { 
   super(pageName, title, titleImage); 
  } 
 
  /* 
  * (non-Javadoc) 
  * 
  * @see 
  * org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets 
  * .Composite) 
  */ 
  public void createControl(Composite parent) { 
  } 
 
  /* 
  * (non-Javadoc) 
  * 
  * @see org.eclipse.jface.wizard.WizardPage#getNextPage() 
  */ 
  public TreeWizardPage getNextPage() { 
   return nextPage; 
  } 
 
  /** 
  * 设置该向导的下一页 
  * 
  * @param nextPage 
  *      the nextPage to set 
  */ 
  public void setNextPage(TreeWizardPage nextPage) { 
   for (int i = 0; i < children.size(); i++) { 
    if (children.get(i) == nextPage) { 
     this.nextPage = nextPage; 
     updateContainerButton(); 
    } 
   } 
 
   this.nextPage = null; 
  } 
 
  /** 
  * 设置该向导的下一页 
  * 
  * @param className 
  */ 
  public void setNextPage(String className) { 
  int number = -1; 
   for (int i = 0; i < children.size(); i++) { 
    if (children.get(i).getClass().getCanonicalName().equalsIgnoreCase(className)) 
     number = i; 
   } 
   if (number != -1) { 
    this.nextPage = children.get(number); 
    updateContainerButton(); 
   } else 
    this.nextPage = null; 
  } 
 
  /** 
  * 添加可能的下一个向导页 
  * 
  * @param page 
  */ 
  public void addChild(TreeWizardPage page) { 
   if (page != null) { 
    children.add(page); 
    page.setPreviousPage(this); 
   } 
  } 
 
  /** 
  * 删除可能的下一个向导页 
  * 
  * @param page 
  */ 
  public void removeChild(TreeWizardPage page) { 
   if (page != null) { 
    if (children.contains(page)) 
     children.remove(page); 
   } 
  } 
 
  /** 
  * 获取所有可能的下一个向导页 
  * 
  * @return the children 
  */ 
  public List <TreeWizardPage> getChildren() { 
   return children; 
  } 
 
  /** 
  * 更新向导中的按钮,包括上一步按钮,下一步按钮,结束按钮以及取消按钮 
  */ 
  public void updateContainerButton() { 
   getContainer().updateButtons(); 
  } 
 } 

关于上文中两个例子的具体实现,读者可以在附件 EclipseWizardExtension.zip 中找到,考虑到不同 JDK 以及版权的问题,并没有将两种向导的父类 DynamicPageWizard 和 TreePageWizard 放在附件中,读者仅需要在 org.eclipse.expand.wizard 包中重建这两个类,并把文中省略部分补全即可。

小结

本文对 Eclipse 向导机制进行了两个方面的扩展,在原有 Eclipse 向导的基础上,扩展实现了一种动态页数的向导,以及一种具有树状拓扑结构的向导。动态页数向导支持在向导中任意添加或者删除新的向导页,实现时向导类需要继承 DynamicPageWizard 类,并重写动态添加或者删除向导页方法;而树状拓扑结构使得向导根据用户不同选择,其流程可以实现分支,树状向导需要继承 TreePageWizard 类,向导页需要继承 TreeWizardPage 类,并分别重写父类中的相应方法。基于这两种扩展,用户可以快速编写复杂的 Eclipse 向导实现,满足实际需要。

Tags:Eclipse 向导 机制

编辑录入:爽爽 [复制链接] [打 印]
[]
  • 好
  • 好的评价 如果觉得好,就请您
      0%(0)
  • 差
  • 差的评价 如果觉得差,就请您
      0%(0)
赞助商链接