| <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> |