Question

We are facing a problem, in handling a large number of Draw2d Figures, in a single Canvas. We are building a Tree of the nodes, with Connections between a parent, and a child node. The number of figures, in the canvas are of the order of 10000 (just the "Node" Figures, there are about another 10000 "Connection" figures too, that I am not counting).

I am attaching a part of one of our diagrams in Image:

enter image description here

The problem is this: the nodes in the tree can be collapsed or expanded. When the number of Nodes in the Tree are of the order of 1000-2000, then the Collapse/Expand takes place momentarily. However, when the node count goes higher, it takes more and more time to Collapse/Expand any particular node, which is irritating.

I have written some sample code to see, if the problem is with our code, or, that draw2d performance degrades in general with more number of widgets. The same problem exists within the sample application, which indicates that we may have to do some optimizations within the draw2d codebase itself. I made a View in Eclipse to demonstrate that. The code of the same is attached below.

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

import org.eclipse.draw2d.Cursors;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.FigureCanvas;
import org.eclipse.draw2d.GridData;
import org.eclipse.draw2d.GridLayout;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.LineBorder;
import org.eclipse.draw2d.MouseEvent;
import org.eclipse.draw2d.MouseListener;
import org.eclipse.draw2d.Panel;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;

public class View extends ViewPart {
    public static final String ID = "GridLayoutTest.view";

    /**
     * This is a callback that will allow us to create the viewer and initialize
     * it.
     */
    public void createPartControl(Composite parent) {
        Composite composite = new Composite(parent, SWT.NONE);
        composite.setLayout(new FillLayout());
        FigureCanvas canvas = new FigureCanvas(composite);
        Figure baseFigure = new Figure();
        baseFigure.setLayoutManager(new GridLayout(3, true));
        Panel contentPanel = new Panel();
        contentPanel.setLayoutManager(new GridLayout(1, true));
        baseFigure.add(new Figure());
        baseFigure.add(contentPanel);
        baseFigure.add(new Figure());
        fillContents(contentPanel);
        canvas.setContents(baseFigure);
    }

    private void fillContents(Panel contentPanel) {
        int margin;
        String text;
        CollapsibleFigure prevParent = null;
        for(int i = 1; i <= 2500; i++) {
            if(i%5 == 1) {
                text = "Parent " + (i/5 + 1);
                margin = 50;
                prevParent = new CollapsibleFigure(contentPanel, text, margin);
            } else {
                text = "Child " + (i%5 - 1);
                margin = 100;
                CollapsibleFigure child = new CollapsibleFigure(contentPanel, text, margin);
                prevParent.addChild(child);
            }
        }

        for(int i = 2501; i <= 7500; i++) {
            if(i == 2501) {
                text = "Parent " + (i/5 + 1);
                margin = 50;
                prevParent = new CollapsibleFigure(contentPanel, text, margin);
            } else {
                text = "Child " + (i - 2501);
                margin = 100;
                CollapsibleFigure child = new CollapsibleFigure(contentPanel, text, margin);
                prevParent.addChild(child);
            }
        }

        for(int i = 7501; i <= 10000; i++) {
            if(i%5 == 1) {
                text = "Parent " + (i/5 + 1);
                margin = 50;
                prevParent = new CollapsibleFigure(contentPanel, text, margin);
            } else {
                text = "Child " + (i%5 - 1);
                margin = 100;
                CollapsibleFigure child = new CollapsibleFigure(contentPanel, text, margin);
                prevParent.addChild(child);
            }
        }
    }

    private class CollapsibleFigure extends Panel {
        private List<CollapsibleFigure> children; 

        private int margin;

        private CollapsibleFigure(Panel contentPanel, String text, int margin) {
            children = new ArrayList<CollapsibleFigure>();
            setBorder(new LineBorder(2));
            setBackgroundColor(new Color(null, 255, 255, 255));
            this.margin = margin;
            GridLayout layout = new GridLayout(2, false);
            GridData layoutData;
            setLayoutManager(layout);
            Label label;
            label = new Label();
            label.setText("x");
            add(label);
            label.setCursor(Cursors.HAND);
            label.addMouseListener(new MouseListener.Stub() {
                public void mouseReleased(MouseEvent e) {
                    Label label = (Label) e.getSource();
                    if(label.getText().equals("x"))
                        collapseChildren();
                    else
                        showChildren();
                }
            });
            label = new Label();
            label.setText(text);
            add(label);
            layoutData = new GridData(SWT.CENTER, SWT.CENTER, true, true);
            layout.setConstraint(label, layoutData);
            label = new Label();
            label.setText("Some Content");
            add(label);
            layoutData = new GridData(SWT.CENTER, SWT.CENTER, true, true);
            layoutData.horizontalSpan = 2;
            layout.setConstraint(label, layoutData);
            contentPanel.add(this);
            layoutData = new GridData(SWT.BEGINNING, SWT.CENTER, false, true);
            layoutData.horizontalIndent = margin;
            contentPanel.getLayoutManager().setConstraint(this, layoutData);
        }

        private void addChild(CollapsibleFigure child) {
            children.add(child);
        }

        private void collapseChildren() {
            Panel contentPanel = (Panel) getParent();
            for(CollapsibleFigure child : children)
                contentPanel.remove(child);
            ((Label)(getChildren().get(0))).setText(">");
        }

        private void showChildren() {
            Panel contentPanel = (Panel) getParent();
            int index = contentPanel.getChildren().indexOf(this) + 1;
            for(CollapsibleFigure child : children) {
                contentPanel.add(child, index);
                GridData layoutData = new GridData(SWT.BEGINNING, SWT.CENTER, false, true);
                layoutData.horizontalIndent = margin + 50;
                contentPanel.getLayoutManager().setConstraint(child, layoutData);
                index++;
            }
            ((Label)(getChildren().get(0))).setText("x");
        }
    }

    @Override
    public void setFocus() {

    }
}

Try to expand/collapse figures in the View (by clicking on the "x" or ">" buttons), it'll take time (won't occur instantaneously). Can anyone please provide some pointers as to how this problem can be solved?

Was it helpful?

Solution

I figured it out. I am posting it here in case anyone faces similar performance issues. I received help in this regard on the Eclipse forum. The link, and full code is provided at the eclipse forum here: http://www.eclipse.org/forums/index.php/m/1064195/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top