The new faces of JFace (part2)


The last time I showed you the new programming model we introduced to JFace to make it feel like programming SWT.

But has this been the only reason that we decided to add this new API beside the existing one (ILabelProvider, ITableLabelProvider, IColorProvider, ITableColorProvider, IFontProvider, ITableFontProvider) .
Sure enough it was not the only reason. First of all many newcomers have been confused by all those NON MANDATORY interfaces to control different aspects of items and we faced the problem that whenever SWTProvided a new feature e.g. Owner Draw Support in 3.2 we would have to add a new interface type and to support new features e.g. ToolTip support for table/tree cells we also had to provide a new interface. We decided that this is not the way to go for the future.

So we sat down and thought about a complete new structure below JFace tree and table support. We added the idea of rows (ViewerRow) and cells (ViewerCell) abstracting common things provided of TreeItem and TableItem and completely hiding the widget specific things into this class. The abstraction level this provided to us made it possible to provide a common class named ColumnViewer.

So what have we learned so far:

  1. We don‘t need all those interfaces any more
  2. We have a new abstraction level for column based viewers (ViewerRow, ViewerCell)
  3. We have a new base class named ColumnViewer

So you may ask what you should use if you can‘t use the old interfaces any more. Well the answer is ColumnLabelProvider or if you want to implement the whole cell behaviour your own it‘s abstract base class named CellLabelProvider. The new ColumnLabelProvider combines all currently know interfaces (ILabelProvider, IFontProvider, IColorProvider). There‘s no base class visible to you supporting ITable*interfaces because those interface put limitations to tables I’ll show you later let‘s now explore how to use the new ColumnLabelProvider interface and how it is used.

TableViewer viewer = new TableViewer(parent,SWT.FULL_SELECTION);

TableViewerColumn column = new TableViewerColumn(viewer,SWT.NONE);
column.setLabelProvider(new StockNameProvider());
column.getColumn().setText("Name");

TableViewerColumn column</span> = new TableViewerColumn(viewer,SWT.NONE);
column.setLabelProvider(new StockValueProvider</span>());
column.getColumn().setText("Modification");

public class StockNameProvider extends ColumnLableProvider {
  @Override
  public String getText(Object element) {
    return ((Stock)element).name;
  }
}

public class StockValueProvider extends ColumnLabelProvider {
  @Override
  public String getText(Object element) {
    return ((Stock)element).modification.doubleValue() + "%";
  }

  @Override 
  public Color getForeground(Object element) {
    if( ((Stock)element)modiciation.doubleValue() &lt; 0 ) {
      return getDisplay().getSystemColor(SWT.COLOR_RED);
    } 
    else {
      return getDisplay().getSystemColor(SWT.COLOR_GREEN);
    }
  }
}

You may now argue that this was easier with the old ITable*-API and you are true but from the point of reusability this version is much more flexible and you can reuse your LabelProviders for many different TableViewers because they don‘t hold any index informations. Another thing is that you needed a bunch of custom code if you wanted the columns to be reordable with the old API this is not an issue any more with the new API because the LabelProvider is directly connected to the column and moves with it.

Next time I’ll continue with some nice new LabelProvider features like ToolTip support and OwnerDraw.

Advertisements
This entry was posted in 3.x. Bookmark the permalink.

6 Responses to The new faces of JFace (part2)

  1. Mark Levison says:

    While your doing all of this work would you consider providing a version of the tree viewer where you store no state information?

    In the product I’m building our engine keeps track of the open/close state, selection etc. In addition results are readonly – so open/close I need make a request of the engine. When its done the work it will hand back a new results set.

    Currently when we use the treeviewer and the content provider we have about 150 lines of code just keep the tree state in sync with the results set.

    Please give us a stateless version of the tree viewer.

  2. Tom says:

    Please file a bug report or CC to the bug report if there one already. If this does need an API-Change maybe I have time in M6 to work on it if we need new API I think its too late.

  3. Mark Levison says:

    I will file a bug report. Mostly I mentioned this as food for thought. I’m hoping to stimulate your thinking as you move forward. Sometimes it would easier for us if your provided less instead of more.

  4. Troy says:

    Has the new API been finalized? I really like this new design and it would help me out quite a bit. I don’t mind at all having to adjust for minor changes here and there as you near the final 3.3 release. I’d just like to avoid adopting it only to find out it’s been abandoned for something else. 🙂

  5. Tom says:

    Well the parts demonstrated here are fairly ready and I don’t expect things to change but to be sure you should wait for M5 which is API freeze. The only thing that is currently in dicussion and will add new API is https://bugs.eclipse.org/bugs/show_bug.cgi?id=151295 but I don’t expect any of the demonstrated API go away. But I’m not the decision maker.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s