Package com.mxgraph.swing.handler

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

/**
* $Id: mxGraphTransferHandler.java,v 1.20 2011-01-25 15:56:18 gaudenz Exp $
* Copyright (c) 2008, Gaudenz Alder
*/
package com.mxgraph.swing.handler;

import java.awt.Color;
import java.awt.Image;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;

import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.TransferHandler;

import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.swing.util.mxGraphTransferable;
import com.mxgraph.util.mxCellRenderer;
import com.mxgraph.util.mxPoint;
import com.mxgraph.util.mxRectangle;
import com.mxgraph.view.mxGraph;

/**
*
*/
public class mxGraphTransferHandler extends TransferHandler
{

  /**
   *
   */
  private static final long serialVersionUID = -6443287704811197675L;

  /**
   * Boolean that specifies if an image of the cells should be created for
   * each transferable. Default is true.
   */
  public static boolean DEFAULT_TRANSFER_IMAGE_ENABLED = true;

  /**
   * Specifies the background color of the transfer image. If no
   * color is given here then the background color of the enclosing
   * graph component is used. Default is Color.WHITE.
   */
  public static Color DEFAULT_BACKGROUNDCOLOR = Color.WHITE;

  /**
   * Reference to the original cells for removal after a move.
   */
  protected Object[] originalCells;

  /**
   * Reference to the last imported cell array.
   */
  protected Transferable lastImported;

  /**
   * Sets the value for the initialImportCount. Default is 1. Updated in
   * exportDone to contain 0 after a cut and 1 after a copy.
   */
  protected int initialImportCount = 1;

  /**
   * Counter for the last imported cell array.
   */
  protected int importCount = 0;

  /**
   * Specifies if a transfer image should be created for the transferable.
   * Default is DEFAULT_TRANSFER_IMAGE.
   */
  protected boolean transferImageEnabled = DEFAULT_TRANSFER_IMAGE_ENABLED;

  /**
   * Specifies the background color for the transfer image. Default is
   * DEFAULT_BACKGROUNDCOLOR.
   */
  protected Color transferImageBackground = DEFAULT_BACKGROUNDCOLOR;

  /**
   *
   */
  protected Point location;

  /**
   *
   */
  protected Point offset;

  /**
   *
   */
  public int getImportCount()
  {
    return importCount;
  }

  /**
   *
   */
  public void setImportCount(int value)
  {
    importCount = value;
  }

  /**
   *
   */
  public void setTransferImageEnabled(boolean transferImageEnabled)
  {
    this.transferImageEnabled = transferImageEnabled;
  }

  /**
   *
   */
  public boolean isTransferImageEnabled()
  {
    return this.transferImageEnabled;
  }

  /**
   *
   */
  public void setTransferImageBackground(Color transferImageBackground)
  {
    this.transferImageBackground = transferImageBackground;
  }

  /**
   *
   */
  public Color getTransferImageBackground()
  {
    return this.transferImageBackground;
  }

  /**
   * Returns true if the DnD operation started from this handler.
   */
  public boolean isLocalDrag()
  {
    return originalCells != null;
  }

  /**
   *
   */
  public void setLocation(Point value)
  {
    location = value;
  }

  /**
   *
   */
  public void setOffset(Point value)
  {
    offset = value;
  }

  /**
   *
   */
  public boolean canImport(JComponent comp, DataFlavor[] flavors)
  {
    for (int i = 0; i < flavors.length; i++)
    {
      if (flavors[i] != null
          && flavors[i].equals(mxGraphTransferable.dataFlavor))
      {
        return true;
      }
    }

    return false;
  }

  /**
   * (non-Javadoc)
   *
   * @see javax.swing.TransferHandler#createTransferable(javax.swing.JComponent)
   */
  public Transferable createTransferable(JComponent c)
  {
    if (c instanceof mxGraphComponent)
    {
      mxGraphComponent graphComponent = (mxGraphComponent) c;
      mxGraph graph = graphComponent.getGraph();

      if (!graph.isSelectionEmpty())
      {
        originalCells = graphComponent.getExportableCells(graph
            .getSelectionCells());

        if (originalCells.length > 0)
        {
          ImageIcon icon = (transferImageEnabled) ? createTransferableImage(
              graphComponent, originalCells) : null;

          return createGraphTransferable(graphComponent,
              originalCells, icon);
        }
      }
    }

    return null;
  }

  /**
   *
   */
  public mxGraphTransferable createGraphTransferable(
      mxGraphComponent graphComponent, Object[] cells, ImageIcon icon)
  {
    mxGraph graph = graphComponent.getGraph();
    mxPoint tr = graph.getView().getTranslate();
    double scale = graph.getView().getScale();

    mxRectangle bounds = graph.getPaintBounds(cells);

    // Removes the scale and translation from the bounds
    bounds.setX(bounds.getX() / scale - tr.getX());
    bounds.setY(bounds.getY() / scale - tr.getY());
    bounds.setWidth(bounds.getWidth() / scale);
    bounds.setHeight(bounds.getHeight() / scale);

    return createGraphTransferable(graphComponent, cells, bounds, icon);
  }

  /**
   *
   */
  public mxGraphTransferable createGraphTransferable(
      mxGraphComponent graphComponent, Object[] cells,
      mxRectangle bounds, ImageIcon icon)
  {
    return new mxGraphTransferable(graphComponent.getGraph().cloneCells(
        cells), bounds, icon);
  }

