我们面临一个问题,在单个 Canvas 中处理大量 Draw2d 图形。我们正在构建一个节点树,在父节点和子节点之间建立连接。画布中的图形数量约为 10000(仅“节点”图形,还有大约 10000 个“连接”图形,我没有计算在内)。
我在图像中附上了我们的一个图表的一部分:
问题是这样的:树中的节点可以折叠或展开。当树中的节点数量约为 1000-2000 时,会立即发生折叠/展开。但是,当节点数增加时,折叠/展开任何特定节点需要越来越多的时间,这很烦人。
我已经编写了一些示例代码来查看问题是否出在我们的代码上,或者随着小部件数量的增加,draw2d 的性能通常会下降。示例应用程序中也存在同样的问题,这表明我们可能需要在 draw2d 代码库本身中进行一些优化。我在 Eclipse 中制作了一个视图来证明这一点。下面附上相同的代码。
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”或“>”按钮),这需要时间(不会立即发生)。谁能提供一些关于如何解决这个问题的指示?