Someone asked me this question in email and I figure it’s better to commit the results to Google than to just answer via the original medium. The question, in a nutshell, is this:
I have some model object that is backed by two files, one primary and one secondary. In my own model navigator I show only the logical resources and when a user clicks on a model element I open my editor on the primary file. If the user views my project in the resource navigator they see both the primary and secondary files. If they open the primary file my editor is opened but if they try and open the secondary file there’s a problem. If I associate an editor with the secondary file then I have two copies of the same model object open at the same time. If I don’t associate an editor then the user cannot edit the model via the secondary file. What do I do?
The solution is
. This interface was created in Eclipse 3.1 to help address this class of issues.
is very simple and contains only one method :
. You associate implementations of this class with your editor via the
attribute in your
extension. Whenever a user requests to open a file via
(or via the three arguement open method with
) all open editors will be consulted. If they have an associated
this class will be instantiated and its
method will called with the opened editor and the new file the user wishes to open. If this method returns
than instead of opening a new editor the existing editor is shown instead.
Imagine the following
:
<plugin> <extension point="org.eclipse.ui.editors"> <editor class="org.eclipse.ui.editormatchingexample.EditorMatchingEditor" default="false" filenames="primary.file,secondary.file" icon="sample.gif" id="org.eclipse.ui.editorMatchingExample.editor1" matchingStrategy="org.eclipse.ui.editormatchingexample.ExampleStrategy" name="Editor Matching Editor"> </editor> </extension>
Here we have an editor type associated with files whose name is either “primary.file” or “secondary.file”. We also provide a
class that looks something like this:
public class ExampleStrategy implements IEditorMatchingStrategy { public boolean matches(IEditorReference editorRef, IEditorInput input) { // see if this input is backed by a file. If not then exit early IFile inputFile = ResourceUtil.getFile(input); if (inputFile != null && inputFile.getParent() instanceof IProject) { String name = inputFile.getName(); // we can match primary files and secondary files if (name.equals("primary.file") || name.equals("secondary.file")) { try { IFile editorFile = ResourceUtil.getFile(editorRef .getEditorInput()); // if they're in the same project they represent the same logical object return editorFile != null && inputFile.getProject().equals( editorFile.getProject()); } catch (PartInitException e) { e.printStackTrace(); return false; } } } return false; }}
If we create a file called “primary.file” it will open an instance of
. Should we create a file called “secondary.file” and attempt to open it the Workbench will iterate through open editors looking for one it can reuse. When it reaches our existing editor on “primary.file”
will be called with the editor reference to the editor on “primary.file” and an IEditorInput matching “secondary.file”. As you can see above, our
will test for these file names and if both files exit in the same project it will return
. The Workbench will then activate our editor on “primary.file” instead of opening a new one on “secondary.file”.
Clearly there is more to this problem than simply reusing editors. Your editor implementation needs to understand some model residing in more than one file and react accordingly on activation. For example, it would be possible to open “secondary.file” first and then reuse its editor when “primary.file” is opened. It’s up to you as an editor implementor to handle this case as well as all of the other issues that come with this level of editor complexity.






