Level: Intermediate Javier Torres (jrtorres@us.ibm.com), Staff Software Engineer, IBM
04 Sep 2007 Learn how to use EMF.Edit and Common Navigator Framework (CNF) to create a model
navigation plug-in based on a tree viewer. Build an
Eclipse plug-in that allows users to manipulate and navigate the content of an
Eclipse Modeling Framework (EMF)-based model. This will involve step-by-step guidance of developing the plug-in,
implementing the proper structures to extract the model content through the EMF edit
framework, and displaying the content in a CNF-based view part.
Typically, EMF project resources — EMF Ecore models, for
example — are displayed as single objects in a viewer (see left side of Figure 1). The limitation of this is that we cannot explore the model without opening
the associated editor. This might be particularly damaging when development is
dependent on a domain model. One way around this is to build a custom view that will
provide access to the domain model content we desire. We could build this plug-in from
scratch or use existing frameworks to ease our development effort. The following
outlines and details the procedure to create such a plug-in. By the end of this
article, we will have a viewer plug-in that can be used to navigate an Ecore model (see
right side of Figure 1).
Figure 1. Types of navigators
Background
We know what we want from this ModelNavigator plug-in, but before we go ahead and
start development, we need to have a basic understanding of the Eclipse components we
will use. We want to build a tree viewer that displays the hierarchy of a model. The
details of tree viewers are outside of the scope of this article; see Resources for more details. One important aspect to note is that
tree viewers access model objects through an adapter called a content provider and
determine how the object should be visualized through a label provider. The following
sections detail how we can access data for the content and label providers, then how we
display the model navigator.
EMF.Edit framework
The EMF.Edit framework is typically used to build editors for EMF models. To build
these editors, the framework provides command code-generation capabilities and other
classes to provide programmatic access to the models. The other set of features this
framework exposes — and most important for us — are the
convenience classes that allow EMF models to be displayed in viewers. The framework
provides this access through generic content and label providers that use an adapter
for the specific type of EMF object to display the model. These are the AdapterFactoryContentProvider and AdapterFactoryLabelProvider classes, which provide the objects,
labels, and images to the viewer for the EMF objects by delegating to item provider
adapters that know how to navigate the EMF model. This scheme is illustrated in Figure
2. It is particularly useful for our project since it shields us
from having to know how to adapt the model to the view. We simply delegate to these
generic providers.
Figure 2. EMF.Edit adapted from Eclipse help
The framework contains these item providers for the various EMF model types. However,
most of us are not going to want to build a separate navigator for each model type. We
want to access all model content from the same navigator. This is where the composed
adapter factory comes in. It will allow us to display objects from more than one EMF
model by providing an adapter factory that is able to adapt the union of objects from
multiple models.
The ComposedAdapterFactory class is another
one of the EMF.Edit convenience classes that acts as the common interface to other
adapter factories. The advantage of this, as we will see later, is that our navigator
only needs to include the item providers for the model types we are interested in as
part of the composed adapter factory. Then the composed adapter factory simply
delegates its implementation to these other providers. For example, we can make our
navigator provide a display for generator models, Ecore models, UML models, etc. When
our viewer tries to display these models, the content and label providers will simply
delegate to the adapter factory, which then delegates to the appropriate item provider,
making our development effort easier and allowing our ModelNavigator to expand to
support multiple domain models.
Common Navigator Framework
 |