  /**
   *
   */
  public ImageIcon createTransferableImage(mxGraphComponent graphComponent,
      Object[] cells)
  {
    ImageIcon icon = null;
    Color bg = (transferImageBackground != null) ? transferImageBackground
        : graphComponent.getBackground();
    Image img = mxCellRenderer.createBufferedImage(
        graphComponent.getGraph(), cells, 1, bg,
        graphComponent.isAntiAlias(), null, graphComponent.getCanvas());

    if (img != null)
    {
      icon = new ImageIcon(img);
    }

    return icon;
  }

  /**
   *
   */
  public void exportDone(JComponent c, Transferable data, int action)
  {
    initialImportCount = 1;
   
    if (c instanceof mxGraphComponent
        && data instanceof mxGraphTransferable)
    {
      // Requires that the graph handler resets the location to null if the drag leaves the
      // component. This is the condition to identify a cross-component move.
      boolean isLocalDrop = location != null;

      if (action == TransferHandler.MOVE && !isLocalDrop)
      {
        removeCells((mxGraphComponent) c, originalCells);
        initialImportCount = 0;
      }
    }

    originalCells = null;
    location = null;
    offset = null;
  }

  /**
   *
   */
  protected void removeCells(mxGraphComponent graphComponent, Object[] cells)
  {
    graphComponent.getGraph().removeCells(cells);
  }

  /**
   *
   */
  public int getSourceActions(JComponent c)
  {
    return COPY_OR_MOVE;
  }

  /**
   * Checks if the mxGraphTransferable data flavour is supported and calls
   * importGraphTransferable if possible.
   */
  public boolean importData(JComponent c, Transferable t)
  {
    boolean result = false;

    if (isLocalDrag())
    {
      // Enables visual feedback on the Mac
      result = true;
    }
    else
    {
      try
      {
        updateImportCount(t);

        if (c instanceof mxGraphComponent)
        {
          mxGraphComponent graphComponent = (mxGraphComponent) c;

          if (graphComponent.isEnabled()
              && t.isDataFlavorSupported(mxGraphTransferable.dataFlavor))
          {
            mxGraphTransferable gt = (mxGraphTransferable) t
                .getTransferData(mxGraphTransferable.dataFlavor);

            if (gt.getCells() != null)
            {
              result = importGraphTransferable(graphComponent, gt);
            }

          }
        }
      }
      catch (Exception ex)
      {
        ex.printStackTrace();
      }
    }

    return result;
  }

  /**
   * Counts the number of times that the given transferable has been imported.
   */
  protected void updateImportCount(Transferable t)
  {
    if (lastImported != t)
    {
      importCount = initialImportCount;
    }
    else
    {
      importCount++;
    }

    lastImported = t;
  }

  /**
   * Returns true if the cells have been imported using importCells.
   */
  protected boolean importGraphTransferable(mxGraphComponent graphComponent,
      mxGraphTransferable gt)
  {
    boolean result = false;

    try
    {
      mxGraph graph = graphComponent.getGraph();
      double scale = graph.getView().getScale();
      mxRectangle bounds = gt.getBounds();
      double dx = 0, dy = 0;

      // Computes the offset for the placement of the imported cells
      if (location != null && bounds != null)
      {
        mxPoint translate = graph.getView().getTranslate();

        dx = location.getX() - (bounds.getX() + translate.getX())
            * scale;
        dy = location.getY() - (bounds.getY() + translate.getY())
            * scale;

        // Keeps the cells aligned to the grid
        dx = graph.snap(dx / scale);
        dy = graph.snap(dy / scale);
      }
      else
      {
        int gs = graph.getGridSize();

        dx = importCount * gs;
        dy = importCount * gs;
      }

      if (offset != null)
      {
        dx += offset.x;
        dy += offset.y;
      }

      importCells(graphComponent, gt, dx, dy);
      location = null;
      offset = null;
      result = true;

      // Requests the focus after an import
      graphComponent.requestFocus();
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return result;
  }

  /**
   * Returns the drop target for the given transferable and location.
   */
  protected Object getDropTarget(mxGraphComponent graphComponent,
      mxGraphTransferable gt)
  {
    Object[] cells = gt.getCells();
    Object target = null;

    // Finds the target cell at the given location and checks if the
    // target is not already the parent of the first imported cell
    if (location != null)
    {
      target = graphComponent.getGraph().getDropTarget(cells, location,
          graphComponent.getCellAt(location.x, location.y));

      if (cells.length > 0
          && graphComponent.getGraph().getModel().getParent(cells[0]) == target)
      {
        target = null;
      }
    }

    return target;
  }

  /**
   * Gets a drop target using getDropTarget and imports the cells using
   * mxGraph.splitEdge or mxGraphComponent.importCells depending on the
   * drop target and the return values of mxGraph.isSplitEnabled and
   * mxGraph.isSplitTarget. Selects and returns the cells that have been
   * imported.
   */
  protected Object[] importCells(mxGraphComponent graphComponent,
      mxGraphTransferable gt, double dx, double dy)
  {
    Object target = getDropTarget(graphComponent, gt);
    mxGraph graph = graphComponent.getGraph();
    Object[] cells = gt.getCells();

    cells = graphComponent.getImportableCells(cells);

    if (graph.isSplitEnabled() && graph.isSplitTarget(target, cells))
    {
      graph.splitEdge(target, cells, dx, dy);
    }
    else
    {
      cells = graphComponent.importCells(cells, dx, dy, target, location);
      graph.setSelectionCells(cells);
    }

    return cells;
  }

}
TOP

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

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.