Package com.mxgraph.canvas

Source Code of com.mxgraph.canvas.mxGraphics2DCanvas

/**
* $Id: mxGraphics2DCanvas.java,v 1.183 2010-07-18 19:47:20 david Exp $
* Copyright (c) 2007-2010, Gaudenz Alder, David Benson
*/
package com.mxgraph.canvas;

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.GeneralPath;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

import javax.swing.CellRendererPane;

import com.mxgraph.shape.mxActorShape;
import com.mxgraph.shape.mxArrowShape;
import com.mxgraph.shape.mxCloudShape;
import com.mxgraph.shape.mxConnectorShape;
import com.mxgraph.shape.mxCurveShape;
import com.mxgraph.shape.mxCylinderShape;
import com.mxgraph.shape.mxDefaultTextShape;
import com.mxgraph.shape.mxDoubleEllipseShape;
import com.mxgraph.shape.mxEllipseShape;
import com.mxgraph.shape.mxHexagonShape;
import com.mxgraph.shape.mxHtmlTextShape;
import com.mxgraph.shape.mxIShape;
import com.mxgraph.shape.mxITextShape;
import com.mxgraph.shape.mxImageShape;
import com.mxgraph.shape.mxLabelShape;
import com.mxgraph.shape.mxLineShape;
import com.mxgraph.shape.mxRectangleShape;
import com.mxgraph.shape.mxRhombusShape;
import com.mxgraph.shape.mxSwimlaneShape;
import com.mxgraph.shape.mxTriangleShape;
import com.mxgraph.util.mxConstants;
import com.mxgraph.util.mxPoint;
import com.mxgraph.util.mxRectangle;
import com.mxgraph.util.mxUtils;
import com.mxgraph.view.mxCellState;

/**
* An implementation of a canvas that uses Graphics2D for painting.
*/
public class mxGraphics2DCanvas extends mxBasicCanvas
{
  /**
   *
   */
  public static final String TEXT_SHAPE_DEFAULT = "default";

  /**
   *
   */
  public static final String TEXT_SHAPE_HTML = "html";

  /**
   * Maps from names to mxIVertexShape instances.
   */
  protected static Map<String, mxIShape> shapes = new HashMap<String, mxIShape>();

  /**
   * Maps from names to mxITextShape instances. There are currently three different
   * hardcoded text shapes available here: default, html and wrapped.
   */
  protected static Map<String, mxITextShape> textShapes = new HashMap<String, mxITextShape>();

  /**
   * Static initializer.
   */
  static
  {
    putShape(mxConstants.SHAPE_ACTOR, new mxActorShape());
    putShape(mxConstants.SHAPE_ARROW, new mxArrowShape());
    putShape(mxConstants.SHAPE_CLOUD, new mxCloudShape());
    putShape(mxConstants.SHAPE_CONNECTOR, new mxConnectorShape());
    putShape(mxConstants.SHAPE_CYLINDER, new mxCylinderShape());
    putShape(mxConstants.SHAPE_CURVE, new mxCurveShape());
    putShape(mxConstants.SHAPE_DOUBLE_ELLIPSE, new mxDoubleEllipseShape());
    putShape(mxConstants.SHAPE_ELLIPSE, new mxEllipseShape());
    putShape(mxConstants.SHAPE_HEXAGON, new mxHexagonShape());
    putShape(mxConstants.SHAPE_IMAGE, new mxImageShape());
    putShape(mxConstants.SHAPE_LABEL, new mxLabelShape());
    putShape(mxConstants.SHAPE_LINE, new mxLineShape());
    putShape(mxConstants.SHAPE_RECTANGLE, new mxRectangleShape());
    putShape(mxConstants.SHAPE_RHOMBUS, new mxRhombusShape());
    putShape(mxConstants.SHAPE_SWIMLANE, new mxSwimlaneShape());
    putShape(mxConstants.SHAPE_TRIANGLE, new mxTriangleShape());
    putTextShape(TEXT_SHAPE_DEFAULT, new mxDefaultTextShape());
    putTextShape(TEXT_SHAPE_HTML, new mxHtmlTextShape());
  }