More on the Common Navigator Framework
A great set of tutorials on the capabilities and uses of the Common Navigator Framework
(CNF) is available from Michael Elder on his blog (see Resources). I highly recommend that developers interested in the CMF check them out. |
|
Now that we have an entire framework that will allow us to access the model content in
our ModelNavigator, the other component we need is the actual viewer that will house
our navigator. It is possible to extend the views plug-in and implement our own view
part that will display our desired content in a tree view. However, a framework already
exists for combining content from various domains into a single view, allowing users to
manipulate and navigate an editor model in a viewer. This framework was introduced in
Eclipse V3.2 as the CNF, org.eclipse.ui.navigator, and allows developers to contribute
content, labels, actions, filters, and other capabilities to a single navigator. It
provides a way to integrate navigational viewers and provide a unified user experience.
CNF supports a single viewer for all editor model integrators, allows
nonresource-driven model content, and allows users to choose what they want to see in
their integrated viewers. The org.eclipse.ui.navigator.resources plug-in is an example of this
framework in action, which we see demonstrated in the form of a Project Explorer view.
It provides declarative viewer extensions for the IResource
model. This framework provides the quickest way for us to build our viewer, it handles
the details of the viewer implementation and only requires us to implement the content
and label providers for our model. It also gives room to expand the plug-in to other
model content, as well as to make use of the more advanced capabilities of the
framework in our viewer (for example, sorters, filters, drag and drop, etc.).
We are now ready to see these components in action and begin to create our model
navigation plug-in.
Simple navigator
To create our ModelNavigator, we will take a two-step approach. First, we set up the
basic structure of the plug-in and define its behavior. Then we will extend this simple
plug-in to display EMF model content.
ModelNavigator project
The first step to create our ModelNavigator is to create a plug-in project. To do
this, we use the new project wizard: File > New > Project, select
Plug-in Project, then click Next.
We will name our plug-in project ModelNavigator, set the
plug-in ID to com.ibm.navigator.example.modelnavigator, the
activator to com.ibm.navigator.example.modelnavigator.ModelNavigatorPlugin, and
click Finish.
Figure 3. Creating the plug-in project
Creating the view
We are ready to start developing our plug-in. The first step is creating the view that
will house our navigator. To do this, we make the necessary extensions in our plug-in to
create the view part and the category under which the view will appear. In the plug-in
xml file, we add a view extension.
From the Extensions tab:
- Click Add
- Under the Extension points tab, select org.eclipse.ui.views
- Create the category:
- Right-click on the org.eclipse.ui.views extension
- Select New > Category
- Set the name to
com.ibm.navigator.example.modelnavigator.mncategory
- Set the ID to
Model Navigator
- Create the view part:
- Right-click on the org.eclipse.ui.views extension
- Select New > View
- Set the ID to
com.ibm.navigator.example.modelnavigator.mnview
- Set the name to
Model Navigator View
- Set the class to
org.eclipse.ui.navigator.CommonNavigator
- Set the category to
com.ibm.navigator.example.modelnavigator.mncategory
- Save the modification to the project
As mentioned, we are shifting some of the implementation burden to the CNF. An
important thing to note about the way we have set up the view is that
instead of creating our own class that will extend the ViewPart for our view, we made
it so the view uses the common navigator class. This also means that the common
navigator class we point to in the class field needs to be added to the class path of
our plug-in. So go ahead and add org.eclipse.ui.navigator to
the required plug-ins on the Dependencies tab.
Setting the default behavior and incorporating to CNF
The next step is to configure the CNF attributes for our
plug-in, which will dictate the default behavior of our navigator.
First, we associate our view to a common navigator viewer. From the Extensions tab:
- Click Add
- Under the Extension points tab, select
org.eclipse.ui.navigator.viewer and click Finish
- Create the viewer:
- Right-click on the org.eclipse.ui.navigator.viewer extension
- Select New > viewer
- Set the viewerid to the ID of the view we defined above
(
com.ibm.navigator.example.modelnavigator.mnview)
The behavior of our navigator plug-in will be governed by the content we bind to it,
the actions we bind to it, and the other options we set in our plug-in when using CNF
(filters, sorters, etc.). In the plug-in, include elements select which
extensions are visible to the viewer. The content extensions tell the framework how to
display content in the view, and the action extensions tell the framework what options
are available to the view (context menus, etc.). To get this bare-bones
version of the navigator up and running, we will add the content and action bindings
from the IResource model, giving the plug-in the familiar
feel of the Package Explorer. To do this, we create a viewerContentBinding for our navigator to add the resource content
extension and create a viewerActionBinding to add the
resource action extensions.
To add the IResource content extension, from the Extensions
tab:
- Right-click on the org.eclipse.ui.navigator.viewer extension
- Select New > viewerContentBinding
- Set the viewerid to the ID of the viewpart of our plug-in
(
com.ibm.navigator.example.modelnavigator.mnview)
- Add the content binding:
- Right-click the viewerContentBinding we just created
- Select New > includes
- Right-click the includes element we just created
- Select New > contentExtension
- Set the pattern to
org.eclipse.ui.navigator.resourceContent
To bind the IResource action extensions, from the Extensions
tab:
- Right-click on the org.eclipse.ui.navigator.viewer extension
- Select New > viewerActionBinding
- Set the viewerid to the ID of the viewpart of our plug-in (
com.ibm.navigator.example.modelnavigator.mnview)
- Add the action binding:
- Right-click the viewerContentBinding we just created
- Select New > includes
- Right-click the includes element we just created
- Select New > actionExtension
- Set the pattern to
org.eclipse.ui.navigator.resources.*
At this point, we have the structure of our navigator set up. We saw how to tell the
navigator framework the type of content we want to display and how we want the navigator
to act. Although we did not necessarily need to add these extensions, by adding the
IResource model content and actions, we have a somewhat more
useful view. We now also know how to bind content to the viewer and could even expand
this to add custom or predefined filters. See Resources for
more information about these capabilities. This navigator is still not what we want, so
we need to add the ability to display an EMF model in the viewer.
Adding EMF domain content
To make the EMF domain model content display in our navigator, we need to inform the
framework of what model is of interest, how information from this model can be
obtained, and how/when to display it. This involves creating a content extension that
can be used by the navigator content service to display the EMF domain model. This work
is accomplished by creating an extension to the org.eclipse.ui.navigator.navigatorContent plug-in.
The navigator
content extension defines a content provider and label provider that can be used to
provide children and parent objects for element of an EMF model. It also defines when
this extension can be invoked to provide children, known as triggerPoints, or parent
objects, known as possibleChildren. There are also many other attributes of the
navigator content we can modify to change the behavior of our plug-in, such as the
action providers, common wizards, filters, etc. However, these are extra features that
are not necessary for us to create our ModelNavigator plug-in.
First, we need to create a new content extension where we can specify the content and
label providers to be used by the common navigator, later we will implement these classes.
To add the navigatorContent extensions, from the Extensions
tab:
- Click Add
- Under the Extension points tab, select
org.eclipse.ui.navigator.navigatorContent and click Finish
- Create the Navigator Content:
- Right-click on the org.eclipse.ui.navigator.navigatorContent extension
- Select New > navigatorContent
- Set the ID to
com.ibm.navigator.example.modelnavigator.emfModelContent
- Set the name to
EMF Model Content
- Set the Content provider to
com.ibm.navigator.example.modelnavigator.MNViewContentProvider
- Set the Label provider to
com.ibm.navigator.example.modelnavigator.MNViewLabelProvider
- Set the Priority to
normal
- Set the activeByDefault to
true
We implement the classes that will act as the content and label providers for this navigator content next.
The composed adapter factory
We will use the EMF.Edit framework to perform the actual work of the content and
label providers. Therefore, we need to create our content and label-provider classes as
subclasses of the adapter factories from the EMF edit framework. Before we create the
content and label-provider classes, which delegate to the AdapterFactoryContentProvider and AdapterFactoryLabelProvider respectively, we should remember that
these adapter factories are instantiated with a list of item providers for the
different EMF models. This means we need to create this list of providers first, as a
composed adapter factory. Create a new class (File > New > Class) named
MNComposedAdapterFactory.
Figure 4. Creating the implementation classes
We also need to add org.eclipse.emf.codegen.ecore.ui to the
required plug-ins on the Dependencies tab. This will make the ComposedAdapterFactory
item providers for the different EMF model types and other EMF.Edit convenience classes
available to the plug-in. Then the implementation of the MNComposedAdapterFactory class would be like Listing 1.
Listing 1. Our ComposedAdapterFactory class
...
public class MNComposedAdapterFactory
{
private static ComposedAdapterFactory mnCompAdapterFactory;
public final static ComposedAdapterFactory getAdapterFactory()
{
if (mnCompAdapterFactory == null)
mnCompAdapterFactory = new ComposedAdapterFactory(createFactoryList());
return mnCompAdapterFactory;
}
public final static ArrayList<AdapterFactory> createFactoryList()
{
ArrayList<AdapterFactory> factories = new ArrayList<AdapterFactory>();
factories.add(new ResourceItemProviderAdapterFactory());
factories.add(new EcoreItemProviderAdapterFactory());
factories.add(new ReflectiveItemProviderAdapterFactory());
return factories;
}
}
|
The important part to note is that we are creating a static method to create a list of
item providers. Of these item providers, the EcoreItemProviderAdapterFactory will be what we want the adapter
factory to delegate to in order to provide the content and labels for and Ecore model.
The content and label providers
In a similar manner, create the content and label-provider classes we specified in the
navigatorContent extension details.
Starting with the content provider (MNViewContentProvider),
create the class by clicking the link next to the provider name in the extension
details panel, or going through the File > New > Class dialogs. Instead of
implementing the ITreeContentProvider interface for the
content provider, we use the EMF.Edit classes. To do this, change the MNViewContentProvider class to extend the AdapterFactoryContentProvider class. The AdapterFactoryContentProvider class already knows how to handle the
implementation of ITreeContentProvider interface, which it
actually does by delegating to an appropriate item provider, that provides content to the viewer.
The AdapterFactoryContentProvider class expects an adapter
factory in its constructor. So we cannot use the implicit constructor for our content
provider. We must explicitly declare our content provider constructor and call the
super-class constructor with the expected parameters. Once we declare the constructor,
add super(MNComposedAdapterFactory.getAdapterFactory()); to
it. The other methods we will focus on in this class are the getChildren, getParent, hasChildren, and getElements.
The getChildren method is called when the viewer needs to
display the child elements of a domain object. It returns an array of domain objects
that are children of the parameter element. Similarly, the getElements method is called to obtain the domain objects of the
parameter element. These two operate in a similar function; they are just called at
different times. To implement the getChildren method, we
simply ask the AdapterFactoryContentProvider to return the
children of the given parent's URI. The getChildren method
is shown in Listing 2. For the getElements method, we simply
return the call to this getChildren method.
Listing 2. getChildren implementation
...
public Object[] getChildren(Object parentElement)
{
if (parentElement instanceof IFile)
{
String path = ((IFile)parentElement).getFullPath().toString();
URI uri = URI.createPlatformResourceURI(path, true);
parentElement = resourceSet.getResource(uri, true);
}
return super.getChildren(parentElement);
}
...
|
The next two important steps to display content in a tree view are to be able to
determine when an object in the view has children that need to be displayed and to be
able to associate a set of children to a parent object. This is what allows the viewer
to control the state of the domain objects, whether they are expanded or collapsed. In
our example, this can translate to an Ecore model that has a set of children packages.
Within those packages are class objects that are associated to the same parent package.
We implement this in Listing 3.
Listing 3. getParent implementation
...
public Object getParent(Object element)
{
if (element instanceof IFile)
return ((IResource)element).getParent();
return super.getParent(element);
}
public boolean hasChildren(Object element)
{
if (element instanceof IFile)
return true;
return super.hasChildren(element);
}
...
|
We might see some errors here about not being able to resolve the resources
we are using. To resolve this, add org.eclipse.core.resources
to the required plug-ins on the Dependencies tab. Also, to allow the content provider
to get the URI of the file resources in the view, we need to use the resource set from
the platform. We create a single static resource set implementation that can be used to
get these resources by adding private static ResourceSetImpl
resourceSet = new ResourceSetImpl(); to the MNViewContentProvider class.
The label provider follows the same format as the content provider in that we will
simply delegate the work to the AdapterFactoryLabelProvider
class from the EMF.Edit framework. As with the content provider, the label provider
accepts domain objects as its arguments, but it returns the Image or String that should
be associated with this object in the viewer. To make our viewer a bit more
customized, we can programmatically control when we want to delegate the task of
getting the names and icons and when we want to provide our own icons for an object.
For our purpose, we opt not to go for any customization. We just want the images and
text that the EMF model provides. To implement the label provider, we call the super
class with the same item provider list we had for the content provider, then delegate
any calls for images or descriptions of the objects to the AdapterFactoryLabelProvider super class.
Listing 4. The label provider
...
public MNViewLabelProvider()
{
super(MNComposedAdapterFactory.getAdapterFactory());
}
public Image getImage(Object element)
{
return super.getImage(element);
}
public String getText(Object element)
{
return super.getText(element);
}
...
|
Tying it all together
At this point, we've completed the work of implementing the content extension in our
plug-in. To allow our view to make use of this content extension is another two-step
process. First, we must define events that will signal the use of this particular
content extension. Second, we must bind the navigator content to the view.
We signal the CNF when we will be able to display the domain model we described in our
classes by adding <possibleChildren /> and <triggerPoints /> elements to the navigator content extension.
These two elements are easy to define as Eclipse core expressions in the plug-in xml
file. In our case, our navigator content will be invoked when the viewer contains an
object that is an instance of an EMF model. Since we currently only want to navigate an
Ecore model, we can make this a simple expression that will check the extension of the
resource to be Ecore. The possible children element dictates when our extension can
provide parents for objects in the viewer, in our case these are objects that are
instances of EMF model objects or resources.
Listing 5. Trigger points and possible children elements
<triggerPoints>
<or>
<and>
<instanceof value="org.eclipse.core.resources.IResource"/>
<test
forcePluginActivation="true"
property="org.eclipse.core.resources.extension"
value="ecore"/>
</and>
</or>
</triggerPoints>
<possibleChildren>
<or>
<instanceof value="org.eclipse.emf.ecore.resource.Resource"/>
<instanceof value="org.eclipse.emf.ecore.EObject"/>
</or>
</possibleChildren>
|
Finally, to bind the navigator content we have created to our view, we will use the
same method we did earlier to include the IResource model
content extension to the viewer content binding.
To bind the navigator content com.ibm.navigator.example.modelnavigator.emfModelContent to the
actual view, from the Extensions tab:
- Expand the org.eclipse.ui.navigator.viewer element
- Expand the viewerContentBinding element
- Create a new content extension:
- Right-click on the includes element
- Select New > contentExtension
- Set the pattern to the
navigatorContent we defined
(com.ibm.navigator.example.modelnavigator.emfModelContent)
- Click Save
That pretty much completes the steps needed to add EMF model content to a common
navigator. We should have a ModelNavigator plug-in that can display objects from the
IResource model and from the EMF Ecore model.
Testing the navigator
 |
