首页 > 代码库 > 5.27 按步就搬 Editor如何保存和打开文件
5.27 按步就搬 Editor如何保存和打开文件
http://www.benisoft.net/day10/index.html
Eclipse通过文件后缀名来决定该文件该用哪个Editor打开,在实现org.eclipse.ui.editors 扩展点时,指定extensions为iti,这样,Eclipse碰到以.iti为文件后缀的文件,就会调用ItineraryEditor打开。
Eclipse首先调用ItineraryEditor.init(...)方法。这个方法的实现一般都会调用基类的init(...)方法 来保存site。site是Eclipse提供的IEditorSite对象,通过这个对象, Editor可以获得Eclipse窗口的一些功能,比如工具栏。 接下来,检查editorInput类型。Eclipse对于导入到Eclipse项目(或者说由Eclipse管理的文件), 和未导入到Eclipse项目的(也就是说直接在文件系统上,没有纳入Eclipse管理的文件)是区别对待的。 它们所对应的IEditorInput是不同的,这个我们会在介绍Resource的时候专门讨论。 因为Itinerary例子不需要将文件导入到Eclipse项目中,可以直接打开文件系统上的文件, 所以我们检查editorInput是否是FileStoreEditorInput实例。请记住,非Eclipse管理的文件所对应的 IEditorInput是FileStoreEditorInput。然后生成一个ItineraryParser对象, 从FileStoreEditorInput获取File对象,并交由parser打开,最后将Editor的标题设置为文件名。
protected void setInput(IEditorInput editorInput) { super.setInput(editorInput); // Referred by DAY10 <<< if (editorInput instanceof FileStoreEditorInput) { // For "File -> Open File" try { FileStoreEditorInput pathEditorInput = (FileStoreEditorInput) editorInput; ItineraryParser parser = new ItineraryParser(); File file = new File(pathEditorInput.getURI().toURL().getFile()); itinerary = parser.parse(file); setPartName(file.getName()); } catch (IOException e) { e.printStackTrace(); } }
到这里为止,ItineraryEditor成功打开.iti文件。接下来看一下如何保存文件。
保存文件
说起来也很简单,两大部分。首先需要告诉Eclipse,打开的文件用户已经编辑过了,需要保存, 其次就是调用方法将Itinerary内容写入iti文件。
第一步,如果需要支持Save As,则ItineraryEditor继承isSaveAsAllowed()方法。
public boolean isSaveAsAllowed() { return true; }
第二步,ItineraryEditor继承isDirty()方法,Eclipse会调用这个方法来知道打开的文件是否需要保存。 这里我们直接返回Itinerary的isDirty()方法(Itinerary维护一个boolean变量dirty, 任何修改Itinerary对象的方法都会将这个boolean变量设置为true)。
public boolean isDirty() { return itinerary.isDirty(); }
第三步,需要重载doSave(...)和doSaveAs()这两个方法,分别对应于File菜单里的Save和Save As这两个菜单。 当用户选择Save或Save As菜单时,会分别调用SaveAction或SaveAsAction,它们分别会调用Editor的 doSave(...)和doSaveAs()方法。我们重载doSave(...)方法, 将用户编辑过的Itinerary对象写入文件保存,然后发送PROP_DIRTY事件,通知EditorPart清除文件已修改标记。 另外,doSave(...)方法接受IProgressMonitor对象,当文件保存非常耗时的情况下, 就可以及时通知用户文件保存的状态。我们假设Itinerary的文件都很小,所以就忽略这个monitor了。
public void doSave(IProgressMonitor monitor) { IEditorInput editorInput = getEditorInput(); ... } else if (editorInput instanceof ExternalFileEditorInput) { try { ExternalFileEditorInput pathEditorInput = (ExternalFileEditorInput) editorInput; File file = pathEditorInput.getFile(); OutputStream os = new FileOutputStream(file); ItineraryWriter writer = new ItineraryWriter(itinerary); writer.write(os); os.close(); itinerary.setDirty(false); firePropertyChange(PROP_DIRTY); } catch (Exception e) { e.printStackTrace(); } }
doSaveAs()方法,需要弹出文件保存对话框,提示用户输入新文件路径名,其他和doSave()类似。 两者代码由很多相似,实际开发时,应该考虑代码合并,这里为了示例清楚起见,就保留重复代码了。
public void doSaveAs() { IEditorInput editorInput = getEditorInput(); if (editorInput instanceof ExternalFileEditorInput || editorInput instanceof FileStoreEditorInput) { FileDialog fileDialog = new FileDialog(getSite().getShell(), SWT.SAVE); fileDialog.setFileName("myitinerary.iti"); fileDialog.setFilterExtensions(new String[] { "iti", "*" }); fileDialog.setFilterIndex(0); fileDialog.setFilterNames(new String[] { "Itinerary Files (*.iti)", "All Files (*.*)" }); fileDialog.setText("Save File"); fileDialog.setOverwrite(true); String filePath = fileDialog.open(); if (filePath != null) { try { ItineraryWriter writer = new ItineraryWriter(itinerary); File file = new File(filePath); writer.write(file); ExternalFileEditorInput input = new ExternalFileEditorInput(file); setInput(input); firePropertyChange(PROP_DIRTY); } catch (IOException e) { e.printStackTrace(); } } }