protected String encode() {
    String result = "points:" + segments.size();

    for (Iterator it = segments.iterator(); it.hasNext(); ) {
      CubicCurve2D next = (CubicCurve2D) it.next();

      result +=
          (":"
              + FigureUtil.printInt(next.getX1())
              + ":"
              + FigureUtil.printInt(next.getY1())
              + ":"
              + FigureUtil.printInt(next.getCtrlX1())
              + ":"
              + FigureUtil.printInt(next.getCtrlY1())
              + ":"
              + FigureUtil.printInt(next.getCtrlX2())
              + ":"
              + FigureUtil.printInt(next.getCtrlY2())
              + ":"
              + FigureUtil.printInt(next.getX2())
              + ":"
              + FigureUtil.printInt(next.getY2()));
    }

    result +=
        "|label:"
            + (label.center().x - textLocator.locate(this).x)
            + ":"
            + (label.center().y - textLocator.locate(this).y);

    result += "|factors:" + startFactor + ":" + endFactor;

    return result;
  }
  /**
   * Draws the label in addition to the spline. Performs drawing only if the connection is not
   * minimized or under the cursor.
   *
   * @see org.openbp.cockpit.modeler.figures.spline.PolySplineFigure#drawSpline(Graphics2D g2)
   */
  protected void drawSpline(Graphics2D g2) {
    if (isVisible() && !isMinimized()) {
      super.drawSpline(g2);

      label.draw(g2);
    }
  }
  /** @see CH.ifa.draw.framework.Figure#containsPoint(int x, int y) */
  public boolean containsPoint(int x, int y) {
    if (!isVisible() || isMinimized()) {
      // We won't react on user interaction if we are not visible or minimized.
      return false;
    }

    return label.containsPoint(x, y) || super.containsPoint(x, y);
  }
  /** Constructor. */
  public PolySplineConnection() {
    super();

    // Set the decorators
    // (start: none, end: arrow, animation: point)
    setEndDecoration(endDecoration);
    setAnimationDecoration(animationDecoration);

    textLocator = new SplineLocator();

    label = new MoveableTitleFigure();
    label.connect(this);
  }
  protected void decodeParameter(String parameter) {
    StringTokenizer inner = new StringTokenizer(parameter, ":");

    try {
      String name = inner.nextToken();

      if (name.equals("points")) {
        int x = Integer.parseInt(inner.nextToken());

        // We provide empty segments
        segments.clear();

        for (int i = 0; i < x; i++) {
          double x1 = Double.parseDouble(inner.nextToken());
          double y1 = Double.parseDouble(inner.nextToken());
          double x2 = Double.parseDouble(inner.nextToken());
          double y2 = Double.parseDouble(inner.nextToken());
          double x3 = Double.parseDouble(inner.nextToken());
          double y3 = Double.parseDouble(inner.nextToken());
          double x4 = Double.parseDouble(inner.nextToken());
          double y4 = Double.parseDouble(inner.nextToken());

          segments.add(new CubicCurve2D.Double(x1, y1, x2, y2, x3, y3, x4, y4));
        }
      } else if (name.equals("label")) {
        // Label position
        int x = Integer.parseInt(inner.nextToken());
        int y = Integer.parseInt(inner.nextToken());

        label.moveBy(x, y);
      } else if (name.equals("factors")) {
        startFactor = Double.parseDouble(inner.nextToken());
        endFactor = Double.parseDouble(inner.nextToken());
      }
    } catch (Exception e) {
    }
  }
 /** @see org.openbp.cockpit.modeler.figures.generic.UpdatableFigure#updateFigure() */
 public void updateFigure() {
   label.updateFigure();
 }
 /** @see CH.ifa.draw.framework.Figure#displayBox() */
 public Rectangle displayBox() {
   return super.displayBox().union(label.displayBox());
 }