How to write a Multi Page Editor

From Bioclipse
Jump to: navigation, search
Development tutorial
Responsible author:Ola
Bioclipse version:N/A
"N/A" is not a number.
Last updated:2009-10-10
Tags:


Define the editor in plugin.xml

Below is shown the JmolEditor's entry:

  <extension
        point="org.eclipse.ui.editors">
     <editor
           name="Jmol Editor"
           extensions="pdb,cml"
         icon="icons/molecule3D.gif"
           contributorClass="net.bioclipse.jmol.editors.JmolEditorContributor"
           class="net.bioclipse.jmol.editors.JmolEditor"
           id="net.bioclipse.jmol.editors.JmolEditor">
     </editor>
  </extension>


Use content types

Instead of hardcoding fileextensions to your editor, use content types.

TBC

Implement the editor

Extend MultiPageEditorPart or FormEditor. Bioclipse preferes the Forms layout (see http://www.eclipse.org/articles/Article-Forms/article.html and http://www.eclipse.org/resources/resource.php?id=404 and http://www.ibm.com/developerworks/opensource/library/os-eclipse-forms/ and http://www.jdg2e.com/forms/EclipseForms.html).

Define the model

All editors should have an underlying model, which is a class that handles the information processed by the editor, and a method to serialize this information to byte[], preferably as XML but in some cases plain text. The GUI code on the pages collect and store information in this model, and upon save the information is serialized to file.


Initialization

The editor has an init(..) method that can be used to read in the Resource into the model.

       IFileEditorInput finput = (IFileEditorInput) input;

       IFile file=finput.getFile();


Add pages

The method addPages() allows us to add pages to the MPE (pages should extend FormEditor if based on forms, or EditorPage (EditorPart?) if non-Forms-based).


React on resource changes

Let the pages and editor implement IResourceChangeListener to listen for any external changes to the resource.

Here is an example from the JmolEditor that reacts if the current resource is deleted or the project of the resource is closed:

   /**
    * Handle resource changes
    */
   public void resourceChanged(final IResourceChangeEvent event){
 
       final IEditorInput input=getEditorInput();
       if (!( input instanceof IFileEditorInput ))
           return;
       final IFile jmolfile=((IFileEditorInput)input).getFile();
       
       /*
        * Closes editor if resource is deleted
        */
       if (event.getType() == IResourceChangeEvent.POST_CHANGE) {
           
           IResourceDelta rootDelta = event.getDelta();
           //get the delta, if any, for the documentation directory
           
           final List<IResource> deletedlist = new ArrayList<IResource>();
           
           IResourceDelta docDelta = rootDelta.findMember(jmolfile.getFullPath());
           if (docDelta != null){
               IResourceDeltaVisitor visitor = new IResourceDeltaVisitor() {
                   public boolean visit(IResourceDelta delta) {
                      //only interested in removal changes
                      if ((delta.getFlags() & IResourceDelta.REMOVED) == 0){
                          deletedlist.add( delta.getResource() );
                      }
                      return true;
                   }
                };
                try {
                   docDelta.accept(visitor);
                } catch (CoreException e) {
                   LogUtils.handleException( e, logger, Activator.PLUGIN_ID );
                }
           }
               
           if (deletedlist.size()>0 && deletedlist.contains( jmolfile )){
               Display.getDefault().asyncExec(new Runnable() {
                   public void run() {
                       if (getSite()==null) 
                           return;
                       if (getSite().getWorkbenchWindow()==null) 
                           return;
                       
                       IWorkbenchPage[] pages = getSite().getWorkbenchWindow()
                                                         .getPages();
                       for (int i = 0; i<pages.length; i++) {
                               IEditorPart editorPart
                                 = pages[i].findEditor(input);
                               pages[i].closeEditor(editorPart,true);
                       }
                   }
               });
           }
           

           
       }

       /*
        * Closes all editors with this editor input on project close.
        */
       if (event.getType() == IResourceChangeEvent.PRE_CLOSE) {
           Display.getDefault().asyncExec(new Runnable() {
               public void run() {
                   if (getSite()==null) 
                       return;
                   if (getSite().getWorkbenchWindow()==null) 
                       return;
                   
                   IWorkbenchPage[] pages = getSite().getWorkbenchWindow()
                                                     .getPages();
                   for (int i = 0; i<pages.length; i++) {
                       if ( jmolfile.getProject()
                               .equals( event.getResource() )) {
                           IEditorPart editorPart
                             = pages[i].findEditor(input);
                           pages[i].closeEditor(editorPart,true);
                       }
                   }
               }
           });
       }
   }

Managing dirty state

TBC


Links