How to build a tree editor in Eclipse Theia

How to build a tree editor in Eclipse Theia

Are you interested in creating an editor displaying data as a tree structure with a detail form in Eclipse Theia, such as the screenshot shown below? In this article we introduce the tree editor framework for Eclipse Theia, which supports exactly that. The framework provided by the EMF.cloud project provides all the basic requirements out-of-the-box so you only need to implement the domain-specific part, e.g. what icons to use, how the hierarchy of the tree is derived from the data or how the detail form is layouted.

For the curious or impatient, you can directly see an online editor of a tree editor in eclipse Theia in the coffee editor online demo. Open the demo and click on “Form/Editor” in the overview to the right. More details about the coffee editor demo can be found in this article.

The Use Case: Tree Master Detail Editor

Many tools require the modification and creation of structured data. Possibly the specification of some software components, the configuration of hardware devices, or any other structured domain-specific data. A very common way to make this data accessible is a “tree master detail” editor as shown above. It displays the structure of the underlying data in a tree. The tree allows the creation of new elements (children of a node). On selection of an element in the tree, the detailed properties of this element are displayed in a detail view allowing for modification. If such an editor is part of a tool chain, it often makes sense to embed it as an editor into a tool frame, e.g. into the Eclipse platform (desktop version) or, in case of a web-based tool into Eclipse Theia

For the desktop use case, there is great framework support in the EMF ecosystem, e.g. the editor framework provided by EMF Forms. Using such a framework significantly reduces the implementation effort and therefore, the EMF.cloud project now provides a similar component for Eclipse Theia, the EMF.cloud tree editor framework.

The basic idea remains the same: Instead of manually coding the full UI, you basically use an API to specify only the domain-specific details. This is essentially the data model that the editor operates on and some details on how it should be displayed in the editor. In particular, you need to specify:

  • Which entities exists (defined by a data schema)
  • How their hierarchy works (in the tree)
  • Which elements can be created
  • What labels and icons to use
  • Which properties of elements are rendered in the detail form and what the layout looks like (again defined by schemata)

Based on that, the framework provides you with a fully functional editor without any manual coding. This includes rendering the tree, populating menus for element creation, default serialization, inline validation of properties and specific input fields based on property types (e.g. a drop down for enum values). Before we dive into the details of how that works, you might want to see the approach in action.

Online Demonstration

As all that above might sound pretty abstract, you may want to see an example of a tree master detail editor in action. As mentioned above, there is an online demo available embedded in the coffee editor. The coffee editor serves as an example of a web-based modeling tool built on Eclipse Theia. It combines a variety of features including a graphical diagram editor, a textual DSL and the tree master detail editor discussed in the article. To try it online, follow this link and see the available features listed to the right. This includes the tree master detail editor (Tree/Form editor). If you are interested in more details about the example and other features, please head over to our article about web-based modeling tools in Eclipse Theia.

Build your own Tree Editor in Theia

Probably the simplest way to get started with building your own editor is to look at an example. From there you can actually adapt the existing data model and learn how to customize the framework based on your specific requirements.

To get started, we provide a Yeoman generator that will create your own template project with a working example. The template is integrated into the Theia extension generator.

To create the editor template project, install the extension generator and launch it like this:

npm install -g yo generator-theia-extension
mkdir my-extension && cd my-extension
yo theia-extension

For the extensions type, select “TreeEditor”

The template generator creates a tree editor based on an example data model. It also creates a Theia product that embeds the editor, so you can directly try it out with the following commands:

cd browser-app
yarn start

Check the running application with your browser at localhost:3000. In the running application, open the menu “Tree Editor”=>”New Example File”. The created file .tree will automatically be opened with the example tree editor. The left side of the editor shows the hierarchy of the JSON data allowing you to create new children and delete nodes. The right site shows the properties of a selected node and allows the modification of the same including validation.

Adapt the tree editor

The generated example tree editor is a good way to learn about how the underlying framework works. An obvious adaptation use case would be to adapt/replace the example data model with your own data definition to use the tree editor for your own custom data. So let’s add a new element type to the example to demonstrate all relevant parts necessary for this.

The tree editor framework itself is implemented in a generic way, which makes it reusable for any data model. The data specific part is fully encapsulated in schemata and services. The first element you need for a new element type is the actual data definition. This is by default done using JSON schema and can be found in the file tree-schema.ts. The JSON object “coffeeSchema” defines all existing elements of the example, let us add a new element type called “MyComponent”, e.g. like this:

