Blog
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 SWT-Provided 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:
- We don't need all those interfaces any more
- We have a new abstraction level for column based viewers (ViewerRow, ViewerCell)
- 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() < 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.