Ejemplo 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;
  }
Ejemplo n.º 3
0
  /**
   * Function: check
   *
   * <p>Checks the multiplicity for the given arguments and returns the error for the given
   * connection or null if the multiplicity does not apply.
   *
   * <p>Parameters:
   *
   * <p>graph - Reference to the enclosing graph instance. edge - Cell that represents the edge to
   * validate. source - Cell that represents the source terminal. target - Cell that represents the
   * target terminal. sourceOut - Number of outgoing edges from the source terminal. targetIn -
   * Number of incoming edges for the target terminal.
   */
  public String check(
      mxGraph graph, Object edge, Object source, Object target, int sourceOut, int targetIn) {
    mxIGraphModel model = graph.getModel();
    Object sourceValue = model.getValue(source);
    Object targetValue = model.getValue(target);
    StringBuffer error = new StringBuffer();

    if ((this.source && checkType(graph, sourceValue, type, attr, value))
        || (!this.source && checkType(graph, targetValue, type, attr, value))) {
      if (!isUnlimited()) {
        int m = getMaxValue();

        if (m == 0 || (this.source && sourceOut >= m) || (!this.source && targetIn >= m)) {
          error.append(countError + "\n");
        }
      }

      if (validNeighbors != null) {
        boolean isValid = !validNeighborsAllowed;
        Iterator<String> it = validNeighbors.iterator();

        while (it.hasNext()) {
          String tmp = it.next();

          if (this.source && checkType(graph, targetValue, tmp)) {
            isValid = validNeighborsAllowed;
            break;
          } else if (!this.source && checkType(graph, sourceValue, tmp)) {
            isValid = validNeighborsAllowed;
            break;
          }
        }

        if (!isValid) {
          error.append(typeError + "\n");
        }
      }
    }

    return (error.length() > 0) ? error.toString() : null;
  }
Ejemplo n.º 4
0
  /** Checks the type of the given value. */
  public boolean checkNeighbors(mxGraph graph, Object edge, Object source, Object target) {
    mxIGraphModel model = graph.getModel();
    Object sourceValue = model.getValue(source);
    Object targetValue = model.getValue(target);
    boolean isValid = !validNeighborsAllowed;
    Iterator<String> it = validNeighbors.iterator();

    while (it.hasNext()) {
      String tmp = it.next();

      if (this.source && checkType(graph, targetValue, tmp)) {
        isValid = validNeighborsAllowed;
        break;
      } else if (!this.source && checkType(graph, sourceValue, tmp)) {
        isValid = validNeighborsAllowed;
        break;
      }
    }

    return isValid;
  }
