Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Eclipse4/RCP/Modeled UI/Contributing to the Model"

< Eclipse4‎ | RCP‎ | Modeled UI
(Creating Model Elements at Runtime)
 
(Fleshed out the model fragments and processor sections)
Line 18: Line 18:
 
</source>
 
</source>
  
Finally, the fragment is then made available through the <tt>org.eclipse.e4.workbench.model</tt> extension point.
+
Finally, the fragment is made available through the <tt>org.eclipse.e4.workbench.model</tt> extension point.
 
+
<source lang="xml">
== Manipulating the Model With Processors ==
+
<extension
 +
        point="org.eclipse.e4.workbench.model">
 +
      <fragment
 +
            uri="fragment.e4xmi">
 +
      </fragment>
 +
</extension>
 +
</source>
  
  
Line 44: Line 50:
 
container.setSelectedElement(part);  // raise to top
 
container.setSelectedElement(part);  // raise to top
 
</source>
 
</source>
 +
 +
 +
== Manipulating the Model With Processors ==
 +
 +
Model processors are objects that provided the opportunity to modify and add to the model before its rendered.  For example, we sketch here a model processor to ensure that a specific <em>AddOn</em> is configured for the application.
 +
 +
A model processor is configured through an extension to the <tt>org.eclipse.e4.workbench.model</tt> extension point.
 +
 +
<source lang="xml">
 +
<extension
 +
        point="org.eclipse.e4.workbench.model">
 +
      <!-- if beforefragment="true", then the processor is run before any fragments are stitched in -->
 +
      <processor
 +
            beforefragment="false"
 +
            class="package.FooProcessor">
 +
      </processor>
 +
</extension>
 +
</source>
 +
 +
A model processor is a normal injectable POJO class whose processing is triggered by ab <tt>@Execute</tt>-annotated method.  For example, the basic template for a processor that acts to ensure that a particular addon is configured would look something like the following:
 +
<source lang="java">
 +
// ensure the FooAddOn is defined for this application
 +
class FooProcessor {
 +
@Inject
 +
protected MApplication app;
 +
 +
@Execute
 +
public void execute() {
 +
String addonId = FooAddOn.class.getName();
 +
for (MAddon addon : app.getAddons()) {
 +
if (addonId.equals(addon.getElementId())) {
 +
// our addon was found
 +
return;
 +
}
 +
}
 +
 +
MAddon addon = MApplicationFactory.INSTANCE.createAddon();
 +
addon.setContributionURI("platform:/plugin/bundle/package.FooAddOn");
 +
addon.setElementId(addonId);
 +
app.getAddons().add(addon);
 +
}
 +
}
 +
</source>
 +
 +
Model processors differ from fragments in two key ways.  First, a processor can perform more sophisticated manipulations of the model, such as deleting elements or moving elements within the model, as well as creating new elements.  Second, model processors are not specific to a particular application instance.  Although our <tt>FooAddOn</tt> could have been installed through a model fragment, the fragment would have had to explicitly specify the application's <tt>elementId</tt> to be extended, and thus been locked-in.  Model processors are particularly useful for installing services that are application-independent.  This pattern is used in the E4AP itself, such as to configure the MacOS X Cocoa enhancement (found in <tt>org.eclipse.e4.ui.workbench.renderers.swt.cocoa</tt>).

Revision as of 20:00, 23 November 2011

Model Fragments

Your application model can be spread out across several e4xmi files, to be stiched together at startup. This mechanism allows adding new mode elements or referencing existing model elements to collections defined by other model elements. For example, you can use a fragment to define a new MWindow and add it to the MApplication's children (a set of windows). It is important that any model elements that you intend to reference have a unique elementId (e.g., the MApplication).

  1. Create a fragment file, typically called fragment.e4xmi
  2. Add the necessary imports to bring in model elements that will be referenced, as opposed to being extended
  3. Add StringModelFragments for each of the model elements to be extended. The parentElementId is the elementId of the element to be extended. featureame is the container feature name where new or existing elements will be added to.

For example, the following is a very simplified example of a fragment adding a command handler for the standard Exit/Quit command, where the command was defined elsewhere and thus imported:

<fragment:ModelFragments ...elided...>
  <imports xsi:type="commands:Command" xmi:id="XXXX" elementId="org.eclipse.ui.file.exit"/>
  <fragments xsi:type="fragment:StringModelFragment" xmi:id="..." featurename="handlers" parentElementId="my.e4.application">
    <elements xsi:type="commands:Handler" xmi:id="..." elementId="handler.exit"
       contributionURI="platform:/plugin/bundle/class.to.MyExitHandler" command="XXXX"/>
   </fragments>
</fragment:ModelFragments>

Finally, the fragment is made available through the org.eclipse.e4.workbench.model extension point.

<extension
         point="org.eclipse.e4.workbench.model">
      <fragment
            uri="fragment.e4xmi">
      </fragment>
</extension>


Creating Model Elements at Runtime

New elements are created and incorporated into the model using standard EMF patterns:

  1. Obtain the appropriate factory for the package.
  2. Create the desired object.
  3. Incorporate it into the model, typically by adding it to the appropriate container, to cause the element to be rendered.

For example, to create a new part:

// the container will hold the new element; maybe obtained using the EModelService
MPartStack container = ...; 
MPart part = MBasicFactory.INSTANCE.createPart();
part.setLabel("The Part Label");
part.setElementId("a-unique-identifier-for-this-part");
part.getPersistedState().put("input", "http://eclipse.org");
part.setContributionURI("platform:/plugin/bundle/classname");
 
container.getChildren().add(part);
container.setSelectedElement(part);  // raise to top


Manipulating the Model With Processors

Model processors are objects that provided the opportunity to modify and add to the model before its rendered. For example, we sketch here a model processor to ensure that a specific AddOn is configured for the application.

A model processor is configured through an extension to the org.eclipse.e4.workbench.model extension point.

<extension
         point="org.eclipse.e4.workbench.model">
      <!-- if beforefragment="true", then the processor is run before any fragments are stitched in -->
      <processor
            beforefragment="false"
            class="package.FooProcessor">
      </processor>
</extension>

A model processor is a normal injectable POJO class whose processing is triggered by ab @Execute-annotated method. For example, the basic template for a processor that acts to ensure that a particular addon is configured would look something like the following:

// ensure the FooAddOn is defined for this application
class FooProcessor {
	@Inject
	protected MApplication app;
 
	@Execute
	public void execute() {
		String addonId = FooAddOn.class.getName();
		for (MAddon addon : app.getAddons()) {
			if (addonId.equals(addon.getElementId())) {
				// our addon was found
				return;
			}
		}
 
		MAddon addon = MApplicationFactory.INSTANCE.createAddon();
		addon.setContributionURI("platform:/plugin/bundle/package.FooAddOn");
		addon.setElementId(addonId);
		app.getAddons().add(addon);
	}
}

Model processors differ from fragments in two key ways. First, a processor can perform more sophisticated manipulations of the model, such as deleting elements or moving elements within the model, as well as creating new elements. Second, model processors are not specific to a particular application instance. Although our FooAddOn could have been installed through a model fragment, the fragment would have had to explicitly specify the application's elementId to be extended, and thus been locked-in. Model processors are particularly useful for installing services that are application-independent. This pattern is used in the E4AP itself, such as to configure the MacOS X Cocoa enhancement (found in org.eclipse.e4.ui.workbench.renderers.swt.cocoa).

Back to the top