# Mediator パターン # # Java言語で学ぶデザインパターンと同様の例題をRubyで記述した。 # # coded by Takehiro Kaga # 3月10日版 # =begin インターフェイス説明用 class Mediator def createColleagues end def colleagueChanged end end =end =begin インターフェイス説明用 class Colleague def setMediator(mediator) end def setColleagueEnabled(enabled) end end =end require 'tk' class ColleagueButton < TkButton def setMediator(mediator) @mediator = mediator end def setColleagueEnabled(enabled) # stateはnormal,active,disabled self.configure('state'=>enabled) puts "Button: " + enabled.to_s end end class ColleagueTextField < TkEntry def setMediator(mediator) @mediator = mediator end def setColleagueEnabled(enabled) self.configure('state'=>enabled) puts "Entry: " + enabled.to_s end def textValueChanged(event) puts "textValueChanged: " + event.to_s @mediator.colleagueChanged(self, event) end end class ColleagueCheckbox < TkRadioButton def setMediator(mediator) @mediator = mediator end def setColleagueEnabled(enabled) self.configure('state'=>enabled) puts "RadioButton: " + enabled.to_s end def itemStateChanged( ev ) puts "StateChanged: " + ev.to_s # デバック @mediator.colleagueChanged(self, ev) end end class LoginFrame def initialize(checkGuest, checkLogin, textUser, textPass, buttonOK, buttonCancel) @checkGuest = checkGuest @checkLogin = checkLogin @textUser = textUser @textPass = textPass @buttonOK = buttonOK @buttonCancel =buttonCancel end # Colleagueからの通知で各Colleagueの有効/無効を判定する def colleagueChanged(colleague, ev=nil ) if (colleague == @checkGuest or colleague == @checkLogin) if ev == "guest" # Guestモード @textUser.setColleagueEnabled("disabled") @textPass.setColleagueEnabled("disabled") @buttonOK.setColleagueEnabled("normal") else # Loginモード @textUser.setColleagueEnabled("normal") userpassChanged end elsif (colleague == @textUser or colleague == @textPass) puts "text--- elsif pass " + ev.to_s userpassChanged else puts "colleagueChanged:unknown colleague = " + colleague.to_s end end # textUserまたはtextPassの変更があった各Colleagueの有効/無効を判定する def userpassChanged puts "userpassChanged" if (@textUser.value.length > 0) @textPass.setColleagueEnabled("normal") if (@textUser.value.length >= 4 and @textPass.value.length >= 4) @buttonOK.setColleagueEnabled("normal") else @buttonOK.setColleagueEnabled("disabled") end else @textPass.setColleagueEnabled("disabled") @buttonOK.setColleagueEnabled("disabled") end end end # ---- Main ---- # # GUIの生成を行う check = TkVariable.new("login") f0 = TkFrame.new.pack # Guestラジオチェックボタン checkGuest = ColleagueCheckbox.new(f0, 'text'=>'Guest ', 'value'=>'guest', 'variable'=>check, 'command'=>proc{checkGuest.itemStateChanged( check )}).pack('side'=>'left') # Loginラジオチェックボタン checkLogin = ColleagueCheckbox.new(f0, 'text'=>'Login ', 'value'=>'login', 'variable'=>check, 'command'=>proc{checkLogin.itemStateChanged( check )}).pack('side'=>'right') # usernameテキストエントリ f = TkFrame.new.pack textUser = ColleagueTextField.new(f,'width'=>10).pack('side'=>'right') textUserl = TkLabel.new(f, 'text'=>'username: ').pack('side'=>'left') # passwordテキストエントリ f2 = TkFrame.new.pack textPass = ColleagueTextField.new(f2,'width'=>10, 'state'=>'disabled').pack('side'=>'right') textPassl = TkLabel.new(f2, 'text'=>'password: ').pack('side'=>'left') # OKボタン buttonOk = ColleagueButton.new(nil, 'text'=>' OK ', 'state'=>'disabled', 'command'=>proc{puts "--- OK ---"}).pack('side'=>'left') # Cancelボタン buttonCancel = ColleagueButton.new(nil, 'text'=>' Cabcel ', 'command'=>proc{puts "--Cancel--"}).pack('side'=>'right') # テキストエントリのバインド指示 Returnキーを押した時にバインド textUser.bind('KeyPress-Return', proc{textUser.textValueChanged(textUser.value)}) textPass.bind('KeyPress-Return', proc{textPass.textValueChanged(textPass.value)}) # LoginFrameの生成を行う logf = LoginFrame.new(checkGuest, checkLogin, textUser, textPass, buttonOk, buttonCancel) # Mediatorのセット checkGuest.setMediator(logf) checkLogin.setMediator(logf) textUser.setMediator(logf) textPass.setMediator(logf) buttonOk.setMediator(logf) buttonCancel.setMediator(logf) Tk.mainloop