Skip to content

Part 4: Tables and Trees


This tutorial is deprecated, and will be rewritten to account for JEB 4 API changes.

JEB Plugin Development Tutorial part 4/8

The interfaces ITextDocument, ITableDocument and ITreeDocument are designed to provide buffered data: data is not generated nor displayed entirely (which could lead to performance/memory problem). It is split into Parts (eg, ITableDocumentPart).

When implementing an IXxxDocument, you can choose to render the full model (for instance if the model is relatively small) or just one or more parts. A client requests as many parts as they see fit. Those indications are hints; ultimately, your plugin has the final say in how many parts it decides to return.

Now, let's check two types of documents that we haven't seen yet: Table and Tree.


For simple tables, you can use StaticTableDocument.

See below an example of a Table having 2 columns, and containing 2 rows.

private ITableDocument getStatisticsTable() {
    List<TableRow> rows = new ArrayList<>();
    rows.add(new TableRow(new Cell("Length"), new Cell(Integer.toString(root.getLength()))));
    rows.add(new TableRow(new Cell("Type"), new Cell(Integer.toString(root.getType()))));
    return new StaticTableDocument(Arrays.asList("Property", "Value"), rows);


Update the getFormatter() method accordingly to include new Documents (use the IUnitFormatter.addPresentation() method). The result should look like:


For simple trees, you can use StaticTreeDocument.

See below an example of a Tree that displays all function parameters.

private ITreeDocument getFunctionsTree() {
    List<Node> treeRoot = new ArrayList<>();
    try {
        if(functions != null) {
            for(FunctionNode function: functions) {
    catch(Exception e) {
    return new StaticTreeDocument(treeRoot);

private Node buildFunctionNode(FunctionNode function) {
    Node functionNode = new Node(function.getName());
    if(function.getParamCount() > 0) {
        for(AstNode var: function.getParams()) {
            functionNode.addChild(new Node(((Name)var).getIdentifier()));
    return functionNode;