Jonas Helming, Maximilian Koegel and Philip Langer co-lead EclipseSource. They work as consultants and software engineers for building web-based and desktop-based tools. …
EMF Forms 1.8.0 Feature: Factories for TreeViewer and TableViewer
March 9, 2016 | 4 min ReadWith Mars.2, we released EMF Forms 1.8.0. EMF Forms makes it really simple to create forms which edit your data based on an EMF model. To get started with EMF Forms please refer to our tutorial. In this post, we wish to outline one of the new features of release 1.8.0: A factory API to efficiently create tables and TreeViewers based on a given EMF model.
Short Story
Using the API of EMF Forms 1.8.0, you can create a TreeViewer for showing EMF model instances with drag and drop support and right click actions just like that:
TreeViewerSWTFactory.createTreeViewer(parent, rootEObject)
The same is true for tables and tree master detail views. The API can be used independent of any view model or the EMF Forms rendering framework or within renderer implementations.
Longer Story
Using EMF as a data model for entity classes makes it very efficient to build UIs based on this model. As an example, if you want to display entities with trees or tables in JFace/SWT, then EMF generates the required ContentProvider and LabelProvider for you. Even more, EMF provides out-of-the-box support for related features such as drag and drop or “child creation” actions in context menus. This saves a lot of effort compared to implementing such features manually. Even more, all of this support is either generated along with the model or generic. That means, if you change your model, through the EMF UI support your UI will automatically be adapted. As an example, a tree will be able to show and create new elements added to the data model.
However, creating trees and tables is still quite some configuration overhead. That basically means, you have to wire all existing pieces together.
For example, the following completely generic lines of code create a TreeViewer for any EMF model instances including updates on changes:
TreeViewer viewer = new TreeViewer(parent, SWT.NONE);
composedAdapterFactory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
viewer.setContentProvider(new AdapterFactoryContentProvider(composedAdapterFactory));
viewer.setLabelProvider(new AdapterFactoryLabelProvider(composedAdapterFactory));
viewer.setInput(myRootEObject);
Some more lines of code would enable drag and drop and right click menus on the tree.
EMF Forms makes it even simpler to create elements such as TreeViewer or Tables, as you only need to specify what is being derived from the standard. As an example, if you want to specify a standard TreeMasterDetail view, showing a hierarchy of the model instance in a tree to the left and the details of the selected element to the right, the view model would simply look like this:
And you would get this in the running application:
The idea is almost the same for tables. However, there is occasionally the need for extensive customization. As an example, you might want to influence the drag and drop behavior, add filters to a tree, or react to the selection of a tree viewer. EMF Forms explicitly supports these kinds of customization by adapting or replacing the existing renderer, which is responsible for creation elements such as trees or tables.
To make the implementation of custom renderers as simple as possible, EMF Forms now provides factories for the creation of trees, tables and tree master detail views. However, these factories can also be used outside of a renderer and without a view model. So you can basically integrate this anywhere in your application in order to create trees and tables programmatically.
The factories implement a builder pattern. The goal is to only require specifications for things which derive from the default.
As seen before, the following lines of code would create a default tree viewer:
TreeViewerSWTFactory.createTreeViewer(parent, rootEObject)
Now, if you want to have a default tree viewer, but add some custom viewer filters to it, the code would look like this:
TreeViewerSWTFactory.fillDefaults(parent, rootEObject).customizeViewerFilters(yourViewerFilters).create();
Using this method you can adapt a lot of things, such as right click menus, content provider, drag and drop, etc.
EMF Forms currently provides three factories to be used:
- TreeViewerSWTFactory (bundle: org.eclipse.emfforms.swt.treemasterdetail)
- TreeMasterDetailSWTFactory (bundle: org.eclipse.emfforms.swt.treemasterdetail)
- TableViewerFactory (bundle: org.eclipse.emfforms.swt.table)
Obviously, tables need a little bit more set-up, as you need to specify the columns. However, the factory makes this pretty easy, you only need to specify a name, a tooltip and a CellLableProvider for every column. The following example code creates a table for “Tasks” with one column showing the name:
final IObservableList inputList = EMFProperties.list(TaskPackage.eINSTANCE.getTask_SubTasks()).observe(task);
CellLabelProvider cellLabelProvider = CellLabelProviderUtil.createCellLabelProvider(task, TaskPackage.eINSTANCE.getTask_Name())
TableViewerFactory.fillDefaults(content, SWT.NONE, inputList).addColumn("Task", "The name of the task", cellLabelProvider)
All factories are part of the EMF Forms SDK starting from release 1.8.0 and are part of Mars.2. You can also download and install it from our update site (1.8.0 or higher). The factories are currently under active development, if you miss any feature or ways to adapt it, please provide feedback by submitting bugs or feature requests or contact us if you are interested in enhancements or support.