All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.mxgraph.swing.util.mxMorphing Maven / Gradle / Ivy
Go to download
JGraphX Swing Component - Java Graph Visualization Library
This is a binary & source redistribution of the original, unmodified JGraphX library originating from:
"https://github.com/jgraph/jgraphx/archive/v3.4.1.3.zip".
The purpose of this redistribution is to make the library available to other Maven projects.
/**
* $Id: mxMorphing.java,v 1.1 2010/06/08 09:49:59 gaudenz Exp $
* Copyright (c) 2007, Gaudenz Alder
*/
package com.mxgraph.swing.util;
import java.awt.Graphics;
import java.util.HashMap;
import java.util.Map;
import com.mxgraph.model.mxGeometry;
import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.swing.view.mxCellStatePreview;
import com.mxgraph.util.mxEvent;
import com.mxgraph.util.mxEventObject;
import com.mxgraph.util.mxPoint;
import com.mxgraph.util.mxRectangle;
import com.mxgraph.view.mxCellState;
import com.mxgraph.view.mxGraph;
/**
* Provides animation effects.
*/
public class mxMorphing extends mxAnimation
{
/**
* Reference to the enclosing graph instance.
*/
protected mxGraphComponent graphComponent;
/**
* Specifies the maximum number of steps for the morphing. Default is
* 6.
*/
protected int steps;
/**
* Counts the current number of steps of the animation.
*/
protected int step;
/**
* Ease-off for movement towards the given vector. Larger values are
* slower and smoother. Default is 1.5.
*/
protected double ease;
/**
* Maps from cells to origins.
*/
protected Map origins = new HashMap();
/**
* Optional array of cells to limit the animation to.
*/
protected Object[] cells;
/**
*
*/
protected transient mxRectangle dirty;
/**
*
*/
protected transient mxCellStatePreview preview;
/**
* Constructs a new morphing instance for the given graph.
*/
public mxMorphing(mxGraphComponent graphComponent)
{
this(graphComponent, 6, 1.5, DEFAULT_DELAY);
// 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);
}
});
}
/**
* Constructs a new morphing instance for the given graph.
*/
public mxMorphing(mxGraphComponent graphComponent, int steps, double ease,
int delay)
{
super(delay);
this.graphComponent = graphComponent;
this.steps = steps;
this.ease = ease;
}
/**
* Returns the number of steps for the animation.
*/
public int getSteps()
{
return steps;
}
/**
* Sets the number of steps for the animation.
*/
public void setSteps(int value)
{
steps = value;
}
/**
* Returns the easing for the movements.
*/
public double getEase()
{
return ease;
}
/**
* Sets the easing for the movements.
*/
public void setEase(double value)
{
ease = value;
}
/**
* Optional array of cells to be animated. If this is not specified
* then all cells are checked and animated if they have been moved
* in the current transaction.
*/
public void setCells(Object[] value)
{
cells = value;
}
/**
* Animation step.
*/
public void updateAnimation()
{
preview = new mxCellStatePreview(graphComponent, false);
if (cells != null)
{
// Animates the given cells individually without recursion
for (Object cell : cells)
{
animateCell(cell, preview, false);
}
}
else
{
// Animates all changed cells by using recursion to find
// the changed cells but not for the animation itself
Object root = graphComponent.getGraph().getModel().getRoot();
animateCell(root, preview, true);
}
show(preview);
if (preview.isEmpty() || step++ >= steps)
{
stopAnimation();
}
};
/**
*
*/
public void stopAnimation()
{
graphComponent.getGraph().getView().revalidate();
super.stopAnimation();
preview = null;
if (dirty != null)
{
graphComponent.getGraphControl().repaint(dirty.getRectangle());
}
}
/**
* Shows the changes in the given mxCellStatePreview.
*/
protected void show(mxCellStatePreview preview)
{
if (dirty != null)
{
graphComponent.getGraphControl().repaint(dirty.getRectangle());
}
else
{
graphComponent.getGraphControl().repaint();
}
dirty = preview.show();
if (dirty != null)
{
graphComponent.getGraphControl().repaint(dirty.getRectangle());
}
}
/**
* Animates the given cell state using moveState.
*/
protected void animateCell(Object cell, mxCellStatePreview move,
boolean recurse)
{
mxGraph graph = graphComponent.getGraph();
mxCellState state = graph.getView().getState(cell);
mxPoint delta = null;
if (state != null)
{
// Moves the animated state from where it will be after the model
// change by subtracting the given delta vector from that location
delta = getDelta(state);
if (graph.getModel().isVertex(cell)
&& (delta.getX() != 0 || delta.getY() != 0))
{
mxPoint translate = graph.getView().getTranslate();
double scale = graph.getView().getScale();
// FIXME: Something wrong with the scale
delta.setX(delta.getX() + translate.getX() * scale);
delta.setY(delta.getY() + translate.getY() * scale);
move.moveState(state, -delta.getX() / ease, -delta.getY()
/ ease);
}
}
if (recurse && !stopRecursion(state, delta))
{
int childCount = graph.getModel().getChildCount(cell);
for (int i = 0; i < childCount; i++)
{
animateCell(graph.getModel().getChildAt(cell, i), move, recurse);
}
}
}
/**
* Returns true if the animation should not recursively find more
* deltas for children if the given parent state has been animated.
*/
protected boolean stopRecursion(mxCellState state, mxPoint delta)
{
return delta != null && (delta.getX() != 0 || delta.getY() != 0);
}
/**
* Returns the vector between the current rendered state and the future
* location of the state after the display will be updated.
*/
protected mxPoint getDelta(mxCellState state)
{
mxGraph graph = graphComponent.getGraph();
mxPoint origin = getOriginForCell(state.getCell());
mxPoint translate = graph.getView().getTranslate();
double scale = graph.getView().getScale();
mxPoint current = new mxPoint(state.getX() / scale - translate.getX(),
state.getY() / scale - translate.getY());
return new mxPoint((origin.getX() - current.getX()) * scale, (origin
.getY() - current.getY())
* scale);
}
/**
* Returns the top, left corner of the given cell.
*/
protected mxPoint getOriginForCell(Object cell)
{
mxPoint result = origins.get(cell);
if (result == null)
{
mxGraph graph = graphComponent.getGraph();
if (cell != null)
{
result = new mxPoint(getOriginForCell(graph.getModel()
.getParent(cell)));
mxGeometry geo = graph.getCellGeometry(cell);
// TODO: Handle offset, relative geometries etc
if (geo != null)
{
result.setX(result.getX() + geo.getX());
result.setY(result.getY() + geo.getY());
}
}
if (result == null)
{
mxPoint t = graph.getView().getTranslate();
result = new mxPoint(-t.getX(), -t.getY());
}
origins.put(cell, result);
}
return result;
}
/**
*
*/
public void paint(Graphics g)
{
if (preview != null)
{
preview.paint(g);
}
}
}