I have implemented a nattable tree view representation for qrtPCR plugin. The following shows the required steps to achieve that:

  • You need to have a row object which can provide child parent relationship to other rows in the table. In my case, I either have Gene or GeneData objects as the rows of my table and Gene object has a list of GeneData objects and GeneData has a reference to its parent Gene. I have created a common class called TableData which both Gene and GeneData inherits and added all Genes and GeneData objects as rows into the table as shown in the following:
        // Underlying data source
        List<TableData>  allData = new ArrayList<TableData>();
        for (Gene gene : data.getGenes()) {
  • The next step is to implement a class that implements TreeList.format interface:
public class PlateTreeFormat implements TreeList.Format<TableData>{


        public void getPath(List<TableData> path, TableData element) {
        	if (element instanceof Gene) {
        	else if (element instanceof GeneData) {
        		path.add(((GeneData) element).getGene());
        	else if (element instanceof MergeTableData)

        public boolean allowsChildren(TableData element) {
            return true;

The important part in the above example is that you should return a path to the parent for each row object in the table. If the row is the root, it should only contain itself. If it is a leaf node, it should contain itself and its parent. You can have as many levels as necessary but I had only two levels in my case.

  • The following shows the related layers in the nattable:
        eventList = GlazedLists.eventList(this.tableData);
        sortedList = new SortedList<TableData>(eventList, null);
        ISortModel sortModel = new PlateTableSortModel<TableData>(sortedList,
                columnPropertyAccessor, configRegistry, columnHeaderDataLayer);

        PlateTreeFormat treeFormat = new PlateTreeFormat(sortModel);
        treeList = new TreeList<TableData>(sortedList,
                treeFormat, new MyExpansionModel());
        GlazedListTreeData<TableData> treeData = new GlazedListTreeData<TableData>(treeList);

        // Body layer
        ListDataProvider<TableData> bodyDataProvider = new ListDataProvider<TableData>(
                treeList, columnPropertyAccessor);
        bodyDataLayer = new DataLayer(bodyDataProvider);
        GlazedListsEventLayer<TableData> glazedListsEventLayer = new GlazedListsEventLayer<TableData>(
                bodyDataLayer, treeList);
        ColumnReorderLayer columnReorderLayer = new ColumnReorderLayer(
        columnHideShowLayer = new ColumnHideShowLayer(

        RowHideShowLayer rowHideShowLayer = new RowHideShowLayer(

        // Switch the ITreeRowModel implementation between using native grid
        // Hide/Show or GlazedList TreeList Hide/Show
        // TreeLayer treeLayer = new TreeLayer(rowHideShowLayer, new
        // TreeRowModel<Datum>(treeData), true);
        treeLayer = new TreeLayer(rowHideShowLayer,
                new GlazedListTreeRowModel<TableData>(treeData), false);

        selectionLayer = new SelectionLayer(treeLayer);

Implementing your own SortModel is optional but since you have to sort children nodes together with their parents, you may need to implement own algorithm. For the details, please check org.grits.toolbox.entry.qrtpcr.table.QrtPCRNatTable, related classes, and org.grits.toolbox.entry.qrtpcr.table.merge.MergeNatTable

Last modified 6 years ago Last modified on 03/23/2016 03:00:58 PM