Home » Eclipse » NAT Tree List with GlazedLists and NatTable

NAT Tree List with GlazedLists and NatTable

This is my exercise code to create a Tree List with expand/collapsible subgroups.

The code was derived from Vogellas Nebula NatTable – Commands & Events – Tutorial.

My Code

The data rows of the table:

package tryout.treelist;

public class Area {
	private String name;
	private long population;
	
	public Area(String name, long population) {
		super();
		this.name = name;
		this.population = population;
	}
	
	public String getName() {
		return name;
	}
	public long getPopulation() {
		return population;
	}
	
	@Override
	public String toString() {
		return name + " Population: " + population;
	}
}

The tree node wrapper

package tryout.treelist;

import java.util.ArrayList;
import java.util.List;

public class TreeItem<T> {
	private T item;
	private TreeItem<T> parent;
	private List<TreeItem<T>> children = new ArrayList<>();
	
	public TreeItem(T item, TreeItem<T> parent){
		this.item=item;
		this.parent=parent;
		this.parent.addChild(this);
	}
	public TreeItem(T content) {
		this.item=content;
	}
	
	private void addChild(TreeItem<T> treeItem) {
		children.add(treeItem);		
	}

	public TreeItem<T> getParent() {
		return parent;
	}

	public boolean hasChildren() {
		return children.size() > 0;
	}

	public T getItem() {
		return item;
	}

}

The tree format definition for such nodes:

package tryout.treelist;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import ca.odell.glazedlists.TreeList;

class TreeItemFormat implements TreeList.Format<TreeItem<Area>> {

    @Override
    public void getPath(List<TreeItem<Area>> path, TreeItem<Area> element) {
    	List<TreeItem<Area>> path1 = new ArrayList<>();
        if (element.getParent() != null) {
        	getPath(path1, element.getParent());
            path.addAll(path1);
        }
        path.add(element);
    }

    @Override
    public boolean allowsChildren(TreeItem<Area> element) {
        return element.hasChildren();
    }

    @Override
    public Comparator<? super TreeItem<Area>> getComparator(int depth) {
        return (o1, o2) -> o1.getItem().toString().compareTo(o2.getItem().toString());
    }
}

The GUI view defining the NAT table and the data fed to it:

package tryout.treelist;

import java.util.Collection;

import javax.annotation.PostConstruct;

import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.nebula.widgets.nattable.data.ExtendedReflectiveColumnPropertyAccessor;
import org.eclipse.nebula.widgets.nattable.data.IColumnPropertyAccessor;
import org.eclipse.nebula.widgets.nattable.data.ListDataProvider;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.tree.GlazedListTreeData;
import org.eclipse.nebula.widgets.nattable.extension.glazedlists.tree.GlazedListTreeRowModel;
import org.eclipse.nebula.widgets.nattable.grid.GridRegion;
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
import org.eclipse.nebula.widgets.nattable.tree.TreeLayer;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;

import com.google.common.collect.ImmutableList;

import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.GlazedLists;
import ca.odell.glazedlists.TreeList;

public class SimpleTreePart {

    @PostConstruct
    public void createComposite(Composite parent) {
        parent.setLayout(new GridLayout());
        // Properties of the Area items inside the TreeItems
        String[] propertyNames = { "item.name", "item.population" };

        IColumnPropertyAccessor<TreeItem<Area>> columnPropertyAccessor = new ExtendedReflectiveColumnPropertyAccessor<TreeItem<Area>>(
                propertyNames);

        EventList<TreeItem<Area>> eventList = GlazedLists.eventList(getSampleAreaTreeItems());
        TreeList<TreeItem<Area>> treeList = new TreeList<TreeItem<Area>>(eventList, new TreeItemFormat(),
                TreeList.nodesStartExpanded());
        ListDataProvider<TreeItem<Area>> dataProvider = new ListDataProvider<>(treeList, columnPropertyAccessor);
        DataLayer dataLayer = new DataLayer(dataProvider);
        setColumWidthPercentage(dataLayer);

        GlazedListTreeData<TreeItem<Area>> glazedListTreeData = new GlazedListTreeData<>(treeList);
        GlazedListTreeRowModel<TreeItem<Area>> glazedListTreeRowModel = new GlazedListTreeRowModel<>(
                glazedListTreeData);

        TreeLayer treeLayer = new TreeLayer(dataLayer, glazedListTreeRowModel);
        treeLayer.setRegionName(GridRegion.BODY);

        new NatTable(parent, treeLayer, true);
        

        GridLayoutFactory.fillDefaults().generateLayout(parent);
    }

    private Collection<TreeItem<Area>> getSampleAreaTreeItems() {
		TreeItem<Area> globe = new TreeItem<Area>(new Area("Globe", 8000));
		
		TreeItem<Area> europe = new TreeItem<Area>(new Area("Europe", 983), globe);
		TreeItem<Area> switzerland = new TreeItem<Area>(new Area("Switzerland", 8), europe);
		TreeItem<Area> germany = new TreeItem<Area>(new Area("Germany", 85), europe);
		TreeItem<Area> russia = new TreeItem<Area>(new Area("Russia", 140), europe);
		
		TreeItem<Area> asia = new TreeItem<Area>(new Area("Asia", 3203), globe);
		TreeItem<Area> japan = new TreeItem<Area>(new Area("Japan", 203), asia);
		TreeItem<Area> china = new TreeItem<Area>(new Area("China", 1230), asia);
		TreeItem<Area> india = new TreeItem<Area>(new Area("India", 1130), asia);
		
	
		return ImmutableList.of(globe, asia, japan, china, india, europe, switzerland, germany, russia);
	}

	private void setColumWidthPercentage(DataLayer dataLayer) {
        dataLayer.setColumnPercentageSizing(true);
        dataLayer.setColumnWidthPercentageByPosition(0, 50);
        dataLayer.setColumnWidthPercentageByPosition(1, 50);
    }
}

And the main class to run the code:

package tryout.treelist;

import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;


public class TreeListMain {

	public static void main(String[] args) {
		Display display = new Display();
		Shell shell = new Shell(display);
		shell.setSize(300, 130);
		shell.setText("Tree List Example");
		shell.setLayout(new RowLayout());

		new SimpleTreePart().createComposite(shell);
		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		display.dispose();
	}
}

Hinterlasse einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert