Sunday, January 06, 2008

JFace TableViewer vs Swing JTable

While the SWT Table widget in Eclipse supports display of tabular data through the host operating system native table widget, its API is low-level and does not come with built-in support for data management through the MVC architectural pattern. This is where JFace TableViewer comes into place. It allows developers to populate tables through the implementation of model classes, the chief of which are IContentProvider and ITableLabelProvider.

How does it compare to the Java Swing JTable though?

To populate a table, JTable requires developers to implement a class called TableModel, which abstracts the data presentation of a table. The actual method that populates the table is getValueAt(int rowIndex, int columnIndex), which returns objects to be rendered for every cell in the table.

TableViewer on the other hand notices a pattern in table population related to the fact that table data is usually broken into rows, and then per each row, it is broken into columns. It takes advantage of that by having developers specify how data is broken into rows through an IContentProvider implementation, and then specify how a row is broken into columns through an ITableLabelProvider implementation.

Since table data often comes in a list or collection of some sort, the benefit of the latter approach is that one can reuse the same IContentProvider implementation across many tables, only needing to implement different ITableLabelProviders for each use-case.

This can still be done in Swing by relying on an abstract TableModel that always expects data in a collection, but the IContentProvider makes the separation of concerns cleaner in TableViewer.

Swing JTable provides other advantages due to being a rendered widget instead of a native platform widget. It supports having a TableCellRenderer, enabling you to render data in any way you like (e.g. as buttons, checkboxes, canvas painting, etc...) whereas TableViewer always displays data only as text, image, or a combination of both.

Is the API of either TableViewer or JTable a factor in determining which to use to build your future business applications?

I would say no. The differences are mostly aesthetic as you can accomplish basic business needs easily with either widget.

What really sets the decision apart is that TableViewer relies on a native table widget, offering a more familiar look and feel and potentially better performance whereas JTable is a Java Swing platform-independent widget, giving you more control and flexibility over the look and feel of the table.

Update: While this may have been accurate for previous versions of SWT, the situation changed with SWT 3.3 as it now supports cell rendering just like Swing. Please check Tom's comment for more details.

4 comments:

Tom said...

You can implement a CellRenderer like behaviour in SWT too since 3.3 when using the ownerdraw-support we and SWT provide. See http://wiki.eclipse.org/JFaceSnippets#Snippet010OwnerDraw.

We have even added better support for it in 3.4. See http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jface.snippets/Eclipse%20JFace%20Snippets/org/eclipse/jface/snippets/viewers/Snippet049SimpleStyledCellLabelProvider.java?view=markup .

Finally if you really want to have a custom widget implementation and use a JFace-Viewer you could use Nebula-Grid which also provides a Viewer-Implementation. See http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.nebula/org.eclipse.swt.nebula.snippets/src/org/eclipse/nebula/snippets/gridviewer/?root=Technology_Project

Annas "Andy" Maleh said...

Thanks for the correction Tom. I mentioned it in a remark at the end of the blog post.

Esteve said...

Swing JTable allows you to use Generics in your model, while JFace use ugly Objects on every methtod (I hate this)

Kai said...

If you want to select a 'block' of cells, the TableViewer is a pain in the a..!