Testing on an EMF project
To run this test, you can choose to import an existing EMF project to your runtime Eclipse
workspace or create a new project. The EMF Developers Guide tutorial shows you how to
create a new project that imports a UML model, which you can choose to download and setup. |
|
We need to run the project and display an Ecore model in our new view to make sure our
ModelNavigator is working. For this test, we need to create an EMF project that will
be displayed in the Model navigator. We will use the example based on the SchoolLibrary UML file (see Resources).
Run the ModelNavigator project as an Eclipse application, then:
- In the new workbench, display the ModelNavigator view by clicking Window > Show View > Other
- Find the Model Navigator category and click the Model Navigator View
- Click OK
To create the EMF project in your runtime workspace:
- Create a new project by clicking File > New > Project
- Expand the Eclipse Modeling Framework element
- Click EMF project and select Next
- Name the project
SchoolLibrary and select Next
- Select Rose class model as the model importer and select Next
- For the model URI, browse to the location where you downloaded the schoollibrary.mdl file
- Click Next
- Select the library and SchoolLibrary packages, as shown in Figure 5
- Click Finish
Figure 5. Creating the EMF test project
If everything went according to plan, we should see the new SchoolLibrary project in our Model Navigator view. More importantly,
if our navigator content is functioning as expected, we should be able to expand the
models directory of the project and be able to navigate through the content of the
library and SchoolLibrary Ecore files within our navigator
view. The navigator should be similar to that in Figure 6.
Figure 6. Testing the ModelNavigator
Update synchronization
We have accomplished what we set out to do: to make EMF model content display in a
viewer. What happens when we actually open the Ecore file in the editor and start
making changes? As it is now, nothing happens. Our ModelNavigator is oblivious to
changes being made to the models it is displaying and will not refresh them. It will
not refresh them unless we make the viewer aware of changes made in the editor and
force it to refresh itself. One way to create this synchronization is to add a resource
change listener to our content provider. The following sections outline the steps required.
Resource-change listener
We make our content provider react to changes in the model by allowing it to listen for
changes in the model file resource (the Ecore file in our case). To do this, we need to
implement the IResourceChangeListener and the IResourceDeltaVisitor interfaces in our MNViewContentProvider class.
The resourceChanged(IResourceChangeEvent event) method is
called when a resource changes and passes the set of events that describe the changes
to the resources. This set of changes supplies us with differences between the resource
tree as a delta in time. We can use this to walk through the changes in the resource
tree and determine what actions need to be taken based on the type of resource that has
changed. We implement the resourceChanged(IResourceChangeEvent
event) method, as shown in Listing 6, which gives us the resource set that has
changed and allows us to visit the resource delta.
Listing 6. Resource-changed method
...
try
{
IResourceDelta delta = event.getDelta();
delta.accept(this);
}
catch (CoreException e)
{
...
|
The visit(IResourceDelta delta) method is invoked after the
delta accepts the visitor. For our plug-in, we only care when the changed resource is
an IResource file that has an Ecore extension. If it so happens the resource that was
changed was an Ecore model, the ModelNavigator needs to be refreshed to reflect these
changes. To do this, we take the changed file, obtain its resource, then reload the
model this resource represents.
Listing 7. The visit method
...
IResource changedResource = delta.getResource();
if (changedResource.getType() == IResource.FILE
&& changedResource.getFileExtension().equals("ecore"))
{
try
{
String path = ((IFile)changedResource).getFullPath().toString();
URI uri = URI.createPlatformResourceURI(path, true);
Resource res = resourceSet.getResource(uri, true);
res.unload();
res.load(resourceSet.getLoadOptions());
}
catch(IOException ie)
{
System.out.println("Error reloading resource - " + ie.toString());
}
return false;
}
return true;
...
|
To make use of this resource-change listener, we need to add it to the content provider
and remove it when appropriate. In the MNContentProvider
class, add the listener by inserting
ResourcesPlugin.getWorkspace().addResourceChangeListener(this,
IResourceChangeEvent.POST_CHANGE); in the constructor. Also, insert
ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); in
the dispose method of the class. Although that should take care of the updates to
resource changes, keep in mind that this is a simplistic way to handle changes. By
simply updating the affected model in our content provider, we are not going through the
dependencies of this model to update those elements. This is a basic way to keep
the navigator updated.
Testing for model updates
To test that changes in the Ecore model are being reflected in the viewer, we will
simply rerun our application and start making some changes.
Run the ModelNavigator project as an Eclipse application, then:
- Navigate to the schoollibrary.ecore under the model directory
- Open the schoollibrary.ecore file in its editor
- Expand the schoollibrary.ecore node
- Right-click the SchoolLibrary package node
- Select New Child > EClass
- On the Properties tab, give this new class a name (
Test)
- Save the file
This change should have triggered the resource-change listener code to execute and
force our ModelNavigator to update the model. We should see the ModelNavigator view
reload itself. If we expand the tree and navigate into the schoollibrary.ecore file, we
should see the changes that were made, as shown in Figure 7.
Figure 7. ModelNavigator with resource updates
Further steps
One final — and rather easy — extension we can make to our
ModelNavigator is to make use of the Composed Adapter Factories. The navigator we have
created will display Ecore models, but what about other types of EMF models? This
actually turns out to be a rather simple task, thanks to the way the EMF.Edit framework
is implemented. We can add support for more domain models with minimal changes by
adding the appropriate adapter factories to our ComposedAdapterFactory and setting the triggers for these new models.
Extending the composed adapter factory
For example, to add the genmodel objects to our navigator,
we just add the generator model item provider to the adapter factory list our content
and label providers use. In the MNComposedAdapterFactory
class, add factories.add(new
GenModelItemProviderAdapterFactory()); to the createFactoryList() method. The only other part of the model
navigator that needs to be changed is to tell the navigator content when this content
provider can be triggered. We use the same strategy of checking the resource extension
as a trigger point, as shown below.
Listing 8. Trigger points for genmodel
<and>
<instanceof value="org.eclipse.core.resources.IResource"/>
<test
forcePluginActivation="true"
property="org.eclipse.core.resources.extension"
value="genmodel"/>
</and>
|
By adding this new trigger expression right under our current trigger, we are making
the navigator content relevant in the case when the object is an instance of IResource and has an extension of Ecore or it is of instance IResource and extension genmodel. If we
run this project again as outlined above, we will see that we can now navigate through
Ecore and Generator EMF models (see Figure 8). However, this is not something we
planned for in our simplistic resource update scheme, so updates will not be
synchronized across the different models from the ModelNavigator view.
Figure 8. ModelNavigator with multiple models
Conclusion
We have completed our task of creating a plug-in that will display EMF model content in
a viewer. We demonstrated how to simplify this process by using the frameworks provided
by Eclipse and even went a little further in adding some simple features to the
plug-in. We have only explored a few of the capabilities exposed by these
frameworks, and I highly encourage everyone to take a deeper look into these Eclipse components.
Download | Description | Name | Size | Download method |
|---|
| Code | os-eclipse-emf.ModelNavigator.zip | 9.5KB | HTTP |
|---|
Resources Learn
-
Learn more about the Eclipse Modeling
Framework Project.
-
Check out Michael Elder's blog for more articles on the Common Navigator Framework.
-
Access model content through the
EMF.Edit
Framework in the Eclipse documentation.
-
Check out Generating
an Extended EMF Model in the Eclipse documentation.
-
Visit Eclipse.org to learn the details of the
Common
Viewer Configuration, the navigatorContent, and How to use the JFace Tree Viewer.
-
Check out the Common Navigator Tutorial 1: Hello World.
-
Don't miss the EclipseCon presentation on the Common Navigator Framework for Platform/UI in 3.2.
-
Learn how to use the resource-change
listener.
-
Visit the EclipseZone community for one more way to access EMF model content: Bridging EMF to the common navigator."
-
Check out the "Recommended Eclipse reading list."
-
Browse all the Eclipse content on developerWorks.
-
New to Eclipse? Read the developerWorks article "Get started with Eclipse Platform" to learn its origin and architecture, and how to extend Eclipse with plug-ins.
-
Expand your Eclipse skills by checking out IBM developerWorks' Eclipse project resources.
-
To listen to interesting interviews and discussions for software developers, check out developerWorks podcasts.
-
For an introduction to the Eclipse platform, see "Getting started with the Eclipse Platform."
-
Stay current with developerWorks' Technical events and webcasts.
-
Watch and learn about IBM and open source technologies and product functions with the no-cost developerWorks On demand demos.
-
Check out upcoming conferences, trade shows, webcasts, and other Events around the world that are of interest to IBM open source developers.
-
Visit the developerWorks Open source zone for extensive how-to information, tools, and project updates to help you develop with open source technologies and use them with IBM's products.
Get products and technologies
Discuss
-
The Eclipse Platform newsgroups should be your first stop to discuss questions regarding Eclipse. (Selecting this will launch your default Usenet news reader application and open eclipse.platform.)
-
The Eclipse newsgroups has many resources for people interested in using and extending Eclipse.
-
Participate in developerWorks blogs and get involved in the developerWorks community.
About the author  | |  | Javier Torres is a software engineer working in the emerging standards
organization of IBM Software Group. He was hired at IBM in 2007, and his current role
focuses on standards-based solution development for the energy and utilities industry.
He holds a master's degree in computer science and a bachelor's degree in computer
engineering, both from Florida International University. |
Rate this page
|