# Tree, Table and the Nebula Grid

### SWT Tree/Table

Tree and Table are among the most powerful widgets in SWT and RAP. Thanks to JFace and virtual rendering they can easily display vast amounts of data. Any tree/table will only render HTML for the items that are currently visible on screen, keeping client memory consumption low and initial rendering time short regardless of item count. Also, if the widget (or viewer) is created with a VIRTUAL flag, items can be created lazily. As a result, data that is not (yet) visible will also not be transferred to the client. However, you will also experience a small rendering delay when scrolling to previously unseen data. You can reduce this effect by pre-caching some items.

### Nebula Grid

In addition to the Tree and Table widgets, RAP also includes a port of the Nebula Grid and it's JFace Viewers. (As of RAP 3.0. RAP 2.x compatible ports of the Grid are available in the RAP Incubator.) The Grid API is very similar to Tree and Table, but includes a number of additional features like column grouping, checkboxes on multiple columns, variable/automatic item height, and a column footer. (Note that for technical reasons the RAP port can only support a subset of the features of the original Nebula Grid.)

The Grid and it's viewers are placed in separate bundles. To use them you need to add a dependency from your project to the org.eclipse.rap.nebula.widgets.grid and org.eclipse.rap.nebula.jface.gridviewer Plug-Ins, or to the org.eclipse.nebula.widgets.grid and org.eclipse.nebula.jface.gridviewer packages.

### RAP Enhancements

RAP adds some some significant functionality to Tree, Table and Grid not found in their SWT/Nebula counterparts. Like most RAP enhancements, these features are activated using the setData method. Even when using a viewer this can still be done in one line:

    viewer.getTable().setData( RWT.MARKUP_ENABLED, Boolean.TRUE );

The following is a list of RAP exclusive features supported by Tree, Table and/or Grid:

### Fixed Columns (Tree and Table)

When a table or tree displays many columns, the user often has to scroll horizontally to see specific data. Doing so means losing sight of the first columns, which may contain vital information that should be visible at all times. Using RWT.FIXED_COLUMNS, it is possible to exclude any number of leftmost columns from scrolling, so that they always stick on the left side of the tree or table.

Example:

    tree.setData( RWT.FIXED_COLUMNS, new Integer( 1 ) );

### Templates (Tree, Table and Grid)

Row templates allow developers to customize the way a Table/Tree/Grid present items on screen, completely replacing the default column layout. A template consists of text and image cells that can be freely arranged. These cells can display either data from an item, or static content.

To create a new template, construct an instance of the Template class, and then add any number of ImageCell and TextCell instances. To apply it, RWT.ROW_TEMPLATE is used:

    Template template = new Template();
    ImageCell imageCell = new ImageCell( template );
    TextCell nameCell = new TextCell( template );
    //... configure cells
    table.setData( RWT.ROW_TEMPLATE, template );

The call to setData should be placed directly after the controls creation. Once a template is applied to a control it will no longer be affected by changes to the template. The same template instance can also be applied to multiple controls.

To position a cell, you have to set exactly two horizontal and two vertical dimensions (two out of left, right and width, and two out of top, bottom and height). The cells are positioned relative to the area that is available to display the current item - which is usually the inner width of the Tree/Table/Grid widget and the height given using RWT.CUSTOM_ITEM_HEIGHT or the Grid.setItemHeight method. The values for left, top, right and bottom may be absolute (in pixel), relative (in percentage), or the sum of both. The values for width and height may only be absolute.

    imageCell.setLeft( 40, 0 ).setWidth( 48 ).setTop( 4 ).setBottom( 33.33f, 4 );

All cells can by further styled with colors, fonts, alignments, etc. Since all setter return the cell instance, chaining the commands as shown above is always possible. Note that as of RAP 2.2, the vertical alignment property is not supported for text cells, only for image cells.

