FAQ

General Questions
Why is it called NatTable?

NatTable was originally written by Andy Tsoi and dedicated to his girlfriend, Natalie.

We also sometimes think of 'Nat' as an acronym for 'Not A Table' given that it's really more of a data grid, or a tool for building tables/grids.

How much data can you put behind it?

As much as you want, pretty much. The only practical limit right now is that the number of columns, rows, width and height of your table must be able to be represented as 32-bit integers. We test against virtual data sets of 1 million columns by 1 million rows.

How To...
How to create ComboBoxCellEditors with dynamic content?

You can either create an instance of ComboBoxCellEditor with a given list of values (which results in a static combobox) or with an instance of a custom IComboBoxDataProvider. By creating and using a custom IComboBoxDataProvider you are able to load the content of the combobox at runtime. As IComboBoxDataProvider.getValues(int, int) gets the column and row index of the cell for which the combobox should be rendered, it is possible to get information out of other cells to determine which content the combobox should contain.

public class MyComboBoxDataProvider implements IComboBoxDataProvider { private IDataProvider bodyDataProvider; public MyComboBoxDataProvider(IDataProvider bodyDataProvider) { this.bodyDataProvider = bodyDataProvider; } @Override public List<?> getValues(int columnIndex, int rowIndex) { //guess in column with index == 1 a checkbox editor with a boolean value //is configured, we get the current boolean value out of the body data //provider and decide which values to show Boolean checked = (Boolean) bodyDataProvider.getDataValue(1, rowIndex); if (checked) { return Arrays.asList(new String[] {"Homer", "Bart"}); } else { return Arrays.asList(new String[] {"Marge", "Lisa", "Maggie"}); } } }

Create custom IComboBoxDataProvider to return different lists regarding other cell values

//the body data provider needs to be known by this configuration configRegistry.registerConfigAttribute( EditConfigAttributes.CELL_EDITOR, new ComboBoxCellEditor(new MyComboBoxDataProvider(bodyDataProvider))), DisplayMode.EDIT, "myComboBoxLabel");

Register a ComboBoxCellEditor with the custom IComboBoxDataProvider

How to autoresize columns/rows programmatically?

NatTable supports the autoresize feature on double clicking cell edges. Unfortunately the existing commands related to that feature doesn't work if they are fired programmatically on building the NatTable. This is because when firing the command, the NatTable isn't rendered yet, so the calculation of the width is returning the wrong values.

But there is another possibility how to achieve autoresizing columns. The TextPainter which is used for rendering cell content as text, can be configured to calculate the column width/row height. Modifying the default configuration the following way will resize the columns on rendering the content, so the content can be shown completely. Also note that if the content contains line breaks, the row height will be calculated also.

NatTable natTable = new NatTable(tableComposite, grid, false); //as the autoconfiguration of the NatTable is turned off, we have to add the //DefaultNatTableStyleConfiguration and the ConfigRegistry manually natTable.setConfigRegistry(configRegistry); natTable.addConfiguration(new DefaultNatTableStyleConfiguration() { { cellPainter = new LineBorderDecorator( new TextPainter(false, true, 5, true)); } }); natTable.configure();

Modifying the DefaultNatTableStyleConfiguration to use a TextPainter that calculates cell width/height as cell painter

The TextPainter solution has one downsite. If the cell content is not a long text but a long word that can't be wrapped, it is not possible to manually resize the cell anymore to show the content cutted.
There is another downsite if the table is editable. The cells will automatically resize if the cell content which defines the cell width is modified to be longer/shorter. In fact this can also be a requirement, but compared to other well known grids, this behaviour is rather unexpected.

In the SourceForge forum josecho2005 found a solution that only does the autoresize after rendering is finished. With some slight modifications it looks like this. You can find the original post here.

NatTable natTable = new NatTable(tableComposite, grid); natTable.addListener(SWT.Paint, new Listener(){ @Override public void handleEvent(Event arg0) { for (int i=0; i < natTable.getColumnCount(); i++) { InitializeAutoResizeColumnsCommand columnCommand = new InitializeAutoResizeColumnsCommand( natTable, i, natTable.getConfigRegistry(), new GCFactory(natTable)); natTable.doCommand(columnCommand); } for (int i=0; i < natTable.getRowCount(); i++) { InitializeAutoResizeRowsCommand rowCommand = new InitializeAutoResizeRowsCommand(natTable, i, natTable.getConfigRegistry(), new GCFactory(natTable)); natTable.doCommand(rowCommand); } natTable.removeListener(SWT.Paint, this); } });

Adding a listener that autoresizes the NatTable after rendering is finished and removes itself after that

In the Eclipse forum Jay Norwood posted a similar solution which also works for larger tables where you need to scroll the content. To understand why this is needed, you have to remember that the NatTable is a virtual table. This means that only the content is processed that is visible. So you can't do an autoresize on columns that aren't visible. So the following solution is remembering which columns/rows where already autoresized. This way the autoresize isn't called again for the same column/row if you scroll or resize the view that contains the NatTable. The listener need to be active all the time and shouldn't be removed then.
This solution also introduces the IOverlayPainter of the NatTable. Implementations of this interface can be added to the NatTable. They will be called after the rendering of the NatTable is finished. You can find the original post here.

final NatTable natTable = new NatTable(tableComposite, grid); natTable.addOverlayPainter(new IOverlayPainter() { private HashSet rowset = new HashSet(); private HashSet colset = new HashSet(); @Override public void paintOverlay(GC gc, ILayer layer) { int count = natTable.getColumnCount(); for (int i=0; i < count; i++) { if (natTable.isColumnPositionResizable(i) == false) { continue; } int pos = natTable.getColumnIndexByPosition(i); if (colset.contains(pos)) { continue; } colset.add(pos); InitializeAutoResizeColumnsCommand columnCommand = new InitializeAutoResizeColumnsCommand(natTable, i, natTable.getConfigRegistry(), new GCFactory(natTable)); natTable.doCommand(columnCommand); } count = natTable.getRowCount(); for (int i=0; i < count; i++) { if (natTable.isRowPositionResizable(i) == false){ continue; } int pos = natTable.getRowIndexByPosition(i); if (rowset.contains(pos)) { continue; } rowset.add(pos); InitializeAutoResizeRowsCommand rowCommand = new InitializeAutoResizeRowsCommand(natTable, i, natTable.getConfigRegistry(), new GCFactory(natTable)); natTable.doCommand(rowCommand); } } });

Adding an IOverlayPainter that autoresizes the NatTable after rendering is finished and on scrolling

Although this solution works for larger tables, this is not a usual use case and can cause some side effects or unexpected behaviour in resizing. We suggest to don't do automatic resizing on larger tables where the user needs to scroll. Other well known grid/table applications doesn't support that either and leave the sizing of columns/rows to the user who is looking at it.

How to add NatTable commands to eclipse menus?
TODO
How to access NatTable icons?
TODO