Virtual containers in tree viewers using EMF.Edit

Maybe you already stumbled upon the problem to display model instances with hundreds or even thousands of child elements in a tree based viewer. Displaying all that children as direct successors of their parent (shown in the figure on the left) is confusing and slows down the UI.

An alternative approach is to hook in virtual folders, that contain a subset of the parent’s child elements instead. This approach is shown in the figure on the right and might be familiar to you since it’s also used in the Eclipse ‘Variables’ view.

If you use EMF.Edit based item providers to display your domain objects read on!

The technique shown here is a slightly modified version of the technique explained in chapter 19.2.3 Adding Non-Model Intermediary View Objects of the standard Eclipse Modeling Framework book.

The source code below is used to display the right tree viewer in the illustration above. It’s usual EMF.Edit programming. The only difference is the usage of a PartitionedContentProvider instead of an AdapterFactoryContentProvider.

You find the implementation of PartitionedContentProvider here. It’s packaged into a plugin but feel free to copy that single class into your own project. Overwrite the method getVirtualFolderSize() to limit the maximum number of container’s direct children. If the number exceeds this limit, virtual folders are hooked in instead. If the virtual folder size is -1 virtual folders are not created.


final AdapterFactory adapterFactory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
domain = new AdapterFactoryEditingDomain(adapterFactory, new BasicCommandStack());

viewer = new TreeViewer(parent, SWT.FLAT | SWT.MULTI);

viewer.addDragSupport(DND.DROP_MOVE, new Transfer[] { LocalTransfer.getInstance() }, new ViewerDragAdapter(viewer));
viewer.addDropSupport(DND.DROP_MOVE, new Transfer[] { LocalTransfer.getInstance() }, new EditingDomainViewerDropAdapter(domain, viewer));
viewer.setLabelProvider(new AdapterFactoryLabelProvider(adapterFactory));

// we limit the maximal child elements for containers to 100
viewer.setContentProvider(new PartitionedContentProvider(adapterFactory) {

       @Override
       protected int getVirtualFolderSize(Object folder) {
          return folder instanceof Container ? 100 : DEFAULT_FOLDER_SIZE;
       }
});