Each cell can either display static content (using setText or setImage on the cell itself), or content form the current Tree/Table/Grid item. For this the cell needs to be bound to a specific column using the bindingIndex. For example, this shows only the text from the first column:

    Table table = new Table( parent, SWT.FULL_SELECTION );
    new TableColumn( table, SWT.NONE ); // important
    Template template = new Template();
    TextCell textCell = new TextCell( template );
    textCell.setLeft( 0 ).setRight( 0 ).setTop( 0 ).setBottom( 0 );
    textCell.setBindingIndex( 0 );
    table.setData( RWT.ROW_TEMPLATE, template );
    TableItem item = new TableItem( table, SWT.NONE );
    item.setText( 0, "Data in the first column" );

Please note that while it is not useful to set the headerVisible property to true if row templates are used, it is still necessary to create column objects. They don't need a text or width though.

Cells can also be selectable. When a selectable cell is clicked on, it does not select the item, but triggers a selection event with the event.detail field set to RWT.CELL. Items can still be selected by clicking elsewhere, though the selection is only visible if the SWT.FULL_SELECTION style flag is set. If multiple cells in a template are selectable, cells can be given a name that is reflected in the event.text field in order to identify the selected cell.

### Markup Support (Tree, Table and Grid)

You can use the markup feature to format the text within a cell or embed links and additional images. See also Markup on List, Tree, Table and Grid.

### Line breaks in Columns (Tree, Table and Grid)

Unlike SWT, RAP supports line breaks (\n) in a columns text property.

### Item Pre-Caching (Tree and Table)

By default, a VIRTUAL Tree/Table will resolve only items currently on screen. If an unresolved item becomes visible, a placeholder (...) will be displayed while data is transferred to the client. This can often be avoided by also resolving a number of items above and below the visible area. You can set the amount of items to be pre cached using `RWT.PRELOADED_ITEMS`.

### Selection/Hover rendering order (Tree, Table and Grid)

Note:Grid uses the theming of Tree, so everything in this section that applies to the Tree also applies to the Grid.

Any item and every cell of an item may have a custom background to highlight a specific unit of data. In SWT (and RAP, by default), hovering or selecting such an item will completely overlay these backgrounds, essentially removing onscreen information. This behavior can be configured in RAP using the CSS Theming API. Note that any item that has a background set on all cells (or the item itself), will only be identifiable as selected by the text color, or not at all (if there is also a custom foreground set).

In addition to the TableItem / TreeItem theming elements, there are also Table-RowOverlay / Tree-RowOverlay elements. In the default theme, these overlay elements are used to define the hover and selection behavior. If you wish for the item backgrounds to paint over the selection/hover effects, you will have to use these overlay element to create the effects. (You can also mix, so that hover or selection paints over the backgrounds, but not the other.)

Assuming you implement a complete custom theme, this is easy. Simply use only the item element to define the effect and define the overlay element as below:

    Table-RowOverlay {
      background-color: transparent;
      color: inherit;
      background-image: none;
    }

If you wish to only make a theme contribution, you also need to overwrite every possible combination for the overlay element that may be defined in the main/default theme:

    Table-RowOverlay,
    Table-RowOverlay:hover,
    Table-RowOverlay:selected,
    Table-RowOverlay:selected:unfocused,
    Table-RowOverlay:linesvisible:even:hover,
    Table-RowOverlay:linesvisible:even:selected,
    Table-RowOverlay:linesvisible:even:selected:unfocused {
      background-color: transparent;
      color: inherit;
      background-image: none;
    }

To create the new hover/selection effect you then have to define some or all of these combinations for the item element, for example:

    TableItem:hover {
      color: #4a4a4a;
      background-color: #b5b5b5;
      background-image: gradient(
        linear, left top, left bottom,
        from( #ebebeb ),
        to( #d5d5d5 )
      );
    }

    TableItem:selected,
    TableItem:linesvisible:even:selected {
      color: #ffffff;
      background-color: #5882b5;
      background-image: gradient(
        linear, left top, left bottom,
        from( #5882b5 ),
        to( #416693 )
      );
    }

Alternatively, it's also possible to define semi-transparent background colors for the overlay element using the rgba notation. This would then create a hover/selection effect with the items background color(s) shining through.