示例#1
0
 private boolean nodeOverlapsRectangle(Node node, Rectangle r2) {
   Rectangle r1 = node.getBounds();
   return (r1.x <= (r2.x + r2.width))
       && ((r1.x + r1.width) >= r2.x)
       && (r1.y <= (r2.y + r2.height))
       && ((r1.y + r1.height) >= r2.y);
 }
示例#2
0
 private Divider dividerAt(Node root, int x, int y) {
   if (root instanceof Divider) {
     Divider divider = (Divider) root;
     return (divider.getBounds().contains(x, y)) ? divider : null;
   } else if (root instanceof Split) {
     Split split = (Split) root;
     for (Node child : split.getChildren()) {
       if (child.getBounds().contains(x, y)) return dividerAt(child, x, y);
     }
   }
   return null;
 }
示例#3
0
 private void minimizeSplitBounds(Split split, Rectangle bounds) {
   Rectangle splitBounds = new Rectangle(bounds.x, bounds.y, 0, 0);
   List<Node> splitChildren = split.getChildren();
   Node lastChild = splitChildren.get(splitChildren.size() - 1);
   Rectangle lastChildBounds = lastChild.getBounds();
   if (split.isRowLayout()) {
     int lastChildMaxX = lastChildBounds.x + lastChildBounds.width;
     splitBounds.add(lastChildMaxX, bounds.y + bounds.height);
   } else {
     int lastChildMaxY = lastChildBounds.y + lastChildBounds.height;
     splitBounds.add(bounds.x + bounds.width, lastChildMaxY);
   }
   split.setBounds(splitBounds);
 }
 private void drawCrosses(Graphics g, List<Node> nodes, Rectangle clip) {
   Graphics2D g2 = (Graphics2D) g;
   Stroke oldStroke = g2.getStroke();
   Stroke stroke = new BasicStroke(DefaultRenderConstants.DEFAULT_RED_CROSS_WIDTH);
   g2.setStroke(stroke);
   Paint oldPaint = g2.getPaint();
   g2.setColor(Color.RED);
   for (Node node : nodes) {
     Rectangle r = node.getBounds();
     if (!clip.intersects(r)) continue;
     g2.drawLine(r.x, r.y, r.x + r.width, r.y + r.height);
     g2.drawLine(r.x, r.y + r.height, r.x + r.width, r.y);
   }
   g2.setStroke(oldStroke);
   g2.setPaint(oldPaint);
 }
 private void drawComponents(
     Graphics g, List<Renderable> comps, Rectangle clip, boolean drawEdgeFirst) {
   List<HyperEdge> edges = new ArrayList<HyperEdge>();
   for (Renderable obj : comps) {
     if (obj instanceof HyperEdge) edges.add((HyperEdge) obj);
   }
   if (drawEdgeFirst) {
     // Draw HyperEdges
     for (HyperEdge reaction : edges) {
       // Have to validate connect nodes first in case empty bounds
       List<Node> nodes = reaction.getConnectedNodes();
       for (Node node : nodes) node.validateBounds(g);
       reaction.validateConnectInfo();
       if (clip.intersects(reaction.getBounds())) reaction.render(g);
     }
   }
   // Draw complexes now
   drawComplexes(comps, clip, g);
   for (Renderable obj : comps) {
     if (obj instanceof RenderableCompartment
         || obj instanceof RenderableComplex
         || obj instanceof RenderablePathway) continue; // Escape it. It should be drawn earlier.
     if (obj instanceof Node) {
       Node node = (Node) obj;
       if (getHidePrivateNote() && (node instanceof Note) && ((Note) node).isPrivate()) continue;
       node.validateBounds(g);
       if (clip.intersects(node.getBounds())) node.render(g);
     }
   }
   if (!drawEdgeFirst) {
     // Draw HyperEdges
     for (HyperEdge reaction : edges) {
       reaction.validateConnectInfo();
       if (clip.intersects(reaction.getBounds())) reaction.render(g);
     }
   }
 }
