package org.ntlab.deltaViewer;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.SwingUtilities;
import com.mxgraph.canvas.mxGraphics2DCanvas;
import com.mxgraph.model.mxICell;
import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.util.mxPoint;
/**
* Generate delta animation for MagnetRON.
*
* @author Nitta Lab.
*/
public class DeltaAnimation {
private DeltaGraphAdapter mxgraph;
private mxGraphComponent mxgraphComponent;
private Graphics2D graphics2D;
private Timer timer;
private static int FINAL_STEP_COUNT = 10;
private mxICell sourceCell;
GeneralPath p = new GeneralPath();
// X, Y
private mxPoint sourcePoint;
private mxPoint targetPoint;
private mxPoint curPoint;
private mxPoint updatePoint = new mxPoint();
// Width, Height
private Dimension targetDimension;
private Dimension curDimension = new Dimension();
private Dimension updateDimension = new Dimension();
private double scale = 1;
/**
* @param mxgraph
* @param mxgraphComponent
*/
public DeltaAnimation(DeltaGraphAdapter mxgraph, mxGraphComponent mxgraphComponent) {
this.mxgraph = mxgraph;
this.mxgraphComponent = mxgraphComponent;
graphics2D = (Graphics2D)mxgraphComponent.getGraphics();
}
/**
* @param zoomLevel Zoom level of MagnetRON view.
*/
public void setScale(double zoomLevel) {
this.scale = zoomLevel;
}
/**
* Set to move animation sourcell vertex to targetPoint.
*
* @param sourceCell Vertex.
* @param targetPoint XY coordinates.
*/
public void setVertexAnimation(mxICell sourceCell, mxPoint targetPoint) {
this.sourceCell = sourceCell;
this.targetPoint = targetPoint;
curPoint = new mxPoint(sourceCell.getGeometry().getX(), sourceCell.getGeometry().getY());
// System.out.println("sourcePoint : " + sourceCell.getGeometry().getPoint());
// System.out.println("targetPoint : " + targetPoint);
calculateResizeLineModel();
}
/**
* Set stretch(expand) animation of edge from sourcePoint to targetPoint.
*
* @param sourcePoint Edge sourcePoint.
* @param targetPoint Edge targetPoint.
*/
public void setExpandEdgeAnimation(mxPoint sourcePoint, mxPoint targetPoint) {
this.sourcePoint = new mxPoint(sourcePoint.getX() * scale + 1, sourcePoint.getY() * scale + 1);
this.targetPoint = new mxPoint(targetPoint.getX() * scale, targetPoint.getY() * scale);
curPoint = this.sourcePoint;
// System.out.println("sourcePoint : " + sourcePoint);
// System.out.println("targetPoint : " + targetPoint);
graphics2D = (Graphics2D)mxgraphComponent.getGraphics();
graphics2D.setColor(Color.decode("#008000"));
float width = (float) (1 * scale);
Stroke dashed = new BasicStroke(width, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, new float[]{(float) (3.0f * scale * width), (float) (3.0f * scale * width)}, 0.0f);
graphics2D.setStroke(dashed);
calculateResizeLineModel();
}
/**
* Set to move animation sourcell vertex clone to targetPoint, reduce edge length.
*
* @param sourceCell Remove sourceCell vertex clone.
* @param targetPoint
*/
public void setReductionEdgeAnimation(mxICell sourceCell, mxPoint targetPoint) {
this.sourceCell = sourceCell;
this.targetPoint = targetPoint;
curPoint = new mxPoint(sourceCell.getGeometry().getX(), sourceCell.getGeometry().getY());
// System.out.println("sourcePoint : " + sourceCell.getGeometry().getPoint());
// System.out.println("targetPoint : " + targetPoint);
calculateResizeLineModel();
}
/**
* Set animation resize vertex.
*
* @param sourceCell
* @param targetDimension Vertex (Width, Height)
*/
public void setResizeVertexAnimation(mxICell sourceCell, Dimension targetDimension) {
this.sourceCell = sourceCell;
this.targetDimension = targetDimension;
curDimension.setSize(sourceCell.getGeometry().getWidth(), sourceCell.getGeometry().getHeight());
calculateResizeVertexModel();
}
/**
* Calculate updatePoint every second from curPoint and targetPoint.
*/
public void calculateResizeLineModel() {
mxPoint distancePoint = new mxPoint();
distancePoint.setX(targetPoint.getX() - curPoint.getX());
distancePoint.setY(targetPoint.getY() - curPoint.getY());
updatePoint.setX(distancePoint.getX() / FINAL_STEP_COUNT);
updatePoint.setY(distancePoint.getY() / FINAL_STEP_COUNT);
}
/**
* Calculate updateDimension every second from curPoint and targetPoint.
*/
public void calculateResizeVertexModel() {
Dimension distanceDimension = new Dimension();
distanceDimension.setSize(targetDimension.getWidth() - curDimension.getWidth(), targetDimension.getHeight() - curDimension.getWidth());
updateDimension.setSize(distanceDimension.getWidth() / FINAL_STEP_COUNT, distanceDimension.getHeight() / FINAL_STEP_COUNT);
}
/**
* Start animation to move sourcell vertex to targetPoint for 10 sec.
*/
public void startVertexAnimation() {
timer = new Timer();
timer.schedule(new TimerTask() {
int stepCount = 0;
@Override
public void run() {
if(stepCount < FINAL_STEP_COUNT) {
updateVertexAnimation();
stepCount++;
if(stepCount >= FINAL_STEP_COUNT){
timer.cancel();
}
}
}
}, 0, 100);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* Start stretch(expand) animation of edge from sourcePoint to targetPoint for 10 sec.
*/
public void startExpandEdgeAnimation() {
timer = new Timer();
timer.schedule(new TimerTask() {
int stepCount = 0;
@Override
public void run() {
if(stepCount < FINAL_STEP_COUNT) {
updateExpandEdgeAnimation();
stepCount++;
if(stepCount >= FINAL_STEP_COUNT){
timer.cancel();
}
}
}
}, 0, 100);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* Start move animation sourcell vertex clone to targetPoint, reduce edge length for 10 sec.
*/
public void startReductionEdgeAnimation() {
timer = new Timer();
timer.schedule(new TimerTask() {
int stepCount = 0;
@Override
public void run() {
if(stepCount < FINAL_STEP_COUNT) {
updateReductionEdgeAnimation();
stepCount++;
if(stepCount >= FINAL_STEP_COUNT){
timer.cancel();
}
}
}
}, 0, 100);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* Start animation resize vertex for 10 sec.
*/
public void startResizeVertexAnimation() {
timer = new Timer();
timer.schedule(new TimerTask() {
int stepCount = 0;
@Override
public void run() {
if(stepCount < FINAL_STEP_COUNT) {
updateResizeVertexAnimation();
stepCount++;
if(stepCount >= FINAL_STEP_COUNT){
timer.cancel();
}
}
}
}, 0, 100);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* Update animation to move sourcell vertex to targetPoint every second.
*/
private void updateVertexAnimation() {
// Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology.
mxgraph.getModel().beginUpdate();
try {
curPoint.setX(sourceCell.getGeometry().getX());
curPoint.setY(sourceCell.getGeometry().getY());
sourceCell.getGeometry().setX(curPoint.getX() + updatePoint.getX());
sourceCell.getGeometry().setY(curPoint.getY() + updatePoint.getY());
// System.out.println(sourceCell.getGeometry().getPoint());
} finally {
mxgraph.getModel().endUpdate();
}
mxgraphComponent.refresh();
}
/**
* Update stretch(expand) animation of edge length updatePoint every second.
*/
private void updateExpandEdgeAnimation() {
Runnable r = new Runnable() {
public void run() {
p.reset();
p.moveTo((float)curPoint.getX(), (float)curPoint.getY());
curPoint.setX(curPoint.getX() + updatePoint.getX());
curPoint.setY(curPoint.getY() + updatePoint.getY());
// System.out.println("curPoint : " + curPoint);
p.lineTo((float)curPoint.getX(), (float)curPoint.getY());
graphics2D.draw(p);
}
};
// Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology.
if (!SwingUtilities.isEventDispatchThread()) {
SwingUtilities.invokeLater(r);
} else {
r.run();
}
}
/**
* Update move animation sourcell vertex clone to targetPoint, reduce edge length updatePoint every second.
*/
private void updateReductionEdgeAnimation() {
// Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology.
mxgraph.getModel().beginUpdate();
try {
curPoint.setX(sourceCell.getGeometry().getX());
curPoint.setY(sourceCell.getGeometry().getY());
sourceCell.getGeometry().setX(curPoint.getX() + updatePoint.getX());
sourceCell.getGeometry().setY(curPoint.getY() + updatePoint.getY());
// System.out.println(sourceCell.getGeometry().getPoint());
} finally {
mxgraph.getModel().endUpdate();
}
mxgraphComponent.refresh();
}
/**
* Update animation resize vertex every second.
*/
private void updateResizeVertexAnimation() {
// Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology.
mxgraph.getModel().beginUpdate();
try {
double preCenterX = sourceCell.getGeometry().getCenterX();
double preCenterY = sourceCell.getGeometry().getCenterY();
curDimension.setSize(sourceCell.getGeometry().getWidth(), sourceCell.getGeometry().getHeight());
sourceCell.getGeometry().setWidth(curDimension.getWidth() + updateDimension.getWidth());
sourceCell.getGeometry().setHeight(curDimension.getHeight() + updateDimension.getHeight());
double curCenterX = sourceCell.getGeometry().getCenterX();
double curCenterY = sourceCell.getGeometry().getCenterY();
double distanceX = (curCenterX - preCenterX);
double distanceY = (curCenterY - preCenterY);
double curX = sourceCell.getGeometry().getX();
double curY = sourceCell.getGeometry().getY();
sourceCell.getGeometry().setX(curX - distanceX);
sourceCell.getGeometry().setY(curY - distanceY);
for (int i = 0; i < sourceCell.getChildCount(); i++) {
mxICell childCell = sourceCell.getChildAt(i);
System.out.println("child" + childCell);
curX = childCell.getGeometry().getX();
curY = childCell.getGeometry().getY();
childCell.getGeometry().setX(curX + distanceX);
childCell.getGeometry().setY(curY + distanceY);
}
} finally {
mxgraph.getModel().endUpdate();
}
mxgraphComponent.refresh();
}
}