Sunday, August 24, 2008

Writing a CTreeCombo-Widget

I was working on my example RCP/EMF/Databinding application


I'm going to use to present various parts of those technologies to my co-workers and getting familiar with new technologies like CDO, Teneo, Spring and others when I hit the problem that standard CCombo didn't suited my needs.

What I wanted to have was a CCombo which presents a Tree like structure like this


for my Login-Screen and as you all know there's no such widget available currently. As you might guess from the above Screenshot I somehow managed to get such a widget.

Before we dive into it another requirement I had was that the implementation plugs itself into the existing viewer and databinding concepts of Eclipse.

So what did I do and how did it work? Well 95% of the work I had to do is C&P. I copied the CCombo-Code replaced List against Tree and solved compilation errors. To make a CTreeCombo widget I would have been done almost if this would have been the only requirement.

The real problem is that widgets are reparentable and that this can happen across Shells which makes it necessary to recreate the Tree and its popup shell from time to time so directly attaching a TreeViewer on the underlying Tree-Widget is not possible. So the only possibility was to create Proxy objects around TreeItem/TreeColumn who proxy the real implemementation so that they could be recreated whenever needed.

So if one wants to use the widget he/she has to write code like this:

int style = SWT.BORDER|SWT.READ_ONLY|SWT.FULL_SELECTION;
CTreeCombo combo = new CTreeCombo(shell,style);

CTreeComboItem item = new CTreeComboItem(combo,SWT.NONE);
item.setText("Parent 1");

CTreeComboItem childItem = new CTreeComboItem(item,SWT.NONE);
childItem.setText("Child 1.1");

childItem = new CTreeComboItem(item,SWT.NONE);
childItem.setText("Child 1.2");

item = new CTreeComboItem(combo,SWT.NONE);
item.setText("Parent 2");

childItem = new CTreeComboItem(item,SWT.NONE);
childItem.setText("Child 2.1");

childItem = new CTreeComboItem(item,SWT.NONE);
childItem.setText("Child 2.2");

CTreeCombo now works like an ordinary SWT-Tree providing the same API as SWT-Tree (at least currently the one which is necessary to write a JFace-Viewer) so that I could subclass AbstractTreeViewer and providing an implementation for it. So if one uses JFace-Viewers in his/her code they simply need to write:

int style = SWT.READ_ONLY|SWT.BORDER|SWT.FULL_SELECTION
CTreeCombo combo = new CTreeCombo(parent,style);

CTreeComboViewer viewer = new CTreeComboViewer(combo);
viewer.setLabelProvider(new LabelProviderImpl());
viewer.setContentProvider(new ContentProviderImpl());
viewer.setInput(input);

In the end it took me longer than I first thought but after 4 hours I had a working CTreeComboViewer (although it is not thoroughly tested yet) which behaves appropiately (at least in the way I currently use it).

If you are interested in the code of the widget or in the application to learn about:

  • Writing a modular RCP-Application

  • Using SWT, JFace and Databinding

  • Using EMF and EMF-Databinding

  • Using and creating your own Extension Points

  • Using and extending the Commands, Handlers and the Expression Framework


You can fetch the code from my companies svn-repository but the application is still in flux. If you are only interested in the widget and viewer code you can find it here for the widget and here for the viewer.

8 comments:

Wassim Melhem said...

Hey Tom, that's very cool. I am always very impressed by your innovation.

David McKinnon said...

I love this widget. Nice job.

M2MBeginner said...

I had a look in your code.
I was mainly interested in your validation stuff.
So you are using the UpdateValueStrategy.

Unfortunately, you don't use OCL with your Ecore model.

This would be very interesting for me since I haven't seen a real application using EMF and MDT OCL.

fisherja said...

Hey Tom, Is there any thought of bringing this widget over to nebula or eclipse 3.6. I picked it up today but would probably want to work to smooth the edges, coming to mind at the moment would be providing setVisibleItems as part of the CTreeCombo api.

Thanks, Jake

Tom said...

Good idea! I'll file a bug against Nebula.

Tom said...

Proposal to nebula is https://bugs.eclipse.org/bugs/show_bug.cgi?id=268499

Daniel Kr├╝gler said...

I like the idea, but I observed a behavior that immediately deviates from native combos and CCombo (at least on Windows): If the combo shows all items and if one item becomes selected, the list doesn't 'collapse' again. Is their a know workaround to realize that behavior?

generic viagra 100mg said...

This is pretty interesting site with lots of very informative post. I pleased to find this site. Every time I got some thing new and interesting information here. I must appreciate your blog site. Good job! Keep posting.

Regards
Alexa