示例#6
0
  private void layoutGrow(Split split, Rectangle bounds) {
    Rectangle splitBounds = split.getBounds();
    ListIterator<Node> splitChildren = split.getChildren().listIterator();
    Node lastWeightedChild = split.lastWeightedChild();

    /* Layout the Split's child Nodes' along the X axis.  The bounds
     * of each child will have the same y coordinate and height as the
     * layoutGrow() bounds argument.  Extra width is allocated to the
     * to each child with a non-zero weight:
     *     newWidth = currentWidth + (extraWidth * splitChild.getWeight())
     * Any extraWidth "left over" (that's availableWidth in the loop
     * below) is given to the last child.  Note that Dividers always
     * have a weight of zero, and they're never the last child.
     */
    if (split.isRowLayout()) {
      double x = bounds.getX();
      double extraWidth = bounds.getWidth() - splitBounds.getWidth();
      double availableWidth = extraWidth;

      while (splitChildren.hasNext()) {
        Node splitChild = splitChildren.next();
        Rectangle splitChildBounds = splitChild.getBounds();
        double splitChildWeight = splitChild.getWeight();

        if (!splitChildren.hasNext()) {
          double newWidth = bounds.getMaxX() - x;
          Rectangle newSplitChildBounds = boundsWithXandWidth(bounds, x, newWidth);
          layout2(splitChild, newSplitChildBounds);
        } else if ((availableWidth > 0.0) && (splitChildWeight > 0.0)) {
          double allocatedWidth =
              (splitChild.equals(lastWeightedChild))
                  ? availableWidth
                  : Math.rint(splitChildWeight * extraWidth);
          double newWidth = splitChildBounds.getWidth() + allocatedWidth;
          Rectangle newSplitChildBounds = boundsWithXandWidth(bounds, x, newWidth);
          layout2(splitChild, newSplitChildBounds);
          availableWidth -= allocatedWidth;
        } else {
          double existingWidth = splitChildBounds.getWidth();
          Rectangle newSplitChildBounds = boundsWithXandWidth(bounds, x, existingWidth);
          layout2(splitChild, newSplitChildBounds);
        }
        x = splitChild.getBounds().getMaxX();
      }
    }

    /* Layout the Split's child Nodes' along the Y axis.  The bounds
     * of each child will have the same x coordinate and width as the
     * layoutGrow() bounds argument.  Extra height is allocated to the
     * to each child with a non-zero weight:
     *     newHeight = currentHeight + (extraHeight * splitChild.getWeight())
     * Any extraHeight "left over" (that's availableHeight in the loop
     * below) is given to the last child.  Note that Dividers always
     * have a weight of zero, and they're never the last child.
     */
    else {
      double y = bounds.getY();
      double extraHeight = bounds.getMaxY() - splitBounds.getHeight();
      double availableHeight = extraHeight;

      while (splitChildren.hasNext()) {
        Node splitChild = splitChildren.next();
        Rectangle splitChildBounds = splitChild.getBounds();
        double splitChildWeight = splitChild.getWeight();

        if (!splitChildren.hasNext()) {
          double newHeight = bounds.getMaxY() - y;
          Rectangle newSplitChildBounds = boundsWithYandHeight(bounds, y, newHeight);
          layout2(splitChild, newSplitChildBounds);
        } else if ((availableHeight > 0.0) && (splitChildWeight > 0.0)) {
          double allocatedHeight =
              (splitChild.equals(lastWeightedChild))
                  ? availableHeight
                  : Math.rint(splitChildWeight * extraHeight);
          double newHeight = splitChildBounds.getHeight() + allocatedHeight;
          Rectangle newSplitChildBounds = boundsWithYandHeight(bounds, y, newHeight);
          layout2(splitChild, newSplitChildBounds);
          availableHeight -= allocatedHeight;
        } else {
          double existingHeight = splitChildBounds.getHeight();
          Rectangle newSplitChildBounds = boundsWithYandHeight(bounds, y, existingHeight);
          layout2(splitChild, newSplitChildBounds);
        }
        y = splitChild.getBounds().getMaxY();
      }
    }
  }
