在面向行为的设计中在 类 之间传递信息
Passing information between classes in a behaviour oriented design
我决定让我的小型文本编辑器适应之前 中建议的行为设计模式。很快就清楚了行为设计如何通过允许添加组合键来调用打开、保存操作等来帮助扩展我的小项目。
不过这个设计主要是用classes,不知道怎么让classes相互通信。添加了一个新的 class 来处理保存当前文件 (SaveFile),但我无法捕获当前文件的 URI(使用 DocumentFileSelector class)。
我怀疑这样做的方法是通过 class 属性,但我无法真正让 document_selector 变量继承 属性,所以我可以将其传递给 SaveDocument class.
代码的相关部分如下:
uses
Gtk
init
Intl.setlocale()
Gtk.init (ref args)
var document = new Text( "Lorem Ipsum" )
var header = new Header ( "My text editor" )
var body = new DocumentView( document )
var editor = new EditorWindow (header,body )
var document_selector = new DocumentFileSelector( editor )
var load_new_content_command = new Load( document, document_selector )
var create_new = new CreateNew( document )
var save_file = new SaveFile( document )
header.add_item( new OpenButton( load_new_content_command ) )
header.add_item( new CreateNewButton ( create_new ) )
header.add_item( new SaveFileButton( save_file ))
editor.show_all ()
Gtk.main ()
class EditorWindow:Window
construct( header:Header, body:DocumentView )
this.window_position = WindowPosition.CENTER
this.set_default_size( 400, 400 )
this.destroy.connect( Gtk.main_quit)
this.set_titlebar(header)
var box = new Box (Gtk.Orientation.VERTICAL, 1)
box.pack_start(body, true, true, 0)
this.add(box)
class Header:HeaderBar
construct( title:string = "" )
this.show_close_button = true
this.set_title( title )
def add_item( item:Widget )
this.pack_start( item )
class SaveFileButton:ToolButton
construct( command:Command )
this.icon_widget = new Image.from_icon_name(
"document-save",
IconSize.SMALL_TOOLBAR
)
this.clicked.connect( command.execute )
class OpenButton:ToolButton
construct( command:Command )
this.icon_widget = new Image.from_icon_name(
"document-open",
IconSize.SMALL_TOOLBAR
)
this.clicked.connect( command.execute )
class CreateNewButton:ToolButton
construct( command:Command )
this.icon_widget = new Image.from_icon_name(
"document-new",
IconSize.SMALL_TOOLBAR
)
this.clicked.connect( command.execute )
class DocumentView:ScrolledWindow
construct( document:TextBuffer )
var view = new TextView.with_buffer( document )
view.set_wrap_mode( Gtk.WrapMode.WORD )
this.add( view )
interface Command:Object
def abstract execute()
interface DocumentSelector:Object
def abstract select():bool
def abstract get_document():string
class Text:TextBuffer
construct ( initial:string = "" )
this.text = initial
class SaveFile:Object implements Command
_receiver:TextBuffer
construct( receiver:TextBuffer )
_receiver = receiver
def execute()
start, end : Gtk.TextIter
_receiver.get_start_iter(out start)
_receiver.get_end_iter(out end)
try
FileUtils.set_contents (_filename, _receiver.get_text(start, end,
false))
except ex : FileError
print "%s\n", ex.message
class DocumentFileSelector:Object implements DocumentSelector
_parent:Window
_uri:string = ""
construct( parent:Window )
_parent = parent
def select():bool
var dialog = new FileChooserDialog( "Open file",
_parent,
FileChooserAction.OPEN,
dgettext( "gtk30", "_OK"),
ResponseType.ACCEPT,
dgettext( "gtk30", "_Cancel" ),
ResponseType.CANCEL
)
selected:bool = false
var response = dialog.run()
case response
when ResponseType.ACCEPT
_uri = dialog.get_uri()
selected = true
dialog.destroy()
return selected
def get_document():string
return "Reading the text from a URI is not implemented\n%s".printf(_uri)
class Load:Object implements Command
_receiver:TextBuffer
_document_selector:DocumentSelector
construct( receiver:TextBuffer, document_selector:DocumentSelector )
_receiver = receiver
_document_selector = document_selector
def execute()
if _document_selector.select()
_receiver.text = _document_selector.get_document()
class CreateNew:Object implements Command
_receiver:TextBuffer
construct( receiver:TextBuffer )
_receiver = receiver
def execute()
var should_I_save=new MessageDialog (null, Gtk.DialogFlags.MODAL,
Gtk.MessageType.INFO, Gtk.ButtonsType.YES_NO, "Hello world!")
should_I_save.format_secondary_text (
"This will delete the contets. Are you sure?")
case should_I_save.run()
when ResponseType.YES
_receiver.set_text("")
should_I_save.destroy ()
when ResponseType.NO
should_I_save.destroy ()
问题
如何将上次打开文件的URI信息传递给SaveDocumentclass?
作为一个额外的问题,每个 class 构造后的第一行是做什么的?读起来像这样的行:
构建(parent:Window)
_parent = parent
编辑
仍然无法解决问题,我最近尝试在 DocumentFileSelector class 中创建另一个名为 whichFile() 的方法。此方法只会 return uri。我在执行时遇到错误:FileUtils.set_contents ( DocumentFileSelector.whichFile(), _receiver.get_text(start, end,false))
.
这里是对代码的修改:
class SaveFile:Object implements Command
_receiver:TextBuffer
construct( receiver:TextBuffer )
_receiver = receiver
def execute()
start, end : Gtk.TextIter
_receiver.get_start_iter(out start)
_receiver.get_end_iter(out end)
try
FileUtils.set_contents ( DocumentFileSelector.whichFile(), _receiver.get_text(start, end,false))
except ex : FileError
print "%s\n", ex.message
class DocumentFileSelector:Object implements DocumentSelector
_parent:Window
_uri:string = ""
construct( parent:Window )
_parent = parent
def select():bool
var dialog = new FileChooserDialog( "Open file",
_parent,
FileChooserAction.OPEN,
dgettext( "gtk30", "_OK"),
ResponseType.ACCEPT,
dgettext( "gtk30", "_Cancel" ),
ResponseType.CANCEL
)
selected:bool = false
var response = dialog.run()
case response
when ResponseType.ACCEPT
_uri = dialog.get_uri()
selected = true
dialog.destroy()
return selected
def whichFile():string
return _uri
def get_document():string
return "Reading the text from a URI is not implemented\n%s".printf(_uri)
你快到了......
只需将对 DocumentSelector
的引用添加到您的 SaveFile
命令,就像您对 LoadFile
命令所做的那样:
class SaveFile:Object implements Command
_receiver:TextBuffer
_document_selector:DocumentSelector
construct( receiver:TextBuffer, document_selector:DocumentSelector)
_receiver = receiver
_document_selector = document_selector
然后您可以在保存的 DocumentSelector
:
上调用新的 whichFile()
方法
def execute()
start, end : Gtk.TextIter
_receiver.get_start_iter(out start)
_receiver.get_end_iter(out end)
try
FileUtils.set_contents (_document_selector.whichFile(), _receiver.get_text(start, end,
false))
except ex : FileError
print "%s\n", ex.message
我决定让我的小型文本编辑器适应之前
不过这个设计主要是用classes,不知道怎么让classes相互通信。添加了一个新的 class 来处理保存当前文件 (SaveFile),但我无法捕获当前文件的 URI(使用 DocumentFileSelector class)。
我怀疑这样做的方法是通过 class 属性,但我无法真正让 document_selector 变量继承 属性,所以我可以将其传递给 SaveDocument class.
代码的相关部分如下:
uses
Gtk
init
Intl.setlocale()
Gtk.init (ref args)
var document = new Text( "Lorem Ipsum" )
var header = new Header ( "My text editor" )
var body = new DocumentView( document )
var editor = new EditorWindow (header,body )
var document_selector = new DocumentFileSelector( editor )
var load_new_content_command = new Load( document, document_selector )
var create_new = new CreateNew( document )
var save_file = new SaveFile( document )
header.add_item( new OpenButton( load_new_content_command ) )
header.add_item( new CreateNewButton ( create_new ) )
header.add_item( new SaveFileButton( save_file ))
editor.show_all ()
Gtk.main ()
class EditorWindow:Window
construct( header:Header, body:DocumentView )
this.window_position = WindowPosition.CENTER
this.set_default_size( 400, 400 )
this.destroy.connect( Gtk.main_quit)
this.set_titlebar(header)
var box = new Box (Gtk.Orientation.VERTICAL, 1)
box.pack_start(body, true, true, 0)
this.add(box)
class Header:HeaderBar
construct( title:string = "" )
this.show_close_button = true
this.set_title( title )
def add_item( item:Widget )
this.pack_start( item )
class SaveFileButton:ToolButton
construct( command:Command )
this.icon_widget = new Image.from_icon_name(
"document-save",
IconSize.SMALL_TOOLBAR
)
this.clicked.connect( command.execute )
class OpenButton:ToolButton
construct( command:Command )
this.icon_widget = new Image.from_icon_name(
"document-open",
IconSize.SMALL_TOOLBAR
)
this.clicked.connect( command.execute )
class CreateNewButton:ToolButton
construct( command:Command )
this.icon_widget = new Image.from_icon_name(
"document-new",
IconSize.SMALL_TOOLBAR
)
this.clicked.connect( command.execute )
class DocumentView:ScrolledWindow
construct( document:TextBuffer )
var view = new TextView.with_buffer( document )
view.set_wrap_mode( Gtk.WrapMode.WORD )
this.add( view )
interface Command:Object
def abstract execute()
interface DocumentSelector:Object
def abstract select():bool
def abstract get_document():string
class Text:TextBuffer
construct ( initial:string = "" )
this.text = initial
class SaveFile:Object implements Command
_receiver:TextBuffer
construct( receiver:TextBuffer )
_receiver = receiver
def execute()
start, end : Gtk.TextIter
_receiver.get_start_iter(out start)
_receiver.get_end_iter(out end)
try
FileUtils.set_contents (_filename, _receiver.get_text(start, end,
false))
except ex : FileError
print "%s\n", ex.message
class DocumentFileSelector:Object implements DocumentSelector
_parent:Window
_uri:string = ""
construct( parent:Window )
_parent = parent
def select():bool
var dialog = new FileChooserDialog( "Open file",
_parent,
FileChooserAction.OPEN,
dgettext( "gtk30", "_OK"),
ResponseType.ACCEPT,
dgettext( "gtk30", "_Cancel" ),
ResponseType.CANCEL
)
selected:bool = false
var response = dialog.run()
case response
when ResponseType.ACCEPT
_uri = dialog.get_uri()
selected = true
dialog.destroy()
return selected
def get_document():string
return "Reading the text from a URI is not implemented\n%s".printf(_uri)
class Load:Object implements Command
_receiver:TextBuffer
_document_selector:DocumentSelector
construct( receiver:TextBuffer, document_selector:DocumentSelector )
_receiver = receiver
_document_selector = document_selector
def execute()
if _document_selector.select()
_receiver.text = _document_selector.get_document()
class CreateNew:Object implements Command
_receiver:TextBuffer
construct( receiver:TextBuffer )
_receiver = receiver
def execute()
var should_I_save=new MessageDialog (null, Gtk.DialogFlags.MODAL,
Gtk.MessageType.INFO, Gtk.ButtonsType.YES_NO, "Hello world!")
should_I_save.format_secondary_text (
"This will delete the contets. Are you sure?")
case should_I_save.run()
when ResponseType.YES
_receiver.set_text("")
should_I_save.destroy ()
when ResponseType.NO
should_I_save.destroy ()
问题
如何将上次打开文件的URI信息传递给SaveDocumentclass?
作为一个额外的问题,每个 class 构造后的第一行是做什么的?读起来像这样的行:
构建(parent:Window)
_parent = parent
编辑
仍然无法解决问题,我最近尝试在 DocumentFileSelector class 中创建另一个名为 whichFile() 的方法。此方法只会 return uri。我在执行时遇到错误:FileUtils.set_contents ( DocumentFileSelector.whichFile(), _receiver.get_text(start, end,false))
.
这里是对代码的修改:
class SaveFile:Object implements Command
_receiver:TextBuffer
construct( receiver:TextBuffer )
_receiver = receiver
def execute()
start, end : Gtk.TextIter
_receiver.get_start_iter(out start)
_receiver.get_end_iter(out end)
try
FileUtils.set_contents ( DocumentFileSelector.whichFile(), _receiver.get_text(start, end,false))
except ex : FileError
print "%s\n", ex.message
class DocumentFileSelector:Object implements DocumentSelector
_parent:Window
_uri:string = ""
construct( parent:Window )
_parent = parent
def select():bool
var dialog = new FileChooserDialog( "Open file",
_parent,
FileChooserAction.OPEN,
dgettext( "gtk30", "_OK"),
ResponseType.ACCEPT,
dgettext( "gtk30", "_Cancel" ),
ResponseType.CANCEL
)
selected:bool = false
var response = dialog.run()
case response
when ResponseType.ACCEPT
_uri = dialog.get_uri()
selected = true
dialog.destroy()
return selected
def whichFile():string
return _uri
def get_document():string
return "Reading the text from a URI is not implemented\n%s".printf(_uri)
你快到了......
只需将对 DocumentSelector
的引用添加到您的 SaveFile
命令,就像您对 LoadFile
命令所做的那样:
class SaveFile:Object implements Command
_receiver:TextBuffer
_document_selector:DocumentSelector
construct( receiver:TextBuffer, document_selector:DocumentSelector)
_receiver = receiver
_document_selector = document_selector
然后您可以在保存的 DocumentSelector
:
whichFile()
方法
def execute()
start, end : Gtk.TextIter
_receiver.get_start_iter(out start)
_receiver.get_end_iter(out end)
try
FileUtils.set_contents (_document_selector.whichFile(), _receiver.get_text(start, end,
false))
except ex : FileError
print "%s\n", ex.message