  /**
   * Cache for images.
   */
  protected Hashtable<String, Image> imageCache = new Hashtable<String, Image>();

  /**
   * Specifies if linefeeds should be replaced with breaks in HTML markup.
   * Default is true.
   */
  protected boolean replaceHtmlLinefeeds = true;

  /**
   * Optional renderer pane to be used for HTML label rendering.
   */
  protected CellRendererPane rendererPane;

  /**
   * Global graphics handle to the image.
   */
  protected Graphics2D g;

  /**
   * Constructs a new graphics canvas with an empty graphics object.
   */
  public mxGraphics2DCanvas()
  {
    this(null);
  }

  /**
   * Constructs a new graphics canvas for the given graphics object.
   */
  public mxGraphics2DCanvas(Graphics2D g)
  {
    this.g = g;

    // Initializes the cell renderer pane for drawing HTML markup
    try
    {
      rendererPane = new CellRendererPane();
    }
    catch (Exception e)
    {
      // ignore
    }
  }

  /**
   *
   */
  public static void putShape(String name, mxIShape shape)
  {
    shapes.put(name, shape);
  }

  /**
   *
   */
  public mxIShape getShape(Map<String, Object> style)
  {
    String name = mxUtils.getString(style, mxConstants.STYLE_SHAPE, null);

    return shapes.get(name);
  }

  /**
   *
   */
  public static void putTextShape(String name, mxITextShape shape)
  {
    textShapes.put(name, shape);
  }

  /**
   *
   */
  public mxITextShape getTextShape(Map<String, Object> style, boolean html)
  {
    String name;

    if (html)
    {
      name = TEXT_SHAPE_HTML;
    }
    else
    {
      name = TEXT_SHAPE_DEFAULT;
    }

    return textShapes.get(name);
  }

  /**
   *
   */
  public CellRendererPane getRendererPane()
  {
    return rendererPane;
  }

  /**
   * Returns replaceHtmlLinefeeds
   */
  public boolean isReplaceHtmlLinefeeds()
  {
    return replaceHtmlLinefeeds;
  }

  /**
   * Returns replaceHtmlLinefeeds
   */
  public void setReplaceHtmlLinefeeds(boolean value)
  {
    replaceHtmlLinefeeds = value;
  }

  /**
   * Returns the graphics object for this canvas.
   */
  public Graphics2D getGraphics()
  {
    return g;
  }

  /**
   * Sets the graphics object for this canvas.
   */
  public void setGraphics(Graphics2D g)
  {
    this.g = g;
  }

  /*
   * (non-Javadoc)
   * @see com.mxgraph.canvas.mxICanvas#drawCell()
   */
  public Object drawCell(mxCellState state)
  {
    Map<String, Object> style = state.getStyle();
    mxIShape shape = getShape(style);

    if (g != null && shape != null)
    {
      // Creates a temporary graphics instance for drawing this shape
      float opacity = mxUtils.getFloat(style, mxConstants.STYLE_OPACITY,
          100);
      Graphics2D previousGraphics = g;
      g = createTemporaryGraphics(style, opacity, state);

      // Paints the shape and restores the graphics object
      shape.paintShape(this, state);
      g.dispose();
      g = previousGraphics;
    }

    return shape;
  }

  /*
   * (non-Javadoc)
   * @see com.mxgraph.canvas.mxICanvas#drawLabel()
   */
  public Object drawLabel(String text, mxCellState state, boolean html)
  {
    Map<String, Object> style = state.getStyle();
    mxITextShape shape = getTextShape(style, html);

    if (g != null && shape != null && drawLabels && text != null
        && text.length() > 0)
    {
      // Creates a temporary graphics instance for drawing this shape
      float opacity = mxUtils.getFloat(style,
          mxConstants.STYLE_TEXT_OPACITY, 100);
      Graphics2D previousGraphics = g;
      g = createTemporaryGraphics(style, opacity, null);

      // Draws the label background and border
      Color bg = mxUtils.getColor(style,
          mxConstants.STYLE_LABEL_BACKGROUNDCOLOR);
      Color border = mxUtils.getColor(style,
          mxConstants.STYLE_LABEL_BORDERCOLOR);
      paintRectangle(state.getLabelBounds().getRectangle(), bg, border);

      // Paints the label and restores the graphics object
      shape.paintShape(this, text, state, style);
      g.dispose();
      g = previousGraphics;
    }

    return shape;
  }