'myComponent': {
    'title': 'MyComponent',
    'properties': {
      'typeId': {
        'const': 'MyComponent'
      },
      'name': {
        'type': 'string',
        'minLength': 3,
        'maxLength': 20
      },
      'active': {
        'type': 'string',
        'enum': [
          'yes',
          'no'
        ]
      }
    },
    'required': [ 'name' ],
    'additionalProperties': false
  }

As you can see, we defined two properties for our element type, a name and an active state. The name property is mandatory and has a min and max length, so we can test the validation in the UI.

Second, we define how our new component can be created within the existing hierarchy of the example model. This is specified in the file tree-model.ts. In the example model, there are two elements, “Machine” and “MultiComponent” which can contain “Components”. So a simple way to integrate our new type is making it a component, so it can be contained in the tree. Therefore, let us add our new type to the list of components:

const components = [
       Type.MultiComponent,
       Type.BrewingUnit,
       Type.ControlUnit,
       Type.DripTray,
       Type.WaterTank,
       Type.MyComponent
   ];

With these two definitions, the tree editor is already able to pick up the new element type. As you can see in the screen capture below, you can create the new type and show its properties. The tree view uses a default icon and assumes the “name” attribute to be the label (both can of course be customized). The details view allows you to modify the element, the UI automatically picks up the data definition, validates the constraints and uses a drop down for the enumeration type. 

The properties view is just the default you get without any further UI specification. Furthermore, it is based on JSON Forms, so the properties view is easily customizable. This includes the layout as well as the controls that are used. As an example, you could add radio button control for the “yes/no” property. As another example, you can easily rearrange the view by adding a so called UI schema. By adding the following declaration to tree-schema.js, we will change the layout and adapt the label of the “active” attribute:

{
 'type': 'HorizontalLayout',
 'elements': [
   {
     'type': 'Control',
     'label': 'Name',
     'scope': '#/properties/name'
   },
   {
     'type': 'Control',
     'label': 'Is the component active?',
     'scope': '#/properties/active'
   }
 ]
}

The details view will then render, as shown, in the following screenshot:

This is only the tip of the iceberg in terms of customization capabilities for the details view. Please take a look at the underlying technology JSON Forms if you want to learn more about that.

Finally, let’s get rid of the default icon and specify a custom icon for our new element type. This is done in the label provider (tree-label-provider.js):

const ICON_CLASSES: Map<string, string> = new Map([
   [CoffeeModel.Type.MyComponent, 'fa-exclamation-circle ' + DEFAULT_COLOR],
]);

With that, the tree will look as follows, showing the specified icon for your node type:

More customization capabilities of the EMF.cloud tree editor for Eclipse Theia can be found on the EMF.cloud website.

Conclusion

The EMF.cloud tree editor for Theia provides a powerful frame for building data-centric editors. These editors are often required to manage domain specific data in tools. The editor is implemented in a generic way so that it can be used for any data model. Domain-specific information, such as the data model and how to display elements can be provided in a mostly declarative way. This drastically accelerates the implementation of such editors, but also reduces the maintenance costs, since changes on the data model like new element types can very easily be applied.

The EMF.cloud tree editor provides good defaults and works out-of-the-box. Furthermore, it is also highly customizable to domain-specific requirements. As an example, the details view can be fully customized (using JSON Forms) or be even replaced with a custom implementation. As another example, the tree editor framework provides a default serialization to JSON, but it supports adding a custom serialization mechanism. See the EMF.cloud website for more documentation on the tree editor.

Data-centric editors such as the one described in this article are often embedded into a toolchain that also uses other representations for the underlying domain data, such as graphical diagram editors or text. Please note that the EMF.cloud tree editor combines well with technologies such as the Eclipse Graphical Language Server Platform (GLSP) or Xtext. In this article, we describe an example tool combining typical features of a modeling tool based on Eclipse Theia, including a live online demonstration.

Finally, if you´re planning the development of a web-based data-centric editor, or if you want an evaluation of a web-based version of your existing tools or you want to make your current tools ready for the upcoming challenges and opportunities, please do not hesitate to contact us. EclipseSource provides you with expertise and experience that can support your tool projects technically and conceptually. With our focus on creating tools, we combine experts for web- and cloud-based tools with Eclipse, DSL, IDE and modeling expertise. Please have a look at our consulting offering for building tools based on Eclipse Theia, support for web-based tools, consulting for building modeling tools or tools in general. If you have any questions or want to learn more about how we can support you, just contact us. It would be nice to hear from you!