📄 treelayoutalgorithm.java
字号:
TreeLayoutNode child, s;
int siblingOffest;
node.pos.translate(off_x + node.offset.x, off_y + node.offset.y);
child = node.child; //topmost child
if (child != null)
{
leftRightNodeLayout(child, node.pos.x, node.pos.y);
s = child.sibling;
siblingOffest = node.pos.y + child.offset.y;
while (s != null)
{
leftRightNodeLayout(s, node.pos.x + child.offset.x, siblingOffest);
siblingOffest += s.offset.y;
s = s.sibling;
}
}
}
protected void upDownNodeLayout(TreeLayoutNode node, int off_x, int off_y)
{
TreeLayoutNode child, s;
int siblingOffset;
node.pos.translate(off_x + (-1 * node.offset.y), off_y + node.offset.x);
child = node.child; //rightmost child
if (child != null)
{
upDownNodeLayout(child, node.pos.x, node.pos.y);
s = child.sibling;
siblingOffset = node.pos.x - child.offset.y;
while (s != null)
{
upDownNodeLayout(s, siblingOffset, node.pos.y + child.offset.x);
siblingOffset -= s.offset.y;
s = s.sibling;
}
}
}
public void perform(JGraph jgraph, boolean applyToAll, Properties configuration)
{
this.jgraph = jgraph;
Object[] selectedCells =
(applyToAll ? jgraph.getRoots() : jgraph.getSelectionCells());
CellView[] selectedCellViews =
jgraph.getGraphLayoutCache().getMapping(selectedCells);
dlgProgress.setVisible(true);
List roots = Arrays.asList(selectedCellViews);
// ---------------------------------------------------
// Addition from Sven Luzar
// ---------------------------------------------------
// roots = VertexViews + EdgeViews
// remove the Non Vertex Views to make the
// Algorithm runnable
for (int i = roots.size() - 1; i >= 0; i--){
Object o = roots.get(i);
if (!(o instanceof VertexView)){
roots.remove(i);
}
}
// ---------------------------------------------------
buildLayoutHelperTree(roots);
layoutTrees(roots);
display(roots);
dlgProgress.setVisible(false);
}
protected List getChildren(VertexView node)
{
ArrayList children = new ArrayList();
Object vertex = node.getCell();
GraphModel model = jgraph.getModel();
int portCount = model.getChildCount(vertex);
// iterate any NodePort
for (int i = 0; i < portCount; i++)
{
Object port = model.getChild(vertex, i);
// iterate any Edge in the port
Iterator itrEdges = model.edges(port);
while (itrEdges.hasNext())
{
Object edge = itrEdges.next();
// if the Edge is a forward edge we should follow this edge
if (port == model.getSource(edge))
{
Object targetPort = model.getTarget(edge);
Object targetVertex = model.getParent(targetPort);
VertexView targetVertexView =
(VertexView) jgraph.getGraphLayoutCache().getMapping(
targetVertex,
false);
children.add(targetVertexView);
}
}
}
return children;
}
protected void layoutTrees(Collection roots)
{
for (Iterator iterator = roots.iterator(); iterator.hasNext();)
{
VertexView view = (VertexView) iterator.next();
TreeLayoutNode root = getTreeLayoutNode(view);
// kick off Moen's algorithm
layout(root);
Point rootPos = view.getBounds().getLocation();
switch (orientation)
{
case LEFT_TO_RIGHT:
leftRightNodeLayout(root, rootPos.x, rootPos.y);
break;
case UP_TO_DOWN:
upDownNodeLayout(root, rootPos.x, rootPos.y);
break;
default:
leftRightNodeLayout(root, rootPos.x, rootPos.y);
}
}
}
protected void buildLayoutHelperTree(Collection roots)
{
for (Iterator iterator = roots.iterator(); iterator.hasNext();)
{
VertexView vv = (VertexView) iterator.next();
decorateNode(vv);
}
}
protected void decorateNode(VertexView node)
{
List cl = getChildren(node);
TreeLayoutNode parent = getTreeLayoutNode(node);
if (cl.size() > 0)
{
//Decorate children with Moen's nodes, parent has a reference
//to a first child only. Each child has a reference to a parent
//and possible next sibling
for (int i = 0; i < cl.size(); i++)
{
VertexView currentChild = (VertexView) cl.get(i);
TreeLayoutNode cln = getTreeLayoutNode(currentChild);
if (i == 0)
{
parent.child = cln;
}
else
{
VertexView previousChild = (VertexView) cl.get(i - 1);
TreeLayoutNode pln = getTreeLayoutNode(previousChild);
pln.sibling = cln;
}
cln.parent = parent;
decorateNode(currentChild);
}
}
}
protected TreeLayoutNode getTreeLayoutNode(VertexView view)
{
return getTreeLayoutNode(view, true);
}
protected TreeLayoutNode getTreeLayoutNode(VertexView view, boolean createIfNotPresent)
{
TreeLayoutNode decor = (TreeLayoutNode) view.getAttributes().get(CELL_WRAPPER);
if (decor == null && createIfNotPresent)
{
TreeLayoutNode n = new TreeLayoutNode(view);
view.getAttributes().put(CELL_WRAPPER, n);
return n;
}
else
{
return decor;
}
}
protected void display(Collection roots)
{
for (Iterator iterator = roots.iterator(); iterator.hasNext();)
{
VertexView vertexView = (VertexView) iterator.next();
displayHelper(vertexView);
}
}
protected void displayHelper(VertexView view)
{
TreeLayoutNode node = getTreeLayoutNode(view);
Object cell = view.getCell();
Map attributes =
GraphConstants.createAttributes(
cell,
GraphConstants.BOUNDS,
new Rectangle(node.pos, new Dimension(node.width, node.height)));
jgraph.getGraphLayoutCache().edit(attributes, null, null, null);
List c = getChildren(view);
for (Iterator iterator = c.iterator(); iterator.hasNext();)
{
VertexView vertexView = (VertexView) iterator.next();
displayHelper(vertexView);
}
view.getAttributes().remove(CELL_WRAPPER);
}
private class TreeLayoutNode
{
TreeLayoutNode parent, child, sibling;
final int width;
final int height;
final int border;
final Point pos;
final Point offset;
Polygon contour;
public TreeLayoutNode(VertexView node)
{
width = (int) node.getBounds().getWidth();
height = (int) node.getBounds().getHeight();
border = 5;
pos = new Point();
offset = new Point();
contour = new Polygon();
}
}
private static class Polygon
{
PolyLine lower_head, lower_tail;
PolyLine upper_head, upper_tail;
}
private static class PolyLine
{
final int dx;
final int dy;
PolyLine link;
PolyLine(int dx, int dy, PolyLine link)
{
this.dx = dx;
this.dy = dy;
this.link = link;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -