| <div id="midcolumn"> | |
| <h2>FAQ</h2> | |
| <div id="doccontent"> | |
| <div class="chapter"> | |
| <h3>General Questions</h3> | |
| <h4>Why is it called NatTable?</h4> | |
| <p>NatTable was originally written by Andy Tsoi and dedicated to his girlfriend, Natalie.</p> | |
| <p>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.</p> | |
| <h4>How much data can you put behind it?</h4> | |
| <p>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.</p> | |
| </div> | |
| <div class="chapter"> | |
| <h3>How To...</h3> | |
| <h4>How to create ComboBoxCellEditors with dynamic content?</h4> | |
| <p> | |
| You can either create an instance of <span class="code">ComboBoxCellEditor</span> with a given list of values | |
| (which results in a static combobox) or with an instance of a custom <span class="code">IComboBoxDataProvider</span>. | |
| By creating and using a custom <span class="code">IComboBoxDataProvider</span> you are able to load the content | |
| of the combobox at runtime. As <span class="code">IComboBoxDataProvider.getValues(int, int)</span> 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. | |
| <div class="codeBlock">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"}); | |
| } | |
| } | |
| }</div> | |
| <p class="subline">Create custom IComboBoxDataProvider to return different lists regarding other cell values</p> | |
| <div class="codeBlock">//the body data provider needs to be known by this configuration | |
| configRegistry.registerConfigAttribute( | |
| EditConfigAttributes.CELL_EDITOR, | |
| new ComboBoxCellEditor(new MyComboBoxDataProvider(bodyDataProvider))), | |
| DisplayMode.EDIT, | |
| "myComboBoxLabel");</div> | |
| <p class="subline">Register a ComboBoxCellEditor with the custom IComboBoxDataProvider</p> | |
| </p> | |
| <h4>How to autoresize columns/rows programmatically?</h4> | |
| <p> | |
| 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.<br/><br/> | |
| But there is another possibility how to achieve autoresizing columns. The <span class="code">TextPainter</span> | |
| 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. | |
| <div class="codeBlock">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();</div> | |
| <p class="subline">Modifying the DefaultNatTableStyleConfiguration to use a TextPainter that calculates cell width/height as cell painter</p> | |
| </p> | |
| <p> | |
| The <span class="code">TextPainter</span> 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.<br/> | |
| 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.<br/><br/> | |
| In the SourceForge forum <b>josecho2005</b> 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 | |
| <a href="http://sourceforge.net/projects/nattable/forums/forum/744994/topic/5245501" title="SourceForge forum topic on autoresize">here</a>. | |
| <div class="codeBlock">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); | |
| } | |
| });</div> | |
| <p class="subline">Adding a listener that autoresizes the NatTable after rendering is finished and removes itself after that</p> | |
| </p> | |
| <p> | |
| In the Eclipse forum <b>Jay Norwood</b> 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.<br/> | |
| This solution also introduces the <span class="code">IOverlayPainter</span> 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 | |
| <a href="http://www.eclipse.org/forums/index.php/t/369717/" title="Eclipse forum topic on autoresize">here</a>. | |
| <div class="codeBlock">final NatTable natTable = new NatTable(tableComposite, grid); | |
| natTable.addOverlayPainter(new IOverlayPainter() { | |
| private HashSet<Integer> rowset = new HashSet<Integer>(); | |
| private HashSet<Integer> colset = new HashSet<Integer>(); | |
| @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); | |
| } | |
| } | |
| });</div> | |
| <p class="subline">Adding an IOverlayPainter that autoresizes the NatTable after rendering is finished and on scrolling</p> | |
| 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. | |
| </p> | |
| <h4>How to add NatTable commands to eclipse menus?</h4> | |
| TODO | |
| <h4>How to access NatTable icons?</h4> | |
| TODO | |
| </div> | |
| </div> | |
| </div> |