  /**
   * Returns an image instance for the given URL. If the URL has
   * been loaded before than an instance of the same instance is
   * returned as in the previous call.
   */
  public Image loadImage(String image)
  {
    Image img = imageCache.get(image);

    if (img == null)
    {
      img = mxUtils.loadImage(image);

      if (img != null)
      {
        imageCache.put(image, img);
      }
    }

    return img;
  }

  /**
   *
   */
  public void flushImageCache()
  {
    imageCache.clear();
  }

  /**
   *
   */
  public void drawImage(Rectangle bounds, String imageUrl)
  {
    if (imageUrl != null)
    {
      Image img = loadImage(imageUrl);

      if (img != null)
      {
        g.drawImage(img, bounds.x, bounds.y, bounds.width,
            bounds.height, null);
      }
    }
  }

  /**
   *
   */
  public void paintPolyline(mxPoint[] points, boolean rounded)
  {
    if (points != null && points.length > 1)
    {
      mxPoint pt = points[0];
      mxPoint pe = points[points.length - 1];

      double arcSize = mxConstants.LINE_ARCSIZE * scale;

      GeneralPath path = new GeneralPath();
      path.moveTo((float) pt.getX(), (float) pt.getY());

      // Draws the line segments
      for (int i = 1; i < points.length - 1; i++)
      {
        mxPoint tmp = points[i];
        double dx = pt.getX() - tmp.getX();
        double dy = pt.getY() - tmp.getY();

        if ((rounded && i < points.length - 1) && (dx != 0 || dy != 0))
        {
          // Draws a line from the last point to the current
          // point with a spacing of size off the current point
          // into direction of the last point
          double dist = Math.sqrt(dx * dx + dy * dy);
          double nx1 = dx * Math.min(arcSize, dist / 2) / dist;
          double ny1 = dy * Math.min(arcSize, dist / 2) / dist;

          double x1 = tmp.getX() + nx1;
          double y1 = tmp.getY() + ny1;
          path.lineTo((float) x1, (float) y1);

          // Draws a curve from the last point to the current
          // point with a spacing of size off the current point
          // into direction of the next point
          mxPoint next = points[i + 1];
          dx = next.getX() - tmp.getX();
          dy = next.getY() - tmp.getY();

          dist = Math.max(1, Math.sqrt(dx * dx + dy * dy));
          double nx2 = dx * Math.min(arcSize, dist / 2) / dist;
          double ny2 = dy * Math.min(arcSize, dist / 2) / dist;

          double x2 = tmp.getX() + nx2;
          double y2 = tmp.getY() + ny2;

          path.quadTo((float) tmp.getX(), (float) tmp.getY(),
              (float) x2, (float) y2);
          tmp = new mxPoint(x2, y2);
        }
        else
        {
          path.lineTo((float) tmp.getX(), (float) tmp.getY());
        }

        pt = tmp;
      }

      path.lineTo((float) pe.getX(), (float) pe.getY());
      g.draw(path);
    }
  }

  /**
   *
   */
  public void paintRectangle(Rectangle bounds, Color background, Color border)
  {
    if (background != null)
    {
      g.setColor(background);
      fillShape(bounds);
    }

    if (border != null)
    {
      g.setColor(border);
      g.draw(bounds);
    }
  }

  /**
   *
   */
  public void fillShape(Shape shape)
  {
    fillShape(shape, false);
  }