示例#7
0
  private void layoutShrink(Split split, Rectangle bounds) {
    Rectangle splitBounds = split.getBounds();
    ListIterator<Node> splitChildren = split.getChildren().listIterator();

    if (split.isRowLayout()) {
      int totalWidth = 0; // sum of the children's widths
      int minWeightedWidth = 0; // sum of the weighted childrens' min widths
      int totalWeightedWidth = 0; // sum of the weighted childrens' widths
      for (Node splitChild : split.getChildren()) {
        int nodeWidth = splitChild.getBounds().width;
        int nodeMinWidth = Math.min(nodeWidth, minimumNodeSize(splitChild).width);
        totalWidth += nodeWidth;
        if (splitChild.getWeight() > 0.0) {
          minWeightedWidth += nodeMinWidth;
          totalWeightedWidth += nodeWidth;
        }
      }

      double x = bounds.getX();
      double extraWidth = splitBounds.getWidth() - bounds.getWidth();
      double availableWidth = extraWidth;
      boolean onlyShrinkWeightedComponents = (totalWeightedWidth - minWeightedWidth) > extraWidth;

      while (splitChildren.hasNext()) {
        Node splitChild = splitChildren.next();
        Rectangle splitChildBounds = splitChild.getBounds();
        double minSplitChildWidth = minimumNodeSize(splitChild).getWidth();
        double splitChildWeight =
            (onlyShrinkWeightedComponents)
                ? splitChild.getWeight()
                : (splitChildBounds.getWidth() / totalWidth);

        if (!splitChildren.hasNext()) {
          double newWidth = Math.max(minSplitChildWidth, bounds.getMaxX() - x);
          Rectangle newSplitChildBounds = boundsWithXandWidth(bounds, x, newWidth);
          layout2(splitChild, newSplitChildBounds);
        } else if ((availableWidth > 0.0) && (splitChildWeight > 0.0)) {
          double allocatedWidth = Math.rint(splitChildWeight * extraWidth);
          double oldWidth = splitChildBounds.getWidth();
          double newWidth = Math.max(minSplitChildWidth, oldWidth - allocatedWidth);
          Rectangle newSplitChildBounds = boundsWithXandWidth(bounds, x, newWidth);
          layout2(splitChild, newSplitChildBounds);
          availableWidth -= (oldWidth - splitChild.getBounds().getWidth());
        } else {
          double existingWidth = splitChildBounds.getWidth();
          Rectangle newSplitChildBounds = boundsWithXandWidth(bounds, x, existingWidth);
          layout2(splitChild, newSplitChildBounds);
        }
        x = splitChild.getBounds().getMaxX();
      }
    } else {
      int totalHeight = 0; // sum of the children's heights
      int minWeightedHeight = 0; // sum of the weighted childrens' min heights
      int totalWeightedHeight = 0; // sum of the weighted childrens' heights
      for (Node splitChild : split.getChildren()) {
        int nodeHeight = splitChild.getBounds().height;
        int nodeMinHeight = Math.min(nodeHeight, minimumNodeSize(splitChild).height);
        totalHeight += nodeHeight;
        if (splitChild.getWeight() > 0.0) {
          minWeightedHeight += nodeMinHeight;
          totalWeightedHeight += nodeHeight;
        }
      }

      double y = bounds.getY();
      double extraHeight = splitBounds.getHeight() - bounds.getHeight();
      double availableHeight = extraHeight;
      boolean onlyShrinkWeightedComponents =
          (totalWeightedHeight - minWeightedHeight) > extraHeight;

      while (splitChildren.hasNext()) {
        Node splitChild = splitChildren.next();
        Rectangle splitChildBounds = splitChild.getBounds();
        double minSplitChildHeight = minimumNodeSize(splitChild).getHeight();
        double splitChildWeight =
            (onlyShrinkWeightedComponents)
                ? splitChild.getWeight()
                : (splitChildBounds.getHeight() / totalHeight);

        if (!splitChildren.hasNext()) {
          double oldHeight = splitChildBounds.getHeight();
          double newHeight = Math.max(minSplitChildHeight, bounds.getMaxY() - y);
          Rectangle newSplitChildBounds = boundsWithYandHeight(bounds, y, newHeight);
          layout2(splitChild, newSplitChildBounds);
          availableHeight -= (oldHeight - splitChild.getBounds().getHeight());
        } else if ((availableHeight > 0.0) && (splitChildWeight > 0.0)) {
          double allocatedHeight = Math.rint(splitChildWeight * extraHeight);
          double oldHeight = splitChildBounds.getHeight();
          double newHeight = Math.max(minSplitChildHeight, oldHeight - allocatedHeight);
          Rectangle newSplitChildBounds = boundsWithYandHeight(bounds, y, newHeight);
          layout2(splitChild, newSplitChildBounds);
          availableHeight -= (oldHeight - splitChild.getBounds().getHeight());
        } else {
          double existingHeight = splitChildBounds.getHeight();
          Rectangle newSplitChildBounds = boundsWithYandHeight(bounds, y, existingHeight);
          layout2(splitChild, newSplitChildBounds);
        }
        y = splitChild.getBounds().getMaxY();
      }
    }

    /* The bounds of the Split node root are set to be
     * big enough to contain all of its children. Since
     * Leaf children can't be reduced below their
     * (corresponding java.awt.Component) minimum sizes,
     * the size of the Split's bounds maybe be larger than
     * the bounds we were asked to fit within.
     */
    minimizeSplitBounds(split, bounds);
  }
 /** Automatically layout this RenderableComplex. */
 public void layout() {
   if (hideComponents) {
     return; // Don't do layout for hiding components
   }
   List list = getComponents();
   if (list == null || list.size() == 0) return;
   int size = list.size();
   int c = (int) Math.ceil(Math.sqrt(size));
   Node rs[][] = new Node[c][c];
   int index = 0;
   // Distribute
   for (int i = 0; i < c && index < size; i++) { // Row
     for (int j = 0; j < c && index < size; j++) { // Col
       rs[i][j] = (Node) list.get(index);
       index++;
     }
   }
   // Assign positions
   // Original position
   int x = position.x;
   int y = position.y;
   Dimension layerSize = new Dimension();
   boolean isDone = false;
   Node r = null;
   Rectangle bounds = null;
   int dx = 0;
   int x0 = 0;
   int y0 = 0;
   for (int i = 0; i < c && !isDone; i++) { // Row
     // Get the center for each layer
     layerSize.width = 0;
     layerSize.height = 0;
     for (int j = 0; j < c; j++) { // Col
       if (rs[i][j] == null) {
         isDone = true;
         break;
       }
       r = rs[i][j];
       if (r.getStoiBounds() != null) {
         layerSize.width += r.getStoiBounds().width;
       }
       if (r.getBounds() != null) {
         layerSize.width += r.getBounds().width;
         if (r.getBounds().height > layerSize.height) layerSize.height = r.getBounds().height;
       } else {
         layerSize.width += Node.getNodeWidth();
         layerSize.height += 20; // arbitrarily
       }
     }
     if (layerSize.width == 0) // nothing is layered.
     break;
     // Assign positions to this layer.
     x = -layerSize.width / 2 + position.x;
     y += layerSize.height / 2;
     for (int j = 0; j < c; j++) {
       if (rs[i][j] == null) break;
       r = rs[i][j];
       // All are nodes
       dx = 0;
       if (r.getStoiBounds() != null) dx = r.getStoiBounds().width;
       if (r.getBounds() != null) dx += r.getBounds().width / 2;
       else dx += Node.getNodeWidth() / 2;
       x += dx;
       x0 = r.position.x;
       y0 = r.position.y;
       // Need to call move to change positions of components in subcomplexes.
       r.move(x - x0, y - y0);
       dx += 1; // A little cushion
       x += dx; // Move to the right end
     }
     y += layerSize.height / 2 + 2; // Make subunits look together
   }
   // Want to keep at the original position
   x0 = position.x;
   y0 = position.y;
   setBoundsFromComponents();
   dx = x0 - position.x;
   int dy = y0 - position.y;
   move(dx, dy);
   // Should not call the following method since it will invalidate the
   // layout results.
   invalidateTextBounds();
 }