Ejemplo n.º 5
0
  public CellSelector(final mxGraphComponent gc, final boolean withScroll) {
    this.gc = gc;
    this.graph = gc.getGraph();
    this.view = graph.getView();
    this.model = graph.getModel();
    this.withScroll = withScroll;
    mxIEventListener updateListener =
        new mxIEventListener() {
          @Override
          public void invoke(Object sender, mxEventObject evt) {
            // System.out.println("Updating marker because of event: "+evt.getName()+" change:
            // "+evt.getProperties());

            Object changes = evt.getProperty("changes");
            if (changes != null && changes instanceof List) {
              for (Object change : ((List) changes)) {
                if (change != null && change instanceof mxStyleChange) {
                  Object cell = ((mxStyleChange) change).getCell();
                  mxCellState state = view.getState(cell, false);
                  if (currentSelectedCells.containsKey(cell)) {
                    mxCellMarker thisCellSelector = currentSelectedCells.get(cell);
                    thisCellSelector.unmark();
                    thisCellSelector.process(
                        state,
                        thisCellSelector.getMarkerColor(null, state, selectSetAsValid),
                        selectSetAsValid);
                    thisCellSelector.mark();
                  }
                }
              }
            }
            for (Entry<mxCell, mxCellMarker> el : currentSelectedCells.entrySet()) {
              el.getValue().unmark();
              el.getValue().mark();
            }
          }
        };

    view.addListener(mxEvent.SCALE_AND_TRANSLATE, updateListener);
    view.addListener(mxEvent.SCALE, updateListener);
    view.addListener(mxEvent.TRANSLATE, updateListener);
    model.addListener(mxEvent.CHANGE, updateListener);
  }
  /**
   * 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();
      }
    }
  }
Ejemplo n.º 7
0
  /**
   * This method is called when the user has created manually an edge in the graph, by dragging a
   * link between two spot cells. It checks whether the matching edge in the model exists, and tune
   * what should be done accordingly.
   *
   * @param cell the mxCell of the edge that has been manually created.
   */
  protected void addEdgeManually(mxCell cell) {
    if (cell.isEdge()) {
      final mxIGraphModel graphModel = graph.getModel();
      cell.setValue("New");
      model.beginUpdate();
      graphModel.beginUpdate();
      try {

        Spot source = graph.getSpotFor(cell.getSource());
        Spot target = graph.getSpotFor(cell.getTarget());

        if (DEBUG) {
          System.out.println(
              "[TrackScheme] #addEdgeManually: edge is between 2 spots belonging to the same frame. Removing it.");
          System.out.println(
              "[TrackScheme] #addEdgeManually: adding edge between source "
                  + source
                  + " at frame "
                  + source.getFeature(Spot.FRAME).intValue()
                  + " and target "
                  + target
                  + " at frame "
                  + target.getFeature(Spot.FRAME).intValue());
        }

        if (Spot.frameComparator.compare(source, target) == 0) {
          // Prevent adding edges between spots that belong to the same frame

          if (DEBUG) {
            System.out.println(
                "[TrackScheme] addEdgeManually: edge is between 2 spots belonging to the same frame. Removing it.");
          }
          graph.removeCells(new Object[] {cell});

        } else {
          // We can add it to the model

          // Put them right in order: since we use a oriented graph,
          // we want the source spot to precede in time.
          if (Spot.frameComparator.compare(source, target) > 0) {

            if (DEBUG) {
              System.out.println(
                  "[TrackScheme] #addEdgeManually: Source "
                      + source
                      + " succeed target "
                      + target
                      + ". Inverting edge direction.");
            }

            Spot tmp = source;
            source = target;
            target = tmp;
          }
          // We add a new jGraphT edge to the underlying model, if it does not exist yet.
          DefaultWeightedEdge edge = model.getTrackModel().getEdge(source, target);
          if (null == edge) {
            edge = model.addEdge(source, target, -1);
            if (DEBUG) {
              System.out.println(
                  "[TrackScheme] #addEdgeManually: Creating new edge: " + edge + ".");
            }
          } else {
            // Ah. There was an existing edge in the model we were trying to re-add there, from the
            // graph.
            // We remove the graph edge we have added,
            if (DEBUG) {
              System.out.println("[TrackScheme] #addEdgeManually: Edge pre-existed. Retrieve it.");
            }
            graph.removeCells(new Object[] {cell});
            // And re-create a graph edge from the model edge.
            cell = graph.addJGraphTEdge(edge);
            cell.setValue(String.format("%.1f", model.getTrackModel().getEdgeWeight(edge)));
            // We also need now to check if the edge belonged to a visible track. If not,
            // we make it visible.
            int ID = model.getTrackModel().trackIDOf(edge);
            // This will work, because track indices will be reprocessed only after the
            // graphModel.endUpdate()
            // reaches 0. So now, it's like we are dealing with the track indices priori to
            // modification.
            if (model.getTrackModel().isVisible(ID)) {
              if (DEBUG) {
                System.out.println(
                    "[TrackScheme] #addEdgeManually: Track was visible. Do nothing.");
              }
            } else {
              if (DEBUG) {
                System.out.println(
                    "[TrackScheme] #addEdgeManually: Track was invisible. Make it visible.");
              }
              importTrack(ID);
            }
          }
          graph.mapEdgeToCell(edge, cell);
        }

      } finally {
        graphModel.endUpdate();
        model.endUpdate();
        selectionModel.clearEdgeSelection();
      }
    }
  }
Ejemplo n.º 8
0
  /** Populate a fresh mxGraph data model from a JGraph data model */
  public void syncMx(JGraph inputGraph) {
    if (inputGraph != null) {
      jgraph = inputGraph;
    } else {
      return;
    }

    GraphModel jModel = jgraph.getModel();

    mxIGraphModel mxModel = null;

    if (graph == null) {
      mxModel = new mxGraphModel();
      this.graph = new mxGraph(mxModel);
    }

    mxModel = graph.getModel();
    mxModel.beginUpdate();
    try {
      int rootCount = jModel.getRootCount();

      // Insert everything in mx in the same order and
      // hierarchy as jgraph
      for (int i = 0; i < rootCount; i++) {
        Object cell = jModel.getRootAt(i);

        if (cell != null) {
          insertCell(cell, graph.getDefaultParent());
        }
      }

      // Edges are inserted without source and targets,
      // since the vertices may not exist at insertion
      // time
      if (edges != null && vertices != null) {
        Set<Object> keys = edges.keySet();

        for (Object edge : keys) {
          Object source = jModel.getSource(edge);
          Object target = jModel.getTarget(edge);

          Object mxEdge = edges.get(edge);

          if (facade != null) {
            source = facade.getSource(edge);
            target = facade.getTarget(edge);
          }

          if (source != null) {
            source = vertices.get(source);
            graph.connectCell(mxEdge, source, true);
          }

          if (target != null) {
            target = vertices.get(target);
            graph.connectCell(mxEdge, target, false);
          }
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      mxModel.endUpdate();
    }
  }