  /**
   *
   */
  public void fillShape(Shape shape, boolean shadow)
  {
    int shadowOffsetX = (shadow) ? mxConstants.SHADOW_OFFSETX : 0;
    int shadowOffsetY = (shadow) ? mxConstants.SHADOW_OFFSETY : 0;

    if (shadow)
    {
      // Saves the state and configures the graphics object
      Paint p = g.getPaint();
      Color previousColor = g.getColor();
      g.setColor(mxConstants.SHADOW_COLOR);
      g.translate(shadowOffsetX, shadowOffsetY);

      // Paints the shadow
      fillShape(shape, false);

      // Restores the state of the graphics object
      g.translate(-shadowOffsetX, -shadowOffsetY);
      g.setColor(previousColor);
      g.setPaint(p);
    }

    g.fill(shape);
  }

  /**
   *
   */
  public Stroke createStroke(Map<String, Object> style)
  {
    double width = mxUtils
        .getFloat(style, mxConstants.STYLE_STROKEWIDTH, 1)
        * scale;
    boolean dashed = mxUtils.isTrue(style, mxConstants.STYLE_DASHED);
    if (dashed)
    {
      float[] dashPattern = mxUtils.getFloatArray(style,
          mxConstants.STYLE_DASH_PATTERN,
          mxConstants.DEFAULT_DASHED_PATTERN);
      float[] scaledDashPattern = new float[dashPattern.length];

      for (int i = 0; i < dashPattern.length; i++)
      {
        scaledDashPattern[i] = (float) (dashPattern[i] * scale);
      }

      return new BasicStroke((float) width, BasicStroke.CAP_BUTT,
          BasicStroke.JOIN_MITER, 10.0f, scaledDashPattern, 0.0f);
    }
    else
    {
      return new BasicStroke((float) width);
    }
  }

  /**
   *
   */
  public Paint createFillPaint(mxRectangle bounds, Map<String, Object> style)
  {
    Color fillColor = mxUtils.getColor(style, mxConstants.STYLE_FILLCOLOR);
    Paint fillPaint = null;

    if (fillColor != null)
    {
      Color gradientColor = mxUtils.getColor(style,
          mxConstants.STYLE_GRADIENTCOLOR);

      if (gradientColor != null)
      {
        String gradientDirection = mxUtils.getString(style,
            mxConstants.STYLE_GRADIENT_DIRECTION);

        float x1 = (float) bounds.getX();
        float y1 = (float) bounds.getY();
        float x2 = (float) bounds.getX();
        float y2 = (float) bounds.getY();

        if (gradientDirection == null
            || gradientDirection
                .equals(mxConstants.DIRECTION_SOUTH))
        {
          y2 = (float) (bounds.getY() + bounds.getHeight());
        }
        else if (gradientDirection.equals(mxConstants.DIRECTION_EAST))
        {
          x2 = (float) (bounds.getX() + bounds.getWidth());
        }
        else if (gradientDirection.equals(mxConstants.DIRECTION_NORTH))
        {
          y1 = (float) (bounds.getY() + bounds.getHeight());
        }
        else if (gradientDirection.equals(mxConstants.DIRECTION_WEST))
        {
          x1 = (float) (bounds.getX() + bounds.getWidth());
        }

        fillPaint = new GradientPaint(x1, y1, fillColor, x2, y2,
            gradientColor, true);
      }
    }

    return fillPaint;
  }

  /**
   *
   */
  public Graphics2D createTemporaryGraphics(Map<String, Object> style,
      float opacity, mxRectangle bounds)
  {
    Graphics2D temporaryGraphics = (Graphics2D) g.create();

    // Applies the default translate
    temporaryGraphics.translate(translate.x, translate.y);

    // Applies the rotation on the graphics object
    if (bounds != null)
    {
      double rotation = mxUtils.getDouble(style,
          mxConstants.STYLE_ROTATION, 0);

      if (rotation != 0)
      {
        temporaryGraphics.rotate(Math.toRadians(rotation), bounds
            .getCenterX(), bounds.getCenterY());
      }
    }

    // Applies the opacity to the graphics object
    if (opacity != 100)
    {
      temporaryGraphics.setComposite(AlphaComposite.getInstance(
          AlphaComposite.SRC_OVER, opacity / 100));
    }

    return temporaryGraphics;
  }

}
TOP

Related Classes of com.mxgraph.canvas.mxGraphics2DCanvas

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.