Exemplo n.º 1
0
  /** Populate the stored JGraph 5 facade from the mxGraph data model. */
  public void syncJGraphFacade() {
    if (facade == null || graph == null) {
      return;
    }

    mxIGraphModel model = graph.getModel();

    if (vertices != null) {
      Set<Object> vertexKeys = vertices.keySet();
      for (Object vertex : vertexKeys) {
        Object mxVertex = vertices.get(vertex);
        mxGeometry geo = model.getGeometry(mxVertex);
        facade.setLocation(vertex, geo.getX(), geo.getY());
      }
    }

    if (edges != null) {
      Set<Object> edgeKeys = edges.keySet();
      for (Object edge : edgeKeys) {
        Object mxEdge = edges.get(edge);
        List<mxPoint> points = model.getGeometry(mxEdge).getPoints();

        if (points != null) {
          facade.setIntermediatePoints(edge, points);
        }
      }
    }
  }
  /**
   * Does a depth first search starting at the specified cell. Makes sure the specified swimlane is
   * never left by the algorithm.
   */
  protected TreeNode dfs(Object cell, Object parent, Set<Object> visited) {
    if (visited == null) {
      visited = new HashSet<Object>();
    }

    TreeNode node = null;

    if (cell != null && !visited.contains(cell) && !isVertexIgnored(cell)) {
      visited.add(cell);
      node = createNode(cell);

      mxIGraphModel model = graph.getModel();
      TreeNode prev = null;
      Object[] out = graph.getEdges(cell, parent, invert, !invert, false);

      for (int i = 0; i < out.length; i++) {
        Object edge = out[i];

        if (!isEdgeIgnored(edge)) {
          // Resets the points on the traversed edge
          if (resetEdges) {
            setEdgePoints(edge, null);
          }

          // Checks if terminal in same swimlane
          Object target = graph.getView().getVisibleTerminal(edge, invert);
          TreeNode tmp = dfs(target, parent, visited);

          if (tmp != null && model.getGeometry(target) != null) {
            if (prev == null) {
              node.child = tmp;
            } else {
              prev.next = tmp;
            }

            prev = tmp;
          }
        }
      }
    }

    return node;
  }
  /**
   * Implements <mxGraphLayout.execute>.
   *
   * <p>If the parent has any connected edges, then it is used as the root of the tree. Else,
   * <mxGraph.findTreeRoots> will be used to find a suitable root node within the set of children of
   * the given parent.
   */
  public void execute(Object parent, Object root) {
    mxIGraphModel model = graph.getModel();

    if (root == null) {
      // Takes the parent as the root if it has outgoing edges
      if (graph.getEdges(parent, model.getParent(parent), invert, !invert, false).length > 0) {
        root = parent;
      }

      // Tries to find a suitable root in the parent's
      // children
      else {
        List<Object> roots = graph.findTreeRoots(parent, true, invert);

        if (roots != null && roots.size() > 0) {
          for (int i = 0; i < roots.size(); i++) {
            if (!isVertexIgnored(roots.get(i))
                && graph.getEdges(roots.get(i), null, invert, !invert, false).length > 0) {
              root = roots.get(i);
              break;
            }
          }
        }
      }
    }

    if (root != null) {
      parent = model.getParent(root);
      model.beginUpdate();

      try {
        TreeNode node = dfs(root, parent, null);

        if (node != null) {
          layout(node);

          double x0 = graph.getGridSize();
          double y0 = x0;

          if (!moveTree || model.getParent(parent) == model.getRoot()) {
            mxGeometry g = model.getGeometry(root);

            if (g != null) {
              x0 = g.getX();
              y0 = g.getY();
            }
          }

          mxRectangle bounds = null;

          if (horizontal) {
            bounds = horizontalLayout(node, x0, y0, null);
          } else {
            bounds = verticalLayout(node, null, x0, y0, null);
          }

          if (bounds != null) {
            double dx = 0;
            double dy = 0;

            if (bounds.getX() < 0) {
              dx = Math.abs(x0 - bounds.getX());
            }

            if (bounds.getY() < 0) {
              dy = Math.abs(y0 - bounds.getY());
            }

            if (parent != null) {
              mxRectangle size = graph.getStartSize(parent);
              dx += size.getWidth();
              dy += size.getHeight();

              // Resize parent swimlane
              if (resizeParent && !graph.isCellCollapsed(parent)) {
                mxGeometry g = model.getGeometry(parent);

                if (g != null) {
                  double width = bounds.getWidth() + size.getWidth() - bounds.getX() + 2 * x0;
                  double height = bounds.getHeight() + size.getHeight() - bounds.getY() + 2 * y0;

                  g = (mxGeometry) g.clone();

                  if (g.getWidth() > width) {
                    dx += (g.getWidth() - width) / 2;
                  } else {
                    g.setWidth(width);
                  }

                  if (g.getHeight() > height) {
                    if (horizontal) {
                      dy += (g.getHeight() - height) / 2;
                    }
                  } else {
                    g.setHeight(height);
                  }

                  model.setGeometry(parent, g);
                }
              }
            }

            moveNode(node, dx, dy);
          }
        }
      } finally {
        model.endUpdate();
      }
    }
  }