Package com.mxgraph.swing.handler

Source Code of com.mxgraph.swing.handler.mxConnectPreview

/**
* $Id: mxConnectPreview.java,v 1.7 2011-05-18 08:09:25 gaudenz Exp $
* Copyright (c) 2008-2010, Gaudenz Alder, David Benson
*/
package com.mxgraph.swing.handler;

import java.awt.AlphaComposite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;

import com.mxgraph.canvas.mxGraphics2DCanvas;
import com.mxgraph.model.mxGeometry;
import com.mxgraph.model.mxICell;
import com.mxgraph.model.mxIGraphModel;
import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.util.mxEvent;
import com.mxgraph.util.mxEventObject;
import com.mxgraph.util.mxEventSource;
import com.mxgraph.util.mxPoint;
import com.mxgraph.util.mxRectangle;
import com.mxgraph.util.mxUtils;
import com.mxgraph.view.mxCellState;
import com.mxgraph.view.mxGraph;

/**
* Connection handler creates new connections between cells. This control is used to display the connector
* icon, while the preview is used to draw the line.
*/
public class mxConnectPreview extends mxEventSource
{
  /**
   *
   */
  protected mxGraphComponent graphComponent;

  /**
   *
   */
  protected mxCellState previewState;

  /**
   *
   */
  protected mxCellState sourceState;

  /**
   *
   */
  protected mxPoint startPoint;

  /**
   *
   * @param graphComponent
   */
  public mxConnectPreview(mxGraphComponent graphComponent)
  {
    this.graphComponent = graphComponent;

    // Installs the paint handler
    graphComponent.addListener(mxEvent.AFTER_PAINT, new mxIEventListener()
    {
      public void invoke(Object sender, mxEventObject evt)
      {
        Graphics g = (Graphics) evt.getProperty("g");
        paint(g);
      }
    });
  }

  /**
   * Creates a new instance of mxShape for previewing the edge.
   */
  protected Object createCell(mxCellState startState, String style)
  {
    mxGraph graph = graphComponent.getGraph();
    mxICell cell = ((mxICell) graph
        .createEdge(null, null, "",
            (startState != null) ? startState.getCell() : null,
            null, style));
    ((mxICell) startState.getCell()).insertEdge(cell, true);

    return cell;
  }

  /**
   *
   */
  public boolean isActive()
  {
    return sourceState != null;
  }

  /**
   *
   */
  public mxCellState getSourceState()
  {
    return sourceState;
  }

  /**
   *
   */
  public mxCellState getPreviewState()
  {
    return previewState;
  }

  /**
   *
   */
  public mxPoint getStartPoint()
  {
    return startPoint;
  }

  /**
   * Updates the style of the edge preview from the incoming edge
   */
  public void start(MouseEvent e, mxCellState startState, String style)
  {
    mxGraph graph = graphComponent.getGraph();
    sourceState = startState;
    startPoint = transformScreenPoint(startState.getCenterX(),
        startState.getCenterY());
    previewState = graph.getView().getState(createCell(startState, style),
        true);
    fireEvent(new mxEventObject(mxEvent.START, "event", e, "state",
        previewState));
  }

  /**
   *
   */
  public void update(MouseEvent e, mxCellState targetState, double x, double y)
  {
    mxGraph graph = graphComponent.getGraph();
    mxICell cell = (mxICell) previewState.getCell();

    mxRectangle dirty = graphComponent.getGraph().getPaintBounds(
        new Object[] { previewState.getCell() });

    if (cell.getTerminal(false) != null)
    {
      cell.getTerminal(false).removeEdge(cell, false);
    }

    if (targetState != null)
    {
      ((mxICell) targetState.getCell()).insertEdge(cell, false);
    }

    mxGeometry geo = graph.getCellGeometry(previewState.getCell());

    geo.setTerminalPoint(startPoint, true);
    geo.setTerminalPoint(transformScreenPoint(x, y), false);

    revalidate(graph.getView().getState(graph.getDefaultParent()),
        previewState.getCell());
    fireEvent(new mxEventObject(mxEvent.CONTINUE, "event", e, "x", x, "y",
        y));

    // Repaints the dirty region
    // TODO: Cache the new dirty region for next repaint
    Rectangle tmp = getDirtyRect(dirty);
   
    if (tmp != null)
    {
      graphComponent.getGraphControl().repaint(tmp);
    }
    else
    {
      graphComponent.getGraphControl().repaint();
    }
  }

  /**
   *
   */
  protected Rectangle getDirtyRect()
  {
    return getDirtyRect(null);
  }

  /**
   *
   */
  protected Rectangle getDirtyRect(mxRectangle dirty)
  {
    if (previewState != null)
    {
      mxRectangle tmp = graphComponent.getGraph().getPaintBounds(
          new Object[] { previewState.getCell() });

      if (dirty != null)
      {
        dirty.add(tmp);
      }
      else
      {
        dirty = tmp;
      }

      if (dirty != null)
      {
        // TODO: Take arrow size into account
        dirty.grow(2);

        return dirty.getRectangle();
      }
    }

    return null;
  }

  /**
   *
   */
  protected mxPoint transformScreenPoint(double x, double y)
  {
    mxGraph graph = graphComponent.getGraph();
    mxPoint tr = graph.getView().getTranslate();
    double scale = graph.getView().getScale();

    return new mxPoint(graph.snap(x / scale - tr.getX()), graph.snap(y / scale - tr.getY()));
  }

  /**
   *
   */
  public void revalidate(mxCellState pState, Object cell)
  {
    mxGraph graph = graphComponent.getGraph();
    mxCellState tmp = graph.getView().getState(cell);
    tmp.setInvalid(true);

    graph.getView().validateBounds(pState, cell);
    graph.getView().validatePoints(pState, cell);

    mxIGraphModel model = graph.getModel();
    int childCount = model.getChildCount(cell);

    for (int i = 0; i < childCount; i++)
    {
      revalidate(tmp, model.getChildAt(cell, i));
    }
  }

  /**
   *
   */
  public void paint(Graphics g)
  {
    if (previewState != null)
    {
      mxGraphics2DCanvas canvas = graphComponent.getCanvas();

      if (graphComponent.isAntiAlias())
      {
        mxUtils.setAntiAlias((Graphics2D) g, true, false);
      }

      float alpha = graphComponent.getPreviewAlpha();

      if (alpha < 1)
      {
        ((Graphics2D) g).setComposite(AlphaComposite.getInstance(
            AlphaComposite.SRC_OVER, alpha));
      }

      Graphics2D previousGraphics = canvas.getGraphics();
      Point previousTranslate = canvas.getTranslate();
      double previousScale = canvas.getScale();

      try
      {
        canvas.setScale(graphComponent.getGraph().getView().getScale());
        canvas.setTranslate(0, 0);
        canvas.setGraphics((Graphics2D) g);

        paintPreview(canvas);
      }
      finally
      {
        canvas.setScale(previousScale);
        canvas.setTranslate(previousTranslate.x, previousTranslate.y);
        canvas.setGraphics(previousGraphics);
      }
    }
  }

  /**
   * Draws the preview using the graphics canvas.
   */
  protected void paintPreview(mxGraphics2DCanvas canvas)
  {
    graphComponent.getGraphControl().drawCell(graphComponent.getCanvas(),
        previewState.getCell());
  }

  /**
   *
   */
  public Object stop(boolean commit)
  {
    return stop(commit, null);
  }

  /**
   *
   */
  public Object stop(boolean commit, MouseEvent e)
  {
    Object result = (sourceState != null) ? sourceState.getCell() : null;

    if (previewState != null)
    {
      mxGraph graph = graphComponent.getGraph();

      graph.getModel().beginUpdate();
      try
      {
        mxICell cell = (mxICell) previewState.getCell();
        Object src = cell.getTerminal(true);
        Object trg = cell.getTerminal(false);

        if (src != null)
        {
          ((mxICell) src).removeEdge(cell, true);
        }

        if (trg != null)
        {
          ((mxICell) trg).removeEdge(cell, false);
        }

        if (commit)
        {
          result = graph.addCell(cell, null, null, src, trg);
        }

        fireEvent(new mxEventObject(mxEvent.STOP, "event", e, "commit",
            commit, "cell", (commit) ? result : null));

        // Clears the state before the model commits
        if (previewState != null)
        {
          Rectangle dirty = getDirtyRect();
          graph.getView().clear(cell, false, true);
          previewState = null;

          if (!commit && dirty != null)
          {
            graphComponent.getGraphControl().repaint(dirty);
          }
        }
      }
      finally
      {
        graph.getModel().endUpdate();
      }
    }

    sourceState = null;
    startPoint = null;

    return result;
  }

}
TOP

Related Classes of com.mxgraph.swing.handler.mxConnectPreview

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.