在Canvas中布置大量draw2d小部件

时间:2013-06-17 10:50:45

标签: java layout swt paint draw2d

我们在单个Canvas中处理大量Draw2d数字时遇到了问题。我们正在构建节点树,在父节点和子节点之间使用Connections。画布中的数字大小为10000(只是“节点”数字,还有另外10000个“连接”数字,我不算数。)

我在图片中附加了我们的一个图表的一部分:

enter image description here

问题是:树中的节点可以折叠或展开。当树中的节点数量为1000-2000时,则会立即进行折叠/展开。但是,当节点数量增加时,折叠/展开任何特定节点需要花费越来越多的时间,这很令人恼火。

我已经编写了一些示例代码,以查看问题是否与我们的代码有关,或者,draw2d性能通常随着更多数量的小部件而降低。示例应用程序中存在同样的问题,这表明我们可能必须在draw2d代码库本身内进行一些优化。我在Eclipse中创建了一个 View 来演示。下面附有相同的代码。

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() {

    }
}

尝试展开/折叠视图中的数字(通过单击“x”或“&gt;”按钮),这需要时间(不会立即发生)。任何人都可以提供一些关于如何解决这个问题的指示吗?

1 个答案:

答案 0 :(得分:3)

我明白了。我在这里发布它,以防任何人面临类似的性能问题。我在Eclipse论坛上收到了这方面的帮助。链接和完整代码在eclipse论坛提供: http://www.eclipse.org/forums/index.php/m/1064195/