diff --git a/src/org/ntlab/animations/EdgeAnimation.java b/src/org/ntlab/animations/EdgeAnimation.java new file mode 100644 index 0000000..cdd0a87 --- /dev/null +++ b/src/org/ntlab/animations/EdgeAnimation.java @@ -0,0 +1,66 @@ +package org.ntlab.animations; + +import java.awt.Point; +import java.awt.geom.Point2D; +import java.util.concurrent.ThreadPoolExecutor; + +import org.ntlab.deltaViewer.DeltaGraphAdapter; + +import com.mxgraph.model.mxICell; +import com.mxgraph.swing.mxGraphComponent; +import com.mxgraph.util.mxPoint; + +/** + * Animation of edge stretching and shrinking. + * + * @author Nitta Lab. + */ +public class EdgeAnimation extends MagnetRONAnimation { + + /** + * The constructor of {@code EdgeAnimation}. + * + * @param mxgraph + * @param mxgraphComponent + */ + public EdgeAnimation(DeltaGraphAdapter mxgraph, mxGraphComponent mxgraphComponent) { + super(mxgraph, mxgraphComponent); + } + + /** + * See {@code MagnetRONAnimation#init(mxICell, Point2D, ThreadPoolExecutor)} + * + * @param sourceCell + * @param targetPoint + */ + @Override + public void init(mxICell sourceCell, Point2D targetPoint, ThreadPoolExecutor threadPoolExecutor) { + super.init(sourceCell, targetPoint, threadPoolExecutor); + + Point2D curPoint = new Point(sourceCell.getGeometry().getPoint()); + System.out.println("sourcePoint: " + sourceCell.getGeometry().getPoint()); + System.out.println("targetPoint: " + targetPoint); + + // Calculate resize line model + mxPoint distancePoint = new mxPoint(); + distancePoint.setX(targetPoint.getX() - curPoint.getX()); + distancePoint.setY(targetPoint.getY() - curPoint.getY()); + Point2D updatePoint = new Point2D.Double(); + updatePoint.setLocation(distancePoint.getX() / getTotalCycleCount(), distancePoint.getY() / getTotalCycleCount()); + setVelocity(updatePoint); + System.out.println("updatePoint: " + getVelocity()); + } + + protected void jumpTo(int curCycleCount) { + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + mxgraph.getModel().beginUpdate(); + try { + getSourceCell().getGeometry().setX(getSourceInitalPoint().getX() + getVelocity().getX() * curCycleCount); + getSourceCell().getGeometry().setY(getSourceInitalPoint().getY() + getVelocity().getY() * curCycleCount); + } finally { + mxgraph.getModel().endUpdate(); + } + mxgraphComponent.refresh(); + } + +} diff --git a/src/org/ntlab/animations/MagnetRONAnimation.java b/src/org/ntlab/animations/MagnetRONAnimation.java new file mode 100644 index 0000000..0bc6537 --- /dev/null +++ b/src/org/ntlab/animations/MagnetRONAnimation.java @@ -0,0 +1,417 @@ +package org.ntlab.animations; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.geom.Point2D; +import java.util.TimerTask; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import org.ntlab.deltaViewer.DeltaGraphAdapter; +import org.ntlab.deltaViewer.MagnetRONScheduledThreadPoolExecutor; + +import com.mxgraph.model.mxICell; +import com.mxgraph.swing.mxGraphComponent; +/** + * + * + * @author Nitta Lab. + */ +public abstract class MagnetRONAnimation { + + protected DeltaGraphAdapter mxgraph; + protected mxGraphComponent mxgraphComponent; + + protected ThreadPoolExecutor threadPoolExecutor; + protected ScheduledFuture scheduledFuture; + /** + * Initial delays the start of an animation. + * + * Cannot be negative. Setting to a negative number will result in {@link IllegalArgumentException}. + * + * @defaultValue 0ms + */ + private long initialDelay; + private static final long DEFAULT_INITIAL_DELAY = 0L; + /** + * Delays the interval between repeating an animation. + * + * Cannot be negative. Setting to a negative number will result in {@link IllegalArgumentException}. + * + * @defaultValue 0ms + */ + private long delay; + private static final long DEFAULT_DELAY = 0L; + + /** + * Defines the direction/speed at which the {@code MagnetRONAnimation} is expected to + * be played. + *

+ * The absolute value of {@code rate} indicates the speed which the + * {@code Animation} is to be played, while the sign of {@code rate} + * indicates the direction. A positive value of {@code rate} indicates + * forward play, a negative value indicates backward play and {@code 0.0} to + * stop a running {@code MagnetRONAnimation}. + *

+ * Rate {@code 1.0} is normal play, {@code 2.0} is 2 time normal, + * {@code -1.0} is backwards, etc... + * + *

+ * Inverting the rate of a running {@code MagnetRONAnimation} will cause the + * {@code MagnetRONAnimation} to reverse direction in place and play back over the + * portion of the {@code MagnetRONAnimation} that has already elapsed. + * + * @defaultValue 1.0 + */ + private double rate; + private static final double DEFAULT_RATE = 1.0; + + /** + * Read-only variable to indicate current direction/speed at which the + * {@code MagnetRONAnimation} is being played. + *

+ * {@code currentRate} is not necessary equal to {@code rate}. + * {@code currentRate} is set to {@code 0.0} when animation is paused or + * stopped. {@code currentRate} may also point to different direction during + * reverse cycles when {@code reverse} is {@code true} + * + * @defaultValue 0.0 + */ + private double currentRate; + private static final double DEFAULT_CURRENT_RATE = 0.0; + + /** + * Defines the number of cycles in this animation. The {@code totalCycleCount} + * may be {@code INDEFINITE} for animations that repeat indefinitely, but + * must otherwise be > 0. + *

+ * It is not possible to change the {@code totalCycleCount} of a running + * {@code MagnetRONAnimation}. If the value of {@code totalCycleCount} is changed for a + * running {@code MagnetRONAnimation}, the animation has to be stopped and started again to pick + * up the new value. + * + * @defaultValue 1 + * + */ + private int totalCycleCount; + private static final int DEFAULT_TOTAL_CYCLE_COUNT = 1; + /** + * The current number of cycles in this animation. + * + * @defaultValu 0 + */ + private int currentCycleCount = 0; + + /** + * Used to specify an animation that repeats indefinitely, until the + * {@code stop()} method is called. + */ + private static final int INDEFINITE = -1; + + /** + * The status of the {@code MagnetRONAnimation}. + * + * In {@code MagnetRONAnimation} can be in one of three states: + * {@link Status#STOPPED}, {@link Status#PAUSED} or {@link Status#RUNNING}. + */ + private Status currentStatus; + private static final Status DEFAULT_STATUS = Status.STOPPED; + + /** + * The action to be executed at the conclusion of this {@code MagnetRONAnimation}. + */ + private ActionListener onFinished; + + /** + * Defines whether this + * {@code MagnetRONAnimation} reverses direction on alternating cycles. If + * {@code true}, the + * {@code MagnetRONAnimation} will proceed reverses on the cycle. + * Otherwise, animation will loop such that each cycle proceeds forward from the start. + * + * It is not possible to change the {@code reverse} flag of a running + * {@code MagnetRONAnimation}. If the value of {@code reverse} is changed for a + * running {@code MagnetRONAnimation}, the animation has to be stopped and started again to pick + * up the new value. + * + * @defaultValue false + */ + private boolean reverse; + private static final boolean DEFAULT_REVERSE = false; + + /** + * The object to animate. + */ + private mxICell sourceCell; + + /** + * The initial point of sourceCell. + */ + private Point2D sourceInitPoint; + /** + * The target point where the sourceCell animates. + */ + private Point2D destinationPoint; + /** + * The point to update for each cycle count. + */ + private Point2D velocity; + + /** + * The possible state for MagnetRONAnimation. + */ + protected static enum Status { + /** + * The paused state. + */ + PAUSED, + /** + * The running state. + */ + RUNNING, + /** + * The stopped state. + */ + STOPPED + } + + /** + * The constructor of {@code MagnetRONAnimation}. + * + * @param mxgraph: visualization model + * @param mxgraphComponent: visualization model group + */ + protected MagnetRONAnimation(DeltaGraphAdapter mxgraph, mxGraphComponent mxgraphComponent) { + this.mxgraph = mxgraph; + this.mxgraphComponent = mxgraphComponent; + } + + protected void setThreadPoolExecutor(ThreadPoolExecutor threadPoolExecutor) { + this.threadPoolExecutor = threadPoolExecutor; + } + + public void setInitialDelay(long initialDelay) { + this.initialDelay = initialDelay; + } + + public void setDelay(long delay) { + this.delay = delay; + } + + protected void setRate(double rate) { + this.rate = rate; + } + + protected void setCurrentRate(double currentRate) { + this.currentRate = currentRate; + } + + public void setTotalCycleCount(int totalCycleCount) { + this.totalCycleCount = totalCycleCount; + } + + protected void setCurrentCycleCount(int currentCycleCount) { + this.currentCycleCount = currentCycleCount; + } + + protected void setCurrentStatus(Status currentStatus) { + this.currentStatus = currentStatus; + } + + public void setOnFinished(ActionListener onFinished) { + this.onFinished = onFinished; + } + + public void setReverse(boolean reverse) { + this.reverse = reverse; + } + + protected void setSourceCell(mxICell sourceCell) { + this.sourceCell = sourceCell; + } + + protected void setSourceInitialPoint(Point2D sourceInitPoint) { + this.sourceInitPoint = sourceInitPoint; + } + + protected void setDestinationPoint(Point2D destinationPoint) { + this.destinationPoint = destinationPoint; + } + + protected void setVelocity(Point2D velocity) { + this.velocity = velocity; + } + + protected ThreadPoolExecutor getThreadPoolExecutor() { + return threadPoolExecutor; + } + + public long getInitialDelay() { + if (initialDelay == 0L) return DEFAULT_INITIAL_DELAY; + return initialDelay; + } + + public long getDelay() { + if (delay == 0L) return DEFAULT_DELAY; + return delay; + } + + protected double getRate() { + if (rate == 0.0) return DEFAULT_RATE; + return rate; + } + + protected double getCurrentRate() { + if (currentRate == 0.0) return DEFAULT_CURRENT_RATE; + return currentRate; + } + + public int getTotalCycleCount() { + if (totalCycleCount == 0) return DEFAULT_TOTAL_CYCLE_COUNT; + return totalCycleCount; + } + + protected int getCurrentCycleCount() { + return currentCycleCount; + } + + protected Status getCurrentStatus() { + if (currentStatus == null) return DEFAULT_STATUS; + return currentStatus; + } + + public ActionListener getOnFinished() { + return onFinished; + } + + public boolean getReverse() { + if (!reverse) return DEFAULT_REVERSE; + return reverse; + } + + protected mxICell getSourceCell() { + return sourceCell; + } + + protected Point2D getSourceInitalPoint() { + return sourceInitPoint; + } + + protected Point2D getDestinationPoint() { + return destinationPoint; + } + + protected Point2D getVelocity() { + return velocity; + } + + /** + * Set expand or reduction animation of edge to targetPoint. + * Must be call {@code MagnetRONAnimation#init(mxICell, mxPoint, ThreadPoolExecutor)} before calling {@code MagnetRONAnimation#play()}. + * + * @param sourceCell: edge object + * @param destinationPoint + */ + protected void init(mxICell sourceCell, Point2D destinationPoint, ThreadPoolExecutor threadPoolExecutor) { + setSourceCell(sourceCell); + setDestinationPoint(destinationPoint); + setThreadPoolExecutor(threadPoolExecutor); + setSourceInitialPoint(getSourceCell().getGeometry().getPoint()); + setCurrentCycleCount(0); + } + + public void stepCurrentCycle(int currentCycleCount) { + if (!getReverse()) { // Animation direction is forward. + setCurrentCycleCount((int) (currentCycleCount + Math.signum(getTotalCycleCount()))); + System.out.println("curCycleCount: " + getCurrentCycleCount()); + } else { + setCurrentCycleCount((int) (currentCycleCount - Math.signum(getTotalCycleCount()))); + } + } + + public void interpolate(double cycleCount) { + + } + + public void playFrom() { + + } + + public void play() { + switch (getCurrentStatus()) { + case STOPPED: + if (getThreadPoolExecutor() != null & getThreadPoolExecutor() instanceof ScheduledThreadPoolExecutor) { + ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = (ScheduledThreadPoolExecutor) getThreadPoolExecutor(); + this.scheduledFuture = scheduledThreadPoolExecutor.scheduleWithFixedDelay(new TimerTask() { + @Override + public void run() { + if(Math.abs(getCurrentCycleCount()) < Math.abs(getTotalCycleCount())) { + jumpTo(getCurrentCycleCount()); + stepCurrentCycle(getCurrentCycleCount()); + } else if(Math.abs(getCurrentCycleCount()) >= Math.abs(getTotalCycleCount())){ + scheduledFuture.cancel(true); + onFinished(); + } + } + }, getInitialDelay(), getDelay(), TimeUnit.MILLISECONDS); + setCurrentStatus(Status.RUNNING); + }; + break; + case PAUSED: + if (getThreadPoolExecutor() != null & getThreadPoolExecutor() instanceof MagnetRONScheduledThreadPoolExecutor) { + MagnetRONScheduledThreadPoolExecutor scheduledThreadPoolExecutor = (MagnetRONScheduledThreadPoolExecutor) getThreadPoolExecutor(); + scheduledThreadPoolExecutor.resume(); + setCurrentStatus(Status.RUNNING); + } + break; + default: + break; + }; + } + + public void playFormStart() { + + } + + public void stop() { + if (getCurrentStatus() == Status.RUNNING) { + } + setCurrentStatus(Status.STOPPED); + setCurrentRate(0.0); + } + + public void pause() { + if (getCurrentStatus() == Status.RUNNING) { + if (getThreadPoolExecutor() != null && getThreadPoolExecutor() instanceof MagnetRONScheduledThreadPoolExecutor) { + MagnetRONScheduledThreadPoolExecutor scheduledThreadPoolExecutor = (MagnetRONScheduledThreadPoolExecutor) getThreadPoolExecutor(); + scheduledThreadPoolExecutor.pause(); + setCurrentStatus(Status.PAUSED); + } + } + + } + + private final void onFinished() { + stop(); + final ActionListener listener = getOnFinished(); + if (listener != null) { + try { + listener.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, null)); + } catch (Exception e) { + Thread.currentThread().getUncaughtExceptionHandler().uncaughtException(Thread.currentThread(), e); + } + } + } + + protected abstract void jumpTo(int currentCycleCount); + + public void sleepThread(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/src/org/ntlab/deltaViewer/CollaborationViewer.java b/src/org/ntlab/deltaViewer/CollaborationViewer.java index 19f68a0..7f1583f 100644 --- a/src/org/ntlab/deltaViewer/CollaborationViewer.java +++ b/src/org/ntlab/deltaViewer/CollaborationViewer.java @@ -315,6 +315,7 @@ cell.getGeometry().setY(absolutePointCell.getY()); deltaAnimation.setVertexAnimation(cell, new mxPoint(vo.getInitialX(), vo.getInitialY())); deltaAnimation.startVertexAnimation(); + deltaAnimation.sleepThread(DEFAULT_THREAD_SLEEP_MILLIS); methodExecToVertexMap.get(me).getArguments().remove(vo); } }else if (locals.size() != 0) { @@ -327,6 +328,7 @@ cell.getGeometry().setY(absolutePointCell.getY()); deltaAnimation.setVertexAnimation(cell, new mxPoint(vo.getInitialX(), vo.getInitialY())); deltaAnimation.startVertexAnimation(); + deltaAnimation.sleepThread(DEFAULT_THREAD_SLEEP_MILLIS); methodExecToVertexMap.get(me).getLocals().remove(vo); } } @@ -336,7 +338,7 @@ } finally { mxgraph.getModel().endUpdate(); } - update(); + update(); } /** @@ -350,14 +352,14 @@ // Create vertices(mxGraph) and objectVertices. List refList = objectCallGraph.getReferences(); int ocgSize = refList.size(); - double vertexObjWidth = VERTEX_OBJECT_SIZE.getWidth(); - double vertexObjHeight = VERTEX_OBJECT_SIZE.getHeight(); + double vertexObjWidth = DEFAULT_OBJECT_VERTEX_SIZE.getWidth(); + double vertexObjHeight = DEFAULT_OBJECT_VERTEX_SIZE.getHeight(); { MethodExecution coordinator = objectCallGraph.getStartPoints().get(0); String coordinatorObjId = coordinator.getThisObjId(); String coordinatorClassName = coordinator.getThisClassName(); - Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, coordinatorObjId, coordinatorClassName, 0, 0, VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. + Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, coordinatorObjId, coordinatorClassName, 0, 0, DEFAULT_OBJECT_VERTEX_SIZE.getWidth(), DEFAULT_OBJECT_VERTEX_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. objectToVertexMap.put(coordinatorObjId, new ObjectVertex(coordinatorClassName, vertex, 0, 0)); } diff --git a/src/org/ntlab/deltaViewer/DeltaAnimation.java b/src/org/ntlab/deltaViewer/DeltaAnimation.java index 76d9c25..0439c30 100644 --- a/src/org/ntlab/deltaViewer/DeltaAnimation.java +++ b/src/org/ntlab/deltaViewer/DeltaAnimation.java @@ -1,27 +1,18 @@ 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 java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; -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. + * Delta animation for MagnetRON. * * @author Nitta Lab. */ @@ -31,7 +22,6 @@ private mxGraphComponent mxgraphComponent; private Graphics2D graphics2D; - private Timer timer; private static int FINAL_STEP_COUNT = 10; private mxICell sourceCell; @@ -50,7 +40,7 @@ private Dimension updateDimension = new Dimension(); private double scale = 1; - + /** * @param mxgraph * @param mxgraphComponent @@ -67,9 +57,9 @@ public void setScale(double zoomLevel) { this.scale = zoomLevel; } - + /** - * Set to move animation sourcell vertex to targetPoint. + * Set to move animation source cell vertex to targetPoint. * * @param sourceCell Vertex. * @param targetPoint XY coordinates. @@ -78,8 +68,6 @@ 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(); } @@ -99,7 +87,7 @@ } /** - * Set to move animation sourcell vertex clone to targetPoint, reduce edge length. + * Set to move animation source cell vertex clone to targetPoint, reduce edge length. * * @param sourceCell Remove sourceCell vertex clone. * @param targetPoint @@ -148,82 +136,65 @@ } /** - * Start animation to move sourcell vertex to targetPoint for 10 sec. + * Start animation to move source cell vertex to targetPoint for 10sec. */ public void startVertexAnimation() { - timer = new Timer(); - timer.schedule(new TimerTask() { + ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1); + scheduledThreadPoolExecutor.scheduleWithFixedDelay(new TimerTask() { int stepCount = 0; @Override public void run() { if(stepCount < FINAL_STEP_COUNT) { updateVertexAnimation(); + System.out.println("updateVertexAnimation: " + stepCount + " " + curPoint.getX()); stepCount++; if(stepCount >= FINAL_STEP_COUNT){ - timer.cancel(); + scheduledThreadPoolExecutor.shutdown(); } } } - }, 0, 100); - try { - Thread.sleep(1001); - } catch (InterruptedException e) { - e.printStackTrace(); - } + }, 0, 100, TimeUnit.MILLISECONDS); +// sleepThread(doThreadSleep); +// try { +// Thread.sleep(1001); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } } /** - * Start stretch(expand) animation of edge from sourcePoint to targetPoint for 10 sec. + * Start stretch(expand) animation of edge from sourcePoint to targetPoint for 10sec. */ public void startExpandEdgeAnimation() { - timer = new Timer(); - timer.schedule(new TimerTask() { + ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1); + scheduledThreadPoolExecutor.scheduleWithFixedDelay(new TimerTask() { int stepCount = 0; @Override public void run() { if(stepCount < FINAL_STEP_COUNT) { updateExpandEdgeAnimation(); - System.out.println(stepCount + ": " + curPoint.getX()); + System.out.println("updateExpandEdgeAnimation: " + stepCount + " " + curPoint.getX()); stepCount++; if(stepCount >= FINAL_STEP_COUNT){ - timer.cancel(); + scheduledThreadPoolExecutor.shutdown(); } - } + } } - }, 0, 100); - try { - Thread.sleep(1001); - } 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); + }, 0, 100, TimeUnit.MILLISECONDS); +// sleepThread(doThreadSleep); // try { // Thread.sleep(1001); // } catch (InterruptedException e) { // e.printStackTrace(); // } + } + + /** + * Start move animation source cell vertex clone to targetPoint, reduce edge length for 10sec. + */ + public void startReductionEdgeAnimation() { ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1); scheduledThreadPoolExecutor.scheduleWithFixedDelay(new TimerTask() { int stepCount = 0; @@ -235,46 +206,25 @@ System.out.println(stepCount + ": " + curPoint.getX()); stepCount++; if(stepCount >= FINAL_STEP_COUNT){ - timer.cancel(); scheduledThreadPoolExecutor.shutdown(); } } } }, 0, 100, TimeUnit.MILLISECONDS); - try { - System.out.println("Thread.sleep()"); - Thread.sleep(1001); - System.out.println("Thread.start()"); - } 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); +// sleepThread(doThreadSleep); // try { -// Thread.sleep(1000); +// System.out.println("Thread.sleep()"); +// Thread.sleep(1001); +// System.out.println("Thread.start()"); // } catch (InterruptedException e) { // e.printStackTrace(); // } + } + /** + * Start animation resize vertex for 10sec. + */ + public void startResizeVertexAnimation() { ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(1); scheduledThreadPoolExecutor.scheduleWithFixedDelay(new TimerTask() { int stepCount = 0; @@ -286,23 +236,23 @@ System.out.println(stepCount + ": " + curDimension.width); stepCount++; if(stepCount >= FINAL_STEP_COUNT){ - timer.cancel(); scheduledThreadPoolExecutor.shutdown(); } } } }, 0, 100, TimeUnit.MILLISECONDS); - try { - System.out.println("Thread.sleep()"); - Thread.sleep(1001); - System.out.println("Thread.start()"); - } catch (InterruptedException e) { - e.printStackTrace(); - } +// sleepThread(doThreadSleep); +// try { +// System.out.println("Thread.sleep()"); +// Thread.sleep(1001); +// System.out.println("Thread.start()"); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } } /** - * Update animation to move sourcell vertex to targetPoint every second. + * Update animation to move source cell 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. @@ -382,7 +332,6 @@ 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); @@ -393,4 +342,13 @@ } mxgraphComponent.refresh(); } + + public void sleepThread(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } diff --git a/src/org/ntlab/deltaViewer/DeltaViewer.java b/src/org/ntlab/deltaViewer/DeltaViewer.java index 9e218f1..5004659 100644 --- a/src/org/ntlab/deltaViewer/DeltaViewer.java +++ b/src/org/ntlab/deltaViewer/DeltaViewer.java @@ -347,7 +347,7 @@ System.out.println("coordinator: " + coordinatorClassName + ", " + coordinatorObjId); coordinatorPoint.setX(coordinatorPoint.getX() + time * 2); xCor += time * 2; - Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, coordinatorObjId, coordinatorClassName, xCor + (time * ((srcSideSize - 1) - i)), yCor + (time * ((srcSideSize - 1) - i)), VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. + Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, coordinatorObjId, coordinatorClassName, xCor + (time * ((srcSideSize - 1) - i)), yCor + (time * ((srcSideSize - 1) - i)), DEFAULT_OBJECT_VERTEX_SIZE.getWidth(), DEFAULT_OBJECT_VERTEX_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. objectToVertexMap.put(coordinatorObjId, new ObjectVertex(coordinatorClassName, vertex, xCor + (time * ((srcSideSize - 1) - i)), yCor + (time * ((srcSideSize - 1) - i)))); srcSideSize++; } @@ -358,7 +358,7 @@ if (srcClassName.contains("[L")) { srcClassName = formatArrayName(srcClassName); } - Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, ref.getSrcObjectId(), srcClassName, xCor + (time * ((srcSideSize - 1) - i)), yCor + (time * ((srcSideSize - 1) - i)), VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. + Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, ref.getSrcObjectId(), srcClassName, xCor + (time * ((srcSideSize - 1) - i)), yCor + (time * ((srcSideSize - 1) - i)), DEFAULT_OBJECT_VERTEX_SIZE.getWidth(), DEFAULT_OBJECT_VERTEX_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. objectToVertexMap.put(ref.getSrcObjectId(), new ObjectVertex(ref.getSrcClassName(), vertex, xCor + (time * ((srcSideSize - 1) - i)), yCor + (time * ((srcSideSize - 1) - i)))); } if (!objectToVertexMap.containsKey(ref.getDstObjectId())) { @@ -367,7 +367,7 @@ if (dstClassName.contains("[L")) { dstClassName = formatArrayName(dstClassName); } - Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, ref.getDstObjectId(), dstClassName, xCor + (time * (srcSideSize - i)), yCor + (time * (srcSideSize - i)), VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. + Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, ref.getDstObjectId(), dstClassName, xCor + (time * (srcSideSize - i)), yCor + (time * (srcSideSize - i)), DEFAULT_OBJECT_VERTEX_SIZE.getWidth(), DEFAULT_OBJECT_VERTEX_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. objectToVertexMap.put(ref.getDstObjectId(), new ObjectVertex(ref.getDstClassName(), vertex, xCor + (time * (srcSideSize - i)), yCor + (time * (srcSideSize - i)))); } } else { @@ -375,7 +375,7 @@ if (srcClassName.contains("[L")) { srcClassName = formatArrayName(srcClassName); } - Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, ref.getSrcObjectId(), srcClassName, xCor + (time * ((srcSideSize - 1) - i)), yCor + (time * ((srcSideSize - 1) - i)), VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. + Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, ref.getSrcObjectId(), srcClassName, xCor + (time * ((srcSideSize - 1) - i)), yCor + (time * ((srcSideSize - 1) - i)), DEFAULT_OBJECT_VERTEX_SIZE.getWidth(), DEFAULT_OBJECT_VERTEX_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. objectToVertexMap.put(ref.getSrcObjectId(), new ObjectVertex(ref.getSrcClassName(), vertex, xCor + (time * ((srcSideSize - 1) - i)), yCor + (time * ((srcSideSize - 1) - i)))); objectToVertexMap.put(ref.getDstObjectId(), new ObjectVertex(ref.getDstClassName(), null, xCor + (time * (srcSideSize - i)), yCor + (time * (srcSideSize - i)))); } @@ -391,7 +391,7 @@ coordinatorPoint.setX(coordinatorPoint.getX() + time * 2); xCor += time * 2; System.out.println(coordinatorPoint.getX() + ", " + xCor); - Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, coordinatorObjId, coordinatorClassName, xCor - (time * (dstSideSize - i + cnt)), yCor + (time * (dstSideSize - i + cnt)), VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. + Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, coordinatorObjId, coordinatorClassName, xCor - (time * (dstSideSize - i + cnt)), yCor + (time * (dstSideSize - i + cnt)), DEFAULT_OBJECT_VERTEX_SIZE.getWidth(), DEFAULT_OBJECT_VERTEX_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. objectToVertexMap.put(coordinatorObjId, new ObjectVertex(coordinatorClassName, vertex, xCor - (time * (dstSideSize - i + cnt)), yCor + (time * (dstSideSize - i + cnt)))); dstSideSize++; } @@ -402,7 +402,7 @@ if (srcClassName.contains("[L")) { srcClassName = formatArrayName(srcClassName); } - Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, ref.getSrcObjectId(), srcClassName, xCor - (time * (dstSideSize - i + cnt)), yCor + (time * (dstSideSize - i + cnt)), VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. + Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, ref.getSrcObjectId(), srcClassName, xCor - (time * (dstSideSize - i + cnt)), yCor + (time * (dstSideSize - i + cnt)), DEFAULT_OBJECT_VERTEX_SIZE.getWidth(), DEFAULT_OBJECT_VERTEX_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. objectToVertexMap.put(ref.getSrcObjectId(), new ObjectVertex(ref.getSrcClassName(), vertex, xCor - (time * (dstSideSize - i + cnt)), yCor + (time * (dstSideSize - i + cnt)))); cnt++; } @@ -411,7 +411,7 @@ if (dstClassName.contains("[L")) { dstClassName = formatArrayName(dstClassName); } - Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, ref.getDstObjectId(), dstClassName, xCor - (time * (dstSideSize - i + cnt)), yCor + (time * (dstSideSize - i + cnt)), VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. + Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, ref.getDstObjectId(), dstClassName, xCor - (time * (dstSideSize - i + cnt)), yCor + (time * (dstSideSize - i + cnt)), DEFAULT_OBJECT_VERTEX_SIZE.getWidth(), DEFAULT_OBJECT_VERTEX_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. objectToVertexMap.put(ref.getDstObjectId(), new ObjectVertex(ref.getDstClassName(), vertex, xCor - (time * (dstSideSize - i + cnt)), yCor + (time * (dstSideSize - i + cnt)))); } } else { diff --git a/src/org/ntlab/deltaViewer/MagnetRONScheduledThreadPoolExecutor.java b/src/org/ntlab/deltaViewer/MagnetRONScheduledThreadPoolExecutor.java new file mode 100644 index 0000000..2b53e83 --- /dev/null +++ b/src/org/ntlab/deltaViewer/MagnetRONScheduledThreadPoolExecutor.java @@ -0,0 +1,56 @@ +package org.ntlab.deltaViewer; + +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +/** + * + * + * @author Nitta Lab. + */ +public class MagnetRONScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor { + + private boolean isPaused; + private ReentrantLock pauseLock = new ReentrantLock(); + private Condition unpaused = pauseLock.newCondition(); + + public MagnetRONScheduledThreadPoolExecutor(int corePoolSize) { + super(corePoolSize); + } + + protected void beforeExecute(Thread t, Runnable r) { + super.beforeExecute(t, r); + pauseLock.lock(); + try { + while (isPaused) unpaused.await(); + } catch (InterruptedException ie) { + t.interrupt(); + } finally { + pauseLock.unlock(); + } + } + + public void stop() { + } + + public void pause() { + pauseLock.lock(); + try { + isPaused = true; + } finally { + pauseLock.unlock(); + } + } + + public void resume() { + pauseLock.lock(); + try { + isPaused = false; + unpaused.signalAll(); + } finally { + pauseLock.unlock(); + } + } + +} diff --git a/src/org/ntlab/deltaViewer/MagnetRONViewer.java b/src/org/ntlab/deltaViewer/MagnetRONViewer.java index 287aefa..a022c18 100644 --- a/src/org/ntlab/deltaViewer/MagnetRONViewer.java +++ b/src/org/ntlab/deltaViewer/MagnetRONViewer.java @@ -4,7 +4,9 @@ import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Point; +import java.awt.event.ActionListener; import java.awt.geom.Path2D; +import java.awt.geom.Point2D; import java.util.AbstractMap; import java.util.ArrayList; import java.util.Collections; @@ -13,11 +15,13 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.concurrent.ThreadPoolExecutor; import javax.swing.JPanel; import org.jgrapht.graph.DefaultEdge; import org.jgrapht.graph.DirectedWeightedPseudograph; +import org.ntlab.animations.EdgeAnimation; import org.ntlab.deltaExtractor.Alias; import org.ntlab.deltaExtractor.IAliasCollector; import org.ntlab.deltaExtractor.Alias.AliasType; @@ -42,13 +46,26 @@ import com.mxgraph.util.mxUtils; import com.mxgraph.view.mxCellState; -abstract public class MagnetRONViewer extends JPanel { +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.util.Duration; - protected static Dimension DEFAULT_SIZE = new Dimension(1300, 700); +/** + + * + * @author Nitta Lab. + */ +public abstract class MagnetRONViewer extends JPanel { + + private static final long serialVersionUID = -6828987937804142956L; + + protected static Dimension DEFAULT_WINDOW_SIZE = new Dimension(1300, 700); protected static String WINDOW_TITLE = "Delta Viewer"; - protected static Dimension VERTEX_OBJECT_SIZE = new Dimension(70, 70); - protected static Dimension VERTEX_METHOD_EXECUTION_SIZE = new Dimension(55, 20); + protected static Dimension DEFAULT_OBJECT_VERTEX_SIZE = new Dimension(70, 70); + protected static Dimension DEFAULT_METHOD_EXECUTION_VERTEX_SIZE = new Dimension(55, 20); + + protected static long DEFAULT_THREAD_SLEEP_MILLIS = 1001; protected IAliasCollector aliasCollector; @@ -61,9 +78,11 @@ protected mxICell mxDefaultParent; protected mxGraphComponent mxgraphComponent; + protected ThreadPoolExecutor threadPoolExecutor; protected DeltaAnimation deltaAnimation; + protected EdgeAnimation edgeAnimation; protected int curFrame = 0; - + public MagnetRONViewer() { mxgraph = new DeltaGraphAdapter(new DirectedWeightedPseudograph(DefaultEdge.class)); mxDefaultParent = (mxCell)mxgraph.getDefaultParent(); @@ -72,10 +91,16 @@ return new CurvedCanvas(this); } }; - deltaAnimation = new DeltaAnimation(mxgraph, mxgraphComponent); - mxgraphComponent.setPreferredSize(DEFAULT_SIZE); + + deltaAnimation = new DeltaAnimation(mxgraph, getGraphComponent()); + edgeAnimation = new EdgeAnimation(mxgraph, getGraphComponent()); + edgeAnimation.setTotalCycleCount(10); + edgeAnimation.setDelay(100); + threadPoolExecutor = new MagnetRONScheduledThreadPoolExecutor(2); + + getGraphComponent().setPreferredSize(DEFAULT_WINDOW_SIZE); setLayout(new BorderLayout()); - add(mxgraphComponent, BorderLayout.CENTER); + add(getGraphComponent(), BorderLayout.CENTER); } public mxGraphComponent getGraphComponent() { @@ -85,7 +110,6 @@ public void clear() { mxgraph.getModel().beginUpdate(); try { - System.out.println("Clear: "); for (ObjectVertex ov: objectToVertexMap.values()) { mxICell ovCell = (mxICell)ov.getCell(); if (ovCell != null) { @@ -96,19 +120,14 @@ } } } - } finally { - mxgraph.getModel().endUpdate(); - } - objectToVertexMap.clear(); - methodExecToVertexMap.clear(); - edgeMap.clear(); - curFrame = 0; - mxgraph.getModel().beginUpdate(); - try { mxgraph.removeCells(mxgraph.getChildVertices(mxDefaultParent)); } finally { mxgraph.getModel().endUpdate(); } + curFrame = 0; + objectToVertexMap.clear(); + methodExecToVertexMap.clear(); + edgeMap.clear(); } abstract public void initAnimation(); @@ -116,14 +135,14 @@ /** * Step to animation of specified alias. * - * @param alias Alias type and occurrence point etc. + * @param alias: alias type and occurrence point etc. */ abstract public void stepToAnimation(Alias alias); /** * Parent : Step to animation of specified numFrame. * - * @param numFrame Current animation frame. + * @param numFrame: current animation frame */ abstract public void stepToAnimation(int numFrame); @@ -137,6 +156,7 @@ for (int i = fromFrame; i <= toFrame; i++) { List aliasList = new ArrayList<>(aliasCollector.getAliasList()); Alias alias = aliasList.get(i); + // Test code (will be deleted) System.out.println("\r\n" + i + ": " + alias.getAliasType().toString()); System.out.println(alias.getObjectId() + ", " + alias.getMethodSignature() + " l." + alias.getLineNo()); switch(alias.getAliasType()) { @@ -150,7 +170,7 @@ update(); break; case CONSTRACTOR_INVOCATION: - // TODO When called after RECEIVER. + // TODO: Confirm the program behavior when called after RECEIVER. createObjectVertexOnConstractor(alias); createMethodExecutionVertex(alias.getObjectId(), ((MethodInvocation)alias.getOccurrencePoint().getStatement()).getCallerSideMethodName(), ((MethodInvocation)alias.getOccurrencePoint().getStatement()).getCalledMethodExecution()); update(); @@ -172,7 +192,7 @@ } break; case RECEIVER: - // Make VertexMethodExecution of called method execution. + // Make {@code MethodExecutionVertex} of called method execution. MethodExecution calledMethodExec = ((MethodInvocation) alias.getOccurrencePoint().getStatement()).getCalledMethodExecution(); if (!methodExecToVertexMap.containsKey(calledMethodExec)) { MethodExecution methodExec = alias.getMethodExecution(); @@ -189,47 +209,58 @@ break; } curFrame = i + 1; + // Test code (will be deleted) outputLog(); } } /** - * Create ObjectVertex when CONSTRACTOR_INVOCATION. + * Create {@code ObjectVertex} when CONSTRACTOR_INVOCATION. + * * @param alias */ protected void createObjectVertexOnConstractor(Alias alias) { ObjectVertex objectVertex = objectToVertexMap.get(alias.getObjectId()); - String sourceObjId = alias.getMethodExecution().getThisObjId(); - mxICell sourceCell = (mxICell)objectToVertexMap.get(sourceObjId).getCell(); - double sourceWidth = sourceCell.getGeometry().getWidth(); - double sourceHeight = sourceCell.getGeometry().getHeight(); - double overlapWidth = sourceWidth * Math.sqrt(2) * 0.1; - double overlapHeight = sourceHeight - (sourceHeight * Math.sqrt(2) * 0.1); - MethodInvocation methodInvocation; + MethodExecution methodExec = alias.getMethodExecution(); + String srcObjId = alias.getMethodExecution().getThisObjId(); + mxICell srcCell = (mxICell)objectToVertexMap.get(srcObjId).getCell(); + double srcWidth = srcCell.getGeometry().getWidth(); + double srcHeight = srcCell.getGeometry().getHeight(); + double overlapWidth = srcWidth * Math.sqrt(2) * 0.1; + double overlapHeight = srcHeight - (srcHeight * Math.sqrt(2) * 0.1); + Point srcCellAbsPt = getAbsolutePointforCell(srcCell); + MethodInvocation methodInv; String fieldName = null; - if (!alias.getMethodExecution().isCollectionType() && alias.getOccurrencePoint().getStatement() != null) { - methodInvocation = (MethodInvocation)alias.getOccurrencePoint().getStatement(); - fieldName = methodInvocation.getCallerSideMethodName(); + if (!methodExec.isCollectionType() + && alias.getOccurrencePoint().getStatement() != null) { + methodInv = (MethodInvocation)alias.getOccurrencePoint().getStatement(); + fieldName = methodInv.getCallerSideMethodName(); } - Point absPtSrcCell = getAbsolutePointforCell(sourceCell); mxgraph.getModel().beginUpdate(); try { - Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, alias.getObjectId(), objectVertex.getLabel(), absPtSrcCell.getX() + overlapWidth, absPtSrcCell.getY() + overlapHeight, VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. -// Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, objectVertex.getLabel(), objectVertex.getLabel(), absPtSrcCell.getX() + overlapWidth, absPtSrcCell.getY() + overlapHeight, VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. - objectVertex.setCell(vertex); - Object edge = mxgraph.insertDeltaEdge(mxDefaultParent, fieldName, null, sourceCell, vertex); - setEdgePoint((mxCell)edge, absPtSrcCell, objectVertex.getInitialPoint()); - edgeMap.put(alias.getMethodExecution().getThisClassName() + "." + fieldName, new Edge(fieldName, TypeName.Create, edge)); - setCellsStyle(); - deltaAnimation.setVertexAnimation((mxICell)vertex, new mxPoint(objectVertex.getInitialX(), objectVertex.getInitialY())); + // Creates a white cell of {@code ObjectVertex}. + mxICell ovCell = + (mxICell) mxgraph.insertDeltaVertex(mxDefaultParent, alias.getObjectId(), objectVertex.getLabel(), + srcCellAbsPt.getX() + overlapWidth, srcCellAbsPt.getY() + overlapHeight, + DEFAULT_OBJECT_VERTEX_SIZE.getWidth(), DEFAULT_OBJECT_VERTEX_SIZE.getHeight(), + "fillColor=white"); + objectVertex.setCell(ovCell); + mxICell edge = (mxICell) mxgraph.insertDeltaEdge(mxDefaultParent, fieldName, null, srcCell, ovCell); +// setEdgePoint((mxCell)edge, srcCellAbsPt, objectVertex.getInitialPoint()); + edgeMap.put(methodExec.getThisClassName() + "." + fieldName, new Edge(fieldName, TypeName.Create, edge)); +// setCellsStyle(); + update(); + deltaAnimation.setVertexAnimation(ovCell, new mxPoint(objectVertex.getInitialX(), objectVertex.getInitialY())); deltaAnimation.startVertexAnimation(); + deltaAnimation.sleepThread(1001); } finally { mxgraph.getModel().endUpdate(); } } /** - * Create ObjectVertex when CONSTRACTOR_INVOCATION is preceded by FORMAL_PARAMETER. + * Create {@code ObjectVertex} when CONSTRACTOR_INVOCATION is preceded by FORMAL_PARAMETER. + * * @param alias */ protected void createObjectVertexOnConstractorByFormalParameter(Alias alias) { @@ -241,7 +272,7 @@ double srcHeight = srcCell.getGeometry().getHeight(); double overlapWidth = srcWidth * Math.sqrt(2) * 0.1; double overlapHeight = srcHeight - (srcHeight * Math.sqrt(2) * 0.1); - Point absPtSrcCell = getAbsolutePointforCell(srcCell); + Point srcCellAbsPt = getAbsolutePointforCell(srcCell); MethodInvocation methodInv; String fieldName = null; if (!methodExec.isCollectionType() && alias.getOccurrencePoint().getStatement() != null) { @@ -250,311 +281,309 @@ } mxgraph.getModel().beginUpdate(); try { - Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, objectVertex.getLabel(), objectVertex.getLabel(), absPtSrcCell.getX() + overlapWidth, absPtSrcCell.getY() + overlapHeight, VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. - objectVertex.setCell(vertex); - Object edge = mxgraph.insertDeltaEdge(mxDefaultParent, fieldName, null, srcCell, vertex); - setEdgePoint((mxCell)edge, absPtSrcCell, objectVertex.getInitialPoint()); + // Creates a white cell of {@code ObjectVertex}. + mxICell ovCell = + (mxICell) mxgraph.insertDeltaVertex(mxDefaultParent, objectVertex.getLabel(), objectVertex.getLabel(), + srcCellAbsPt.getX() + overlapWidth, srcCellAbsPt.getY() + overlapHeight, + DEFAULT_OBJECT_VERTEX_SIZE.getWidth(), DEFAULT_OBJECT_VERTEX_SIZE.getHeight(), + "fillColor=white"); + objectVertex.setCell(ovCell); + mxICell edge = (mxICell) mxgraph.insertDeltaEdge(mxDefaultParent, fieldName, null, srcCell, ovCell); + setEdgePoint(edge, srcCellAbsPt, objectVertex.getInitialPoint()); edgeMap.put(methodExec.getThisClassName() + "." + fieldName, new Edge(fieldName, TypeName.Create, edge)); - setCellsStyle(); - deltaAnimation.setVertexAnimation((mxICell)vertex, new mxPoint(objectVertex.getInitialX(), objectVertex.getInitialY())); +// setCellsStyle(); + update(); + deltaAnimation.setVertexAnimation(ovCell, new mxPoint(objectVertex.getInitialX(), objectVertex.getInitialY())); deltaAnimation.startVertexAnimation(); + deltaAnimation.sleepThread(1001); } finally { mxgraph.getModel().endUpdate(); } } + /** + * + * @param fieldUpdateStatement + * @param fieldName + */ protected void createObjectRefrence(FieldUpdate fieldUpdateStatement, String fieldName) { - String sourceObjectId = fieldUpdateStatement.getContainerObjId(); - String targetObjectId = fieldUpdateStatement.getValueObjId(); - mxICell sourceCell = (mxICell)objectToVertexMap.get(sourceObjectId).getCell(); - mxICell targetCell = (mxICell)objectToVertexMap.get(targetObjectId).getCell(); - Point absolutePointTargetCell = getAbsolutePointforCell(targetCell); + String srcObjId = fieldUpdateStatement.getContainerObjId(); + String dstObjId = fieldUpdateStatement.getValueObjId(); + mxICell dstCell = (mxICell)objectToVertexMap.get(dstObjId).getCell(); + Point dstCellAbsPt = getAbsolutePointforCell(dstCell); - targetCell.getParent().remove(targetCell); - targetCell.setParent(mxDefaultParent); - targetCell.getGeometry().setX(absolutePointTargetCell.getX()); - targetCell.getGeometry().setY(absolutePointTargetCell.getY()); - Object edge = mxgraph.insertDeltaEdge(mxDefaultParent, fieldUpdateStatement.getFieldName(), fieldName, objectToVertexMap.get(sourceObjectId).getCell(), objectToVertexMap.get(targetObjectId).getCell()); -// ((mxCell)edge).setStyle("exitX=0;exitY=0.5;exitPerimeter=1;entryX=1;entryY=0.5;entryPerimeter=1;strokeColor=red;"); - ((mxCell)edge).setStyle("strokeColor=red;"); -// mxgraph.orderCells(true, new Object[] {edge}); - edgeMap.put(fieldUpdateStatement.getFieldName(), new Edge(fieldName, TypeName.Reference, edge)); - // System.out.println("last" + objectToVertexMap.get(targetObjectId).getInitialX() + ", " + objectToVertexMap.get(targetObjectId).getInitialY()); - deltaAnimation.setVertexAnimation(targetCell, new mxPoint(objectToVertexMap.get(targetObjectId).getInitialX(), objectToVertexMap.get(targetObjectId).getInitialY())); - deltaAnimation.startVertexAnimation(); - targetCell.getGeometry().setX(objectToVertexMap.get(targetObjectId).getInitialX()); - targetCell.getGeometry().setY(objectToVertexMap.get(targetObjectId).getInitialY()); + mxgraph.getModel().beginUpdate(); + try { + dstCell.getParent().remove(dstCell); + dstCell.setParent(mxDefaultParent); + dstCell.getGeometry().setX(dstCellAbsPt.getX()); + dstCell.getGeometry().setY(dstCellAbsPt.getY()); + mxICell edge = + (mxICell) mxgraph.insertDeltaEdge(mxDefaultParent, fieldUpdateStatement.getFieldName(), fieldName, + objectToVertexMap.get(srcObjId).getCell(), objectToVertexMap.get(dstObjId).getCell()); + edge.setStyle("strokeColor=red;"); + // mxgraph.orderCells(true, new Object[] {edge}); + edgeMap.put(fieldUpdateStatement.getFieldName(), new Edge(fieldName, TypeName.Reference, edge)); + deltaAnimation.setVertexAnimation(dstCell, new mxPoint(objectToVertexMap.get(dstObjId).getInitialX(), objectToVertexMap.get(dstObjId).getInitialY())); + deltaAnimation.startVertexAnimation(); + deltaAnimation.sleepThread(DEFAULT_THREAD_SLEEP_MILLIS); + dstCell.getGeometry().setX(objectToVertexMap.get(dstObjId).getInitialX()); + dstCell.getGeometry().setY(objectToVertexMap.get(dstObjId).getInitialY()); + } finally { + mxgraph.getModel().endUpdate(); + } } - protected void createObjectRefrence(String srcClassName, String srcObjId, String tgtObjId) { - mxICell targetCell; -// if (objectToVertexMap.containsKey(targetObjId)) { - targetCell = (mxICell)objectToVertexMap.get(tgtObjId).getCell(); -// } else { -// targetObjId = methodExec.getCallerMethodExecution().getArguments().get(0).getId(); -// targetCell = (mxICell)objectToVertexMap.get(targetObjId).getCell(); -// } - Point absolutePointTargetCell = getAbsolutePointforCell(targetCell); + /** + * + * @param sourceClassName + * @param sourceObjectId + * @param destinationObjectId + */ + protected void createObjectRefrence(String sourceClassName, String sourceObjectId, String destinationObjectId) { + mxICell dstCell = (mxICell)objectToVertexMap.get(destinationObjectId).getCell(); + Point dstCellAbsPt = getAbsolutePointforCell(dstCell); // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. mxgraph.getModel().beginUpdate(); try { - targetCell.getParent().remove(targetCell); - targetCell.setParent(mxDefaultParent); - targetCell.getGeometry().setX(absolutePointTargetCell.getX()); - targetCell.getGeometry().setY(absolutePointTargetCell.getY()); - Object edge = mxgraph.insertDeltaEdge(mxDefaultParent, tgtObjId, null, objectToVertexMap.get(srcObjId).getCell(), objectToVertexMap.get(tgtObjId).getCell()); -// ((mxCell)edge).setStyle("exitX=0;exitY=0.5;exitPerimeter=1;entryX=1;entryY=0.5;entryPerimeter=1;strokeColor=red;"); + dstCell.getParent().remove(dstCell); + dstCell.setParent(mxDefaultParent); + dstCell.getGeometry().setX(dstCellAbsPt.getX()); + dstCell.getGeometry().setY(dstCellAbsPt.getY()); + mxICell edge = + (mxICell) mxgraph.insertDeltaEdge(mxDefaultParent, destinationObjectId, null, + objectToVertexMap.get(sourceObjectId).getCell(), objectToVertexMap.get(destinationObjectId).getCell()); ((mxCell)edge).setStyle("strokeColor=red;"); -// mxgraph.orderCells(true, new Object[] {edge}); - edgeMap.put(tgtObjId, new Edge(null, TypeName.Reference, edge)); -// System.out.println("last" + objectToVertexMap.get(targetObjectId).getInitialX() + ", " + objectToVertexMap.get(targetObjectId).getInitialY()); - deltaAnimation.setVertexAnimation(targetCell, new mxPoint(objectToVertexMap.get(tgtObjId).getInitialX(), objectToVertexMap.get(tgtObjId).getInitialY())); + edgeMap.put(destinationObjectId, new Edge(null, TypeName.Reference, edge)); + deltaAnimation.setVertexAnimation(dstCell, new mxPoint(objectToVertexMap.get(destinationObjectId).getInitialX(), objectToVertexMap.get(destinationObjectId).getInitialY())); deltaAnimation.startVertexAnimation(); - targetCell.getGeometry().setX(objectToVertexMap.get(tgtObjId).getInitialX()); - targetCell.getGeometry().setY(objectToVertexMap.get(tgtObjId).getInitialY()); + deltaAnimation.sleepThread(1001); + dstCell.getGeometry().setX(objectToVertexMap.get(destinationObjectId).getInitialX()); + dstCell.getGeometry().setY(objectToVertexMap.get(destinationObjectId).getInitialY()); } finally { mxgraph.getModel().endUpdate(); } - - System.out.println("rTHIS " + srcClassName + ", " + tgtObjId); + // Test code (will be deleted) + System.out.println("rTHIS " + sourceClassName + ", " + destinationObjectId); } /** - * SourceVertex move targetVertex. + * Move to position of destination {@code ObjectVertex} from source {@code ObjectVertex}. * * @param alias */ protected void moveObjectVertex(Alias alias) { - // sourceVertex - ObjectVertex sourceObjectVertex = objectToVertexMap.get(alias.getObjectId()); + // source {@code ObjectVertex} + ObjectVertex srcObjVertex = objectToVertexMap.get(alias.getObjectId()); if (alias.getMethodExecution().isStatic() && !methodExecToVertexMap.containsKey(alias.getMethodExecution())) { createMethodExecutionVertex(alias.getObjectId(), alias.getMethodExecution().getSignature(), alias.getMethodExecution()); } - // targetVertex - MethodExecutionVertex targetMethodExecVertex = methodExecToVertexMap.get(alias.getMethodExecution()); - System.out.println("moveObjectVertex: " + targetMethodExecVertex); + // destination {@code ObjectVertex} + MethodExecutionVertex dstMethodExecVertex = methodExecToVertexMap.get(alias.getMethodExecution()); + // Test code (will be deleted) + System.out.println("moveObjectVertex: " + dstMethodExecVertex); System.out.println("moveObjectVertex: " + alias.getMethodExecution().isStatic()); - moveObjectVertex(alias, sourceObjectVertex, targetMethodExecVertex); + moveObjectVertex(alias, srcObjVertex, dstMethodExecVertex); updateObjectVertices(); } /** - * Parent : Source VertexObject move target VertexMethodExecution. + * Parent: Move to position of destination {@code ObjectVertex} from source {@code ObjectVertex}. * * @param alias - * @param sourceVertexObject Source VertexObject. - * @param targetVertexMethodExec Target VertexMethodExecution. + * @param sourceVertexObject: source {@code ObjectVertex} + * @param destinationVertexMethodExec: destination {@code MethodExecutionVertex} */ - private void moveObjectVertex(Alias alias, ObjectVertex sourceVertexObject, MethodExecutionVertex targetVertexMethodExec) { + private void moveObjectVertex(Alias alias, ObjectVertex sourceObjectVertex, MethodExecutionVertex destinationMethodExecutionVertex) { MethodExecution methodExec = alias.getMethodExecution(); if (alias.getAliasType().equals(AliasType.RETURN_VALUE) || alias.getAliasType().equals(AliasType.METHOD_INVOCATION)) { - if (sourceVertexObject.getCell() == null && methodExec.isCollectionType()) { + if (sourceObjectVertex.getCell() == null && methodExec.isCollectionType()) { if (methodExec.getArguments().isEmpty()) { createObjectVertexOnConstractor(alias); } else { createObjectVertexOnConstractorByFormalParameter(alias); } } - moveLocalObjectVertex(methodExec, sourceVertexObject, targetVertexMethodExec); + if (alias.getAliasType().equals(AliasType.RETURN_VALUE)) { + deltaAnimation.sleepThread(1001); + } + moveLocalObjectVertex(methodExec, sourceObjectVertex, destinationMethodExecutionVertex); } else if (alias.getAliasType().equals(AliasType.FORMAL_PARAMETER)) { - moveArgumentObjectVertex(methodExec, sourceVertexObject, targetVertexMethodExec); + moveArgumentObjectVertex(methodExec, sourceObjectVertex, destinationMethodExecutionVertex); } else if (alias.getAliasType().equals(AliasType.ACTUAL_ARGUMENT)) { - moveActualArgumentObjectVertex(methodExec, sourceVertexObject, targetVertexMethodExec); + moveActualArgumentObjectVertex(methodExec, sourceObjectVertex, destinationMethodExecutionVertex); } } /** - * Source VertexObject move target VertexMethodExecution to Local position from caller MethodExecution. + * Move to local position of destination {@code MethodExecutionVertex} from caller {@code MethodExecution} of source {@code ObjectVertex}. * - * @param callerMethodExec Caller MethodExecution. - * @param sourceVertexObject - * @param targetVertexMethodExec + * @param callerMethodExecution: caller {@code MethodExecution} + * @param sourceObjectVertex + * @param destinationMethodExecutionVertex */ - private void moveLocalObjectVertex(MethodExecution callerMethodExec, ObjectVertex sourceVertexObject, MethodExecutionVertex targetVertexMethodExec) { - mxICell sourceCell = (mxICell)sourceVertexObject.getCell(); - mxICell targetCell = (mxICell) targetVertexMethodExec.getCell(); + private void moveLocalObjectVertex(MethodExecution callerMethodExecution, ObjectVertex sourceObjectVertex, MethodExecutionVertex destinationMethodExecutionVertex) { + mxICell sourceCell = (mxICell)sourceObjectVertex.getCell(); + mxICell destinationCell = (mxICell) destinationMethodExecutionVertex.getCell(); - if (sourceCell == targetCell.getParent()) { - System.out.println("nothing."); + if (sourceCell == destinationCell.getParent()) { + // Test code (will be deleted) + System.out.println("Nothing to moveLocalObjectVertex()."); return; } - // Remove sourceVertex from Locals and Arguments Vertex of MethodExecution's Vertex. - if (methodExecToVertexMap.containsKey(callerMethodExec) && methodExecToVertexMap.get(callerMethodExec).getLocals().contains(sourceVertexObject)) { - methodExecToVertexMap.get(callerMethodExec).getLocals().remove(sourceVertexObject); - System.out.println(methodExecToVertexMap.get(callerMethodExec).getLabel() + " :removeLocal: " + sourceVertexObject.getLabel()); + // Remove sourceObjectVertex from Locals and Arguments of MethodExecution's Vertex. + if (methodExecToVertexMap.containsKey(callerMethodExecution) && methodExecToVertexMap.get(callerMethodExecution).getLocals().contains(sourceObjectVertex)) { + methodExecToVertexMap.get(callerMethodExecution).getLocals().remove(sourceObjectVertex); + // Test code (will be deleted) + System.out.println(methodExecToVertexMap.get(callerMethodExecution).getLabel() + " :removeLocal: " + sourceObjectVertex.getLabel()); } - if (methodExecToVertexMap.containsKey(callerMethodExec) && methodExecToVertexMap.get(callerMethodExec).getArguments().contains(sourceVertexObject)) { - methodExecToVertexMap.get(callerMethodExec).getArguments().remove(sourceVertexObject); - System.out.println(methodExecToVertexMap.get(callerMethodExec).getLabel() + " :removeArgument: " + sourceVertexObject.getLabel()); + if (methodExecToVertexMap.containsKey(callerMethodExecution) && methodExecToVertexMap.get(callerMethodExecution).getArguments().contains(sourceObjectVertex)) { + methodExecToVertexMap.get(callerMethodExecution).getArguments().remove(sourceObjectVertex); + // Test code (will be deleted) + System.out.println(methodExecToVertexMap.get(callerMethodExecution).getLabel() + " :removeArgument: " + sourceObjectVertex.getLabel()); } // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. mxgraph.getModel().beginUpdate(); try { - int time = targetVertexMethodExec.getLocals().size(); - double sourceX = sourceCell.getGeometry().getX(); - double sourceY = sourceCell.getGeometry().getY(); - - // System.out.println(time); + int time = destinationMethodExecutionVertex.getLocals().size(); + double srcCellCoordX = sourceCell.getGeometry().getX(); + double srcCellCoordY = sourceCell.getGeometry().getY(); if(sourceCell.getParent().getValue() != null) { Point absolutePointSourceCell = getAbsolutePointforCell(sourceCell); - sourceX = absolutePointSourceCell.getX(); - sourceY = absolutePointSourceCell.getY(); + srcCellCoordX = absolutePointSourceCell.getX(); + srcCellCoordY = absolutePointSourceCell.getY(); sourceCell.getParent().remove(sourceCell); } mxgraph.orderCells(true, new Object[] {sourceCell}); - sourceCell.setParent(targetCell.getParent()); - targetCell.getParent().insert(sourceCell); + sourceCell.setParent(destinationCell.getParent()); + destinationCell.getParent().insert(sourceCell); + // Test code (will be deleted) System.out.println("moveLocalObjectVertex: " + sourceCell.getId() + " (" + sourceCell.hashCode() + ")" + ", " + sourceCell.getParent().getId() + " (" + sourceCell.getParent().hashCode() + ")"); - System.out.println(" " + targetCell.getId() + " (" + targetCell.hashCode() + ")" + ", " + targetCell.getParent().getId() + " (" + targetCell.getParent().hashCode() + ")"); + System.out.println(" " + destinationCell.getId() + " (" + destinationCell.hashCode() + ")" + ", " + destinationCell.getParent().getId() + " (" + destinationCell.getParent().hashCode() + ")"); - Point absolutePointTargetCell = getAbsolutePointforCell(sourceCell.getParent()); - sourceCell.getGeometry().setX(sourceX - absolutePointTargetCell.getX()); - sourceCell.getGeometry().setY(sourceY - absolutePointTargetCell.getY()); + Point dstCellAbsPt = getAbsolutePointforCell(sourceCell.getParent()); + sourceCell.getGeometry().setX(srcCellCoordX - dstCellAbsPt.getX()); + sourceCell.getGeometry().setY(srcCellCoordY - dstCellAbsPt.getY()); - double sourceWidth = sourceCell.getGeometry().getWidth(); - double sourceHeight = sourceCell.getGeometry().getHeight(); - double targetWidth = targetCell.getGeometry().getWidth(); - double targetHeight = targetCell.getGeometry().getHeight(); - double overlapWidth = sourceWidth - (sourceWidth * Math.sqrt(2) * 0.1); - double overlapHeight = sourceHeight - (sourceHeight * Math.sqrt(2) * 0.1); + double srcCellWidth = sourceCell.getGeometry().getWidth(); + double dstCellHeight = destinationCell.getGeometry().getHeight(); -// deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() - overlapWidth, targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time))); -// deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() - overlapWidth + (sourceWidth * time), targetCell.getGeometry().getY() - overlapHeight + sourceHeight)); - deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() - (sourceWidth / Math.sqrt(2.5)) + (sourceWidth * time), targetCell.getGeometry().getY() + targetHeight)); + deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(destinationCell.getGeometry().getX() - (srcCellWidth / Math.sqrt(2.5)) + (srcCellWidth * time), destinationCell.getGeometry().getY() + dstCellHeight)); deltaAnimation.startVertexAnimation(); - - sourceCell.setParent(targetCell.getParent()); - targetCell.getParent().insert(sourceCell); -// sourceCell.getGeometry().setX(targetCell.getGeometry().getX() - overlapWidth); -// sourceCell.getGeometry().setY(targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time)); -// sourceCell.getGeometry().setX(targetCell.getGeometry().getX() - overlapWidth + (sourceWidth * time)); -// sourceCell.getGeometry().setY(targetCell.getGeometry().getY() - overlapHeight + sourceHeight); - sourceCell.getGeometry().setX(targetCell.getGeometry().getX() - (sourceWidth / Math.sqrt(2.5)) + (sourceWidth * time)); - sourceCell.getGeometry().setY(targetCell.getGeometry().getY() + targetHeight); - targetVertexMethodExec.getLocals().add(sourceVertexObject); - System.out.println("moveLocalObjectVertex: " + targetVertexMethodExec.getLabel() + " :Local: " + sourceVertexObject.getLabel()); + deltaAnimation.sleepThread(1001); + + sourceCell.setParent(destinationCell.getParent()); + destinationCell.getParent().insert(sourceCell); + sourceCell.getGeometry().setX(destinationCell.getGeometry().getX() - (srcCellWidth / Math.sqrt(2.5)) + (srcCellWidth * time)); + sourceCell.getGeometry().setY(destinationCell.getGeometry().getY() + dstCellHeight); + destinationMethodExecutionVertex.getLocals().add(sourceObjectVertex); + // Test code (will be deleted) + System.out.println("moveLocalObjectVertex: " + destinationMethodExecutionVertex.getLabel() + " :Local: " + sourceObjectVertex.getLabel()); } finally { mxgraph.getModel().endUpdate(); } } /** - * Source VertexObject move target VertexMethodExecution to Argument position from MethodExecution. + * Move to position of destination {@code MethodExecutionVertex}'s argument from {@code MethodExecution} of source {@code VertexObject}. * - * @param methodExec MethodExecution. - * @param sourceVertexObject move - * @param targetVertexMethodExec + * @param methodExecution: {@code MethodExecution} + * @param sourceVertexObject: moving {@code VertexObject} + * @param destinationMethodExecutionVertex */ - protected void moveArgumentObjectVertex(MethodExecution methodExec, ObjectVertex sourceVertexObject, MethodExecutionVertex targetVertexMethodExec) { - mxICell sourceCell = (mxICell)sourceVertexObject.getCell(); - mxICell targetCell = (mxICell) targetVertexMethodExec.getCell(); - // mxICell parentTargetMethodExecCell = targetMethodExecCell.getParent(); + protected void moveArgumentObjectVertex(MethodExecution methodExecution, ObjectVertex sourceObjectVertex, MethodExecutionVertex destinationMethodExecutionVertex) { + mxICell srcCell = (mxICell)sourceObjectVertex.getCell(); + mxICell dstCell = (mxICell) destinationMethodExecutionVertex.getCell(); - // Remove sourceVertex from Locals and Arguments Vertex of MethodExecution's Vertex. - MethodExecution callerMethodExecution = methodExec.getCallerMethodExecution(); - if (methodExecToVertexMap.containsKey(callerMethodExecution) && methodExecToVertexMap.get(callerMethodExecution).getLocals().contains(sourceVertexObject)) { - methodExecToVertexMap.get(callerMethodExecution).getLocals().remove(sourceVertexObject); - System.out.println(methodExecToVertexMap.get(callerMethodExecution).getLabel() + " :removeLocal: " + sourceVertexObject.getLabel()); + // Remove source {@code VertexObject} from Locals and Arguments of {@code MethodExecution}'s Vertex. + MethodExecution callerMethodExec = methodExecution.getCallerMethodExecution(); + if (methodExecToVertexMap.containsKey(callerMethodExec) && methodExecToVertexMap.get(callerMethodExec).getLocals().contains(sourceObjectVertex)) { + methodExecToVertexMap.get(callerMethodExec).getLocals().remove(sourceObjectVertex); + // Test code (will be deleted) + System.out.println(methodExecToVertexMap.get(callerMethodExec).getLabel() + " :removeLocal: " + sourceObjectVertex.getLabel()); } - if (methodExecToVertexMap.containsKey(callerMethodExecution) && methodExecToVertexMap.get(callerMethodExecution).getArguments().contains(sourceVertexObject)) { - methodExecToVertexMap.get(callerMethodExecution).getArguments().remove(sourceVertexObject); - System.out.println(methodExecToVertexMap.get(callerMethodExecution).getLabel() + " :removeArgument: " + sourceVertexObject.getLabel()); + if (methodExecToVertexMap.containsKey(callerMethodExec) && methodExecToVertexMap.get(callerMethodExec).getArguments().contains(sourceObjectVertex)) { + methodExecToVertexMap.get(callerMethodExec).getArguments().remove(sourceObjectVertex); + // Test code (will be deleted) + System.out.println(methodExecToVertexMap.get(callerMethodExec).getLabel() + " :removeArgument: " + sourceObjectVertex.getLabel()); } // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. mxgraph.getModel().beginUpdate(); try { - int time = targetVertexMethodExec.getArguments().size(); - double sourceX = sourceCell.getGeometry().getX(); - double sourceY = sourceCell.getGeometry().getY(); + int time = destinationMethodExecutionVertex.getArguments().size(); + double srcCoordX = srcCell.getGeometry().getX(); + double srcCoordY = srcCell.getGeometry().getY(); - // System.out.println(time); - - if(sourceCell.getParent().getValue() != null) { - Point absolutePointSourceCell = getAbsolutePointforCell(sourceCell); - sourceX = absolutePointSourceCell.getX(); - sourceY = absolutePointSourceCell.getY(); - sourceCell.getParent().remove(sourceCell); + if(srcCell.getParent().getValue() != null) { + Point srcCellAbsPt = getAbsolutePointforCell(srcCell); + srcCoordX = srcCellAbsPt.getX(); + srcCoordY = srcCellAbsPt.getY(); + srcCell.getParent().remove(srcCell); } - if (!isParent(targetCell, sourceCell)) { - mxgraph.orderCells(true, new Object[] {sourceCell}); - sourceCell.setParent(targetCell.getParent()); - targetCell.getParent().insert(sourceCell); - Point absolutePointSourceParentCell = getAbsolutePointforCell(sourceCell.getParent()); - sourceCell.getGeometry().setX(sourceX - absolutePointSourceParentCell.getX()); - sourceCell.getGeometry().setY(sourceY - absolutePointSourceParentCell.getY()); + if (!isParent(dstCell, srcCell)) { + mxgraph.orderCells(true, new Object[] {srcCell}); + srcCell.setParent(dstCell.getParent()); + dstCell.getParent().insert(srcCell); + Point srcParentCellAbsPt = getAbsolutePointforCell(srcCell.getParent()); + srcCell.getGeometry().setX(srcCoordX - srcParentCellAbsPt.getX()); + srcCell.getGeometry().setY(srcCoordY - srcParentCellAbsPt.getY()); - double sourceWidth = sourceCell.getGeometry().getWidth(); - double sourceHeight = sourceCell.getGeometry().getHeight(); - double overlapWidth = sourceWidth - (sourceWidth * Math.sqrt(2) * 0.1); - double overlapHeight = sourceHeight - (sourceHeight * Math.sqrt(2) * 0.1); + double srcCellWidth = srcCell.getGeometry().getWidth(); + double srcCellHeight = srcCell.getGeometry().getHeight(); + double overlapWidth = srcCellWidth - (srcCellWidth * Math.sqrt(2) * 0.1); + double overlapHeight = srcCellHeight - (srcCellHeight * Math.sqrt(2) * 0.1); - deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() - overlapWidth, targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time))); + deltaAnimation.setVertexAnimation(srcCell, new mxPoint(dstCell.getGeometry().getX() - overlapWidth, dstCell.getGeometry().getY() - overlapHeight + (srcCellHeight * time))); deltaAnimation.startVertexAnimation(); + deltaAnimation.sleepThread(1001); - // sourceCell.setParent(targetCell.getParent()); - // targetCell.getParent().insert(sourceCell); - sourceCell.getGeometry().setX(targetCell.getGeometry().getX() - overlapWidth); - sourceCell.getGeometry().setY(targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time)); - targetVertexMethodExec.getArguments().add(sourceVertexObject); - System.out.println("moveArgumentObejctVertex" + targetVertexMethodExec.getLabel() + " :Argument: " + sourceVertexObject.getLabel()); - } else { // �d�l��̃o�O, ���[�v������ + srcCell.getGeometry().setX(dstCell.getGeometry().getX() - overlapWidth); + srcCell.getGeometry().setY(dstCell.getGeometry().getY() - overlapHeight + (srcCellHeight * time)); + destinationMethodExecutionVertex.getArguments().add(sourceObjectVertex); + // Test code (will be deleted) + System.out.println("moveArgumentObejctVertex" + destinationMethodExecutionVertex.getLabel() + " :Argument: " + sourceObjectVertex.getLabel()); + } else { // TODO: �d�l��̃o�O�A���[�v������ + // Test code (will be deleted) outputLog(); -// try { - // ObjectVertex(sourceCell)�̃N���[������ -// mxICell cloneSourceCell = (mxICell) mxgraph.addCell(sourceCell.clone()); -// -// cloneSourceCell.setStyle("fillColor=#ffffff;opacity=50;shape=ellipse"); -// cloneSourceCell.setId("clone" + cloneSourceCell.getId()); -// cloneSourceCell.setValue(null); -// cloneSourceCell.setParent(sourceCell); -// sourceCell.insert(cloneSourceCell); -// cloneSourceCell.getGeometry().setX(0); -// cloneSourceCell.getGeometry().setX(0); -// cloneSourceCell.getGeometry().setY(0); - // ����ObjectVertex - Point absPtSourceCell = getAbsolutePointforCell(sourceCell); - Point absPtTargetParentCell = getAbsolutePointforCell(targetCell.getParent()); + // ����{@code ObjectVertex} + Point srcCellAbsPt = getAbsolutePointforCell(srcCell); + Point dstParentCellAbsPt = getAbsolutePointforCell(dstCell.getParent()); - sourceCell.remove(targetCell.getParent()); - targetCell.getParent().setParent(mxDefaultParent); - sourceCell.setParent(targetCell.getParent()); - targetCell.getParent().insert(sourceCell); + srcCell.remove(dstCell.getParent()); + dstCell.getParent().setParent(mxDefaultParent); + srcCell.setParent(dstCell.getParent()); + dstCell.getParent().insert(srcCell); - targetCell.getParent().getGeometry().setX(absPtTargetParentCell.getX()); - targetCell.getParent().getGeometry().setY(absPtTargetParentCell.getY()); - sourceCell.getGeometry().setX(absPtSourceCell.getX() - absPtTargetParentCell.getX()); - sourceCell.getGeometry().setY(absPtSourceCell.getY() - absPtTargetParentCell.getY()); - sourceCell.setStyle("opacity=50;shape=ellipse"); + dstCell.getParent().getGeometry().setX(dstParentCellAbsPt.getX()); + dstCell.getParent().getGeometry().setY(dstParentCellAbsPt.getY()); + srcCell.getGeometry().setX(srcCellAbsPt.getX() - dstParentCellAbsPt.getX()); + srcCell.getGeometry().setY(srcCellAbsPt.getY() - dstParentCellAbsPt.getY()); + srcCell.setStyle("opacity=50;shape=ellipse"); - double sourceWidth = sourceCell.getGeometry().getWidth(); - double sourceHeight = sourceCell.getGeometry().getHeight(); -// double overlapWidth = targetCell.getGeometry().getWidth() / 2; - double overlapWidth = sourceWidth - (sourceWidth * Math.sqrt(2) * 0.1); - double overlapHeight = sourceHeight - (sourceHeight * Math.sqrt(2) * 0.1); + double srcCellWidth = srcCell.getGeometry().getWidth(); + double srcCellHeight = srcCell.getGeometry().getHeight(); + double overlapWidth = srcCellWidth - (srcCellWidth * Math.sqrt(2) * 0.1); + double overlapHeight = srcCellHeight - (srcCellHeight * Math.sqrt(2) * 0.1); -// deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() + overlapWidth, targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time))); - deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() - overlapWidth + (sourceWidth * time), targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time))); + deltaAnimation.setVertexAnimation(srcCell, new mxPoint(dstCell.getGeometry().getX() - overlapWidth + (srcCellWidth * time), dstCell.getGeometry().getY() - overlapHeight + (srcCellHeight * time))); deltaAnimation.startVertexAnimation(); + deltaAnimation.sleepThread(DEFAULT_THREAD_SLEEP_MILLIS); + // Test code (will be deleted) outputLog(); -// sourceCell.getGeometry().setX(targetCell.getGeometry().getX() + overlapWidth); - sourceCell.getGeometry().setX(targetCell.getGeometry().getX() - overlapWidth + (sourceWidth * time)); - sourceCell.getGeometry().setY(targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time)); + srcCell.getGeometry().setX(dstCell.getGeometry().getX() - overlapWidth + (srcCellWidth * time)); + srcCell.getGeometry().setY(dstCell.getGeometry().getY() - overlapHeight + (srcCellHeight * time)); - targetVertexMethodExec.getArguments().add(sourceVertexObject); - -// } catch (CloneNotSupportedException e) { -// e.printStackTrace(); -// } + destinationMethodExecutionVertex.getArguments().add(sourceObjectVertex); } } finally { mxgraph.getModel().endUpdate(); @@ -562,136 +591,133 @@ } /** - * Source VertexObject move target VertexMethodExecution to Argument position from MethodExecution. * - * @param methodExec MethodExecution. - * @param sourceVertexObject - * @param targetVertexMethodExec + * @param methodExecution: {@code MethodExecution} + * @param sourceVertexObject: moving {@code VertexObject} + * @param destinationVertexMethodExec */ - private void moveActualArgumentObjectVertex(MethodExecution methodExec, ObjectVertex sourceVertexObject, MethodExecutionVertex targetVertexMethodExec) { - mxICell sourceCell = (mxICell)sourceVertexObject.getCell(); - mxICell targetCell = (mxICell) targetVertexMethodExec.getCell(); - // mxICell parentTargetMethodExecCell = targetMethodExecCell.getParent(); - if (sourceCell == targetCell.getParent()) { - System.out.println("nothing."); + /** + * Move to position of destination {@code MethodExecutionVertex}'s actual argument from {@code MethodExecution} of source {@code VertexObject}. + * + * @param methodExecution: {@code MethodExecution} + * @param sourceObjectVertex + * @param destinationMethodExecutionVertex + */ + private void moveActualArgumentObjectVertex(MethodExecution methodExecution, ObjectVertex sourceObjectVertex, MethodExecutionVertex destinationMethodExecutionVertex) { + mxICell srcCell = (mxICell)sourceObjectVertex.getCell(); + mxICell dstCell = (mxICell) destinationMethodExecutionVertex.getCell(); + + if (srcCell == dstCell.getParent()) { + System.out.println("Nothing to moveActualArgumentObjectVertex()."); return; } - // Remove sourceVertex from Locals and Arguments Vertex of MethodExecution's Vertex. - // MethodExecution callerMethodExecution = methodExec.getCallerMethodExecution(); - System.out.println(methodExec.getSignature()); - System.out.println(sourceVertexObject.getLabel()); - // if (methodExecToVertexMap.containsKey(callerMethodExecution) && methodExecToVertexMap.get(callerMethodExecution).getLocals().contains(sourceVertexObject)) { - // methodExecToVertexMap.get(callerMethodExecution).getLocals().remove(sourceVertexObject); - // System.out.println(methodExecToVertexMap.get(callerMethodExecution).getLabel() + " :removeLocal: " + sourceVertexObject.getLabel()); - // } - // - // if (methodExecToVertexMap.containsKey(callerMethodExecution) && methodExecToVertexMap.get(callerMethodExecution).getArguments().contains(sourceVertexObject)) { - // methodExecToVertexMap.get(callerMethodExecution).getArguments().remove(sourceVertexObject); - // System.out.println(methodExecToVertexMap.get(callerMethodExecution).getLabel() + " :removeArgument: " + sourceVertexObject.getLabel()); - // } - if (methodExecToVertexMap.containsKey(methodExec) && methodExecToVertexMap.get(methodExec).getLocals().contains(sourceVertexObject)) { - methodExecToVertexMap.get(methodExec).getLocals().remove(sourceVertexObject); - System.out.println(methodExecToVertexMap.get(methodExec).getLabel() + " :removeLocal: " + sourceVertexObject.getLabel()); + // Remove sourceVertex from Locals and Arguments of MethodExecution's Vertex. + // Test code (will be deleted) + System.out.println(methodExecution.getSignature()); + System.out.println(sourceObjectVertex.getLabel()); + if (methodExecToVertexMap.containsKey(methodExecution) && methodExecToVertexMap.get(methodExecution).getLocals().contains(sourceObjectVertex)) { + methodExecToVertexMap.get(methodExecution).getLocals().remove(sourceObjectVertex); + // Test code (will be deleted) + System.out.println(methodExecToVertexMap.get(methodExecution).getLabel() + " :removeLocal: " + sourceObjectVertex.getLabel()); } - if (methodExecToVertexMap.containsKey(methodExec) && methodExecToVertexMap.get(methodExec).getArguments().contains(sourceVertexObject)) { - methodExecToVertexMap.get(methodExec).getArguments().remove(sourceVertexObject); - System.out.println(methodExecToVertexMap.get(methodExec).getLabel() + " :removeArgument: " + sourceVertexObject.getLabel()); + if (methodExecToVertexMap.containsKey(methodExecution) && methodExecToVertexMap.get(methodExecution).getArguments().contains(sourceObjectVertex)) { + methodExecToVertexMap.get(methodExecution).getArguments().remove(sourceObjectVertex); + // Test code (will be deleted) + System.out.println(methodExecToVertexMap.get(methodExecution).getLabel() + " :removeArgument: " + sourceObjectVertex.getLabel()); } // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. mxgraph.getModel().beginUpdate(); try { -// int time = targetVertexMethodExec.getArguments().size(); -// int time = targetVertexMethodExec.getLocals().size() + 1; - int time = targetVertexMethodExec.getLocals().size(); - double sourceX = sourceCell.getGeometry().getX(); - double sourceY = sourceCell.getGeometry().getY(); + int time = destinationMethodExecutionVertex.getLocals().size(); + double srcCellCoordX = srcCell.getGeometry().getX(); + double srcCellCoordY = srcCell.getGeometry().getY(); - System.out.println(time + ", " + targetVertexMethodExec.getLocals().size()); - // if (time == 0) time = 1; + // Test code (will be deleted) + System.out.println(time + ", " + destinationMethodExecutionVertex.getLocals().size()); - if(sourceCell.getParent().getValue() != null) { - Point absolutePointSourceCell = getAbsolutePointforCell(sourceCell); - sourceX = absolutePointSourceCell.getX(); - sourceY = absolutePointSourceCell.getY(); - sourceCell.getParent().remove(sourceCell); + if(srcCell.getParent().getValue() != null) { + Point srcCellAbsPt = getAbsolutePointforCell(srcCell); + srcCellCoordX = srcCellAbsPt.getX(); + srcCellCoordY = srcCellAbsPt.getY(); + srcCell.getParent().remove(srcCell); } - sourceCell.setParent(targetCell.getParent()); - targetCell.getParent().insert(sourceCell); - Point absolutePointSourceParentCell = getAbsolutePointforCell(sourceCell.getParent()); - sourceCell.getGeometry().setX(sourceX - absolutePointSourceParentCell.getX()); - sourceCell.getGeometry().setY(sourceY - absolutePointSourceParentCell.getY()); + srcCell.setParent(dstCell.getParent()); + dstCell.getParent().insert(srcCell); + Point srcParentCellAbsPt = getAbsolutePointforCell(srcCell.getParent()); + srcCell.getGeometry().setX(srcCellCoordX - srcParentCellAbsPt.getX()); + srcCell.getGeometry().setY(srcCellCoordY - srcParentCellAbsPt.getY()); - double sourceWidth = sourceCell.getGeometry().getWidth(); - double sourceHeight = sourceCell.getGeometry().getHeight(); - double targetWidth = targetCell.getGeometry().getWidth(); - double targetHeight = targetCell.getGeometry().getHeight(); - double overlapWidth = sourceWidth - (sourceWidth * Math.sqrt(2) * 0.1); - double overlapHeight = sourceHeight - (sourceHeight * Math.sqrt(2) * 0.1); + double srcCellWidth = srcCell.getGeometry().getWidth(); + double dstCellHeight = dstCell.getGeometry().getHeight(); -// deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() - overlapWidth, targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time))); - deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() - (sourceWidth / Math.sqrt(3)) + (sourceWidth * time), targetCell.getGeometry().getY() + targetHeight)); + deltaAnimation.setVertexAnimation(srcCell, + new mxPoint(dstCell.getGeometry().getX() - (srcCellWidth / Math.sqrt(3)) + (srcCellWidth * time), dstCell.getGeometry().getY() + dstCellHeight)); deltaAnimation.startVertexAnimation(); -// sourceCell.getGeometry().setX(targetCell.getGeometry().getX() - overlapWidth); -// sourceCell.getGeometry().setY(targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time)); - sourceCell.getGeometry().setX(targetCell.getGeometry().getX() - (sourceWidth / Math.sqrt(3)) + (sourceWidth * time)); - sourceCell.getGeometry().setY(targetCell.getGeometry().getY() + targetHeight); + deltaAnimation.sleepThread(DEFAULT_THREAD_SLEEP_MILLIS); + srcCell.getGeometry().setX(dstCell.getGeometry().getX() - (srcCellWidth / Math.sqrt(3)) + (srcCellWidth * time)); + srcCell.getGeometry().setY(dstCell.getGeometry().getY() + dstCellHeight); - targetVertexMethodExec.getArguments().add(sourceVertexObject); - System.out.println("moveActualArgumentObjectVertex: " + targetVertexMethodExec.getLabel() + " :Argument: " + sourceVertexObject.getLabel()); + destinationMethodExecutionVertex.getArguments().add(sourceObjectVertex); + // Test code (will be deleted) + System.out.println("moveActualArgumentObjectVertex: " + destinationMethodExecutionVertex.getLabel() + " :Argument: " + sourceObjectVertex.getLabel()); } finally { mxgraph.getModel().endUpdate(); } } - /** Update ObjectVertices size and position. */ + /** + * Update size and position of all {@code ObjectVertex}. + */ protected void updateObjectVertices() { // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology mxgraph.getModel().beginUpdate(); try { - for (ObjectVertex objectVertex: objectToVertexMap.values()) { - mxCell objectVertexCell = ((mxCell) objectVertex.getCell()); - if (objectVertexCell != null) { + for (ObjectVertex ov: objectToVertexMap.values()) { + mxCell ovCell = (mxCell) ov.getCell(); + if (ovCell != null) { int time = 0; - for (int i = 0; i < objectVertexCell.getChildCount(); i++) { - if (!(objectVertexCell.getChildAt(i).getId()).contains("clone")) { + for (int i = 0; i < ovCell.getChildCount(); i++) { + if (!(ovCell.getChildAt(i).getId()).contains("clone")) { time++; } } -// time = countChildVertex(objectVertex); if (time == 0) { time = 1; } - if(objectVertexCell.getGeometry().getWidth() != VERTEX_OBJECT_SIZE.getWidth() * time) { - System.out.println("updateVertexObjectSize: " + objectVertexCell.getGeometry().getWidth() + "->" + VERTEX_OBJECT_SIZE.getWidth() * time+ ", " + objectVertexCell.getId()); - Dimension targetDimension = new Dimension(); - targetDimension.setSize(VERTEX_OBJECT_SIZE.getWidth() * time, VERTEX_OBJECT_SIZE.getHeight() * time); - if (objectVertexCell.getParent() != mxDefaultParent && (objectVertexCell.getChildCount() != 0 || objectVertexCell.getGeometry().getWidth() > VERTEX_OBJECT_SIZE.getWidth() * time)) { - double overlapX = (targetDimension.getWidth() - objectVertexCell.getGeometry().getWidth()) / 2 / Math.sqrt(2); - double overlapY = (targetDimension.getHeight() - objectVertexCell.getGeometry().getHeight()) / 2 / Math.sqrt(2); - System.out.println("updateVertexObjectPosition: " + objectVertexCell.getGeometry().getX() + " - " + overlapX); - mxPoint targetPoint = new mxPoint(objectVertexCell.getGeometry().getX() - overlapX, objectVertexCell.getGeometry().getY() + overlapY); - int idxFromParent = objectVertexCell.getParent().getIndex(objectVertexCell); + if(ovCell.getGeometry().getWidth() != DEFAULT_OBJECT_VERTEX_SIZE.getWidth() * time) { + // Test code (will be deleted) + System.out.println("updateVertexObjectSize: " + ovCell.getGeometry().getWidth() + "->" + DEFAULT_OBJECT_VERTEX_SIZE.getWidth() * time+ ", " + ovCell.getId()); + Dimension dstSize = new Dimension(); + dstSize.setSize(DEFAULT_OBJECT_VERTEX_SIZE.getWidth() * time, DEFAULT_OBJECT_VERTEX_SIZE.getHeight() * time); + if (ovCell.getParent() != mxDefaultParent && (ovCell.getChildCount() != 0 || ovCell.getGeometry().getWidth() > DEFAULT_OBJECT_VERTEX_SIZE.getWidth() * time)) { + double overlapX = (dstSize.getWidth() - ovCell.getGeometry().getWidth()) / 2 / Math.sqrt(2); + double overlapY = (dstSize.getHeight() - ovCell.getGeometry().getHeight()) / 2 / Math.sqrt(2); + // Test code (will be deleted) + System.out.println("updateVertexObjectPosition: " + ovCell.getGeometry().getX() + " - " + overlapX); + mxPoint dstPt = new mxPoint(ovCell.getGeometry().getX() - overlapX, ovCell.getGeometry().getY() + overlapY); + int idxFromParent = ovCell.getParent().getIndex(ovCell); if (idxFromParent >= 2) { - overlapY = (targetDimension.getHeight() - objectVertexCell.getGeometry().getHeight()) / 2; - targetPoint.setY(objectVertexCell.getGeometry().getY() + overlapY); + overlapY = (dstSize.getHeight() - ovCell.getGeometry().getHeight()) / 2; + dstPt.setY(ovCell.getGeometry().getY() + overlapY); } for (MethodExecutionVertex methodExecVertex: methodExecToVertexMap.values()) { List arguments = methodExecVertex.getArguments(); - if (arguments != null && arguments.contains(objectVertex)) { - targetPoint.setY(objectVertexCell.getGeometry().getY() - overlapY); + if (arguments != null && arguments.contains(ov)) { + dstPt.setY(ovCell.getGeometry().getY() - overlapY); break; } } - deltaAnimation.setVertexAnimation(objectVertexCell, targetPoint); + deltaAnimation.setVertexAnimation(ovCell, dstPt); deltaAnimation.startVertexAnimation(); } - deltaAnimation.setResizeVertexAnimation(objectVertexCell, targetDimension); + deltaAnimation.setResizeVertexAnimation(ovCell, dstSize); deltaAnimation.startResizeVertexAnimation(); + deltaAnimation.sleepThread(DEFAULT_THREAD_SLEEP_MILLIS); } } } @@ -703,72 +729,78 @@ abstract protected void createMethodExecutionVertex(Alias alias); /** - * Parent : Create MethodExecutionVertex. + * Parent: Create {@code MethodExecutionVertex}. * - * @param objId - * @param methodSignature Called or this MethodSignature. - * @param methodExec Called or this MethodExecution. + * @param objectId + * @param methodSignature: called or this method signature + * @param methodExec: called or this {@code MethodExecution} */ - protected void createMethodExecutionVertex(String objId, String methodSignature, MethodExecution methodExec) { - if (methodSignature == null) methodSignature = methodExec.getSignature(); + protected void createMethodExecutionVertex(String objectId, String methodSignature, MethodExecution methodExecution) { + mxICell parentCell = (mxICell) objectToVertexMap.get(objectId).getCell(); + +// if (cell == null) return; + + if (methodSignature == null) { + methodSignature = methodExecution.getSignature(); + } if (methodSignature.matches(".+\\(.*\\)")) { + // Test code (will be deleted) System.out.println(methodSignature); - methodSignature = formatMethodSignature(methodSignature, methodExec.getThisClassName()); + methodSignature = formatMethodSignature(methodSignature, methodExecution.getThisClassName()); + } + + if (methodExecution.isStatic() && !objectId.equals("0")) { + objectId = methodExecution.getCallerMethodExecution().getThisObjId(); + } + + double coordX = DEFAULT_OBJECT_VERTEX_SIZE.getWidth() * 0.1; + double coordY = DEFAULT_OBJECT_VERTEX_SIZE.getHeight() * 0.5; + double stdX = coordX; + double stdY = 0; + int time = objectToVertexMap.get(objectId).getVertexMethodExecutions().size(); + // Test code (will be deleted) + System.out.println("time" + time); + if (time >= 1) { + mxICell stdCell = (mxICell) objectToVertexMap.get(objectId).getVertexMethodExecutions().get(0).getCell(); + stdX = stdCell.getGeometry().getX(); + stdY = stdCell.getGeometry().getY(); + time -= 1; } // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. mxgraph.getModel().beginUpdate(); try { - if (methodExec.isStatic() && !objId.equals("0")) { - objId = methodExec.getCallerMethodExecution().getThisObjId(); - } + // Creates a white cell of {@code ObjectVertex}. + mxICell cell = (mxICell) mxgraph.insertDeltaVertex(parentCell, methodSignature, methodSignature, "fillColor=white"); + mxgraph.orderCells(false, new Object[] {cell}); + // Test code (will be deleted) + System.out.println("makeVertexMethodExecution: " + cell.getId() + " in " + objectId + " (" + stdX + ", " + coordY * (time + 1) + stdY + ")"); - Object object = objectToVertexMap.get(objId).getCell(); - -// if (object != null) { - double xCor = VERTEX_OBJECT_SIZE.getWidth() * 0.1; - double yCor = VERTEX_OBJECT_SIZE.getHeight() * 0.5; - double standardX = xCor; - double standardY = 0; - int time = objectToVertexMap.get(objId).getVertexMethodExecutions().size(); - System.out.println(time); - if (time >= 1) { - mxICell standardCell = (mxICell) objectToVertexMap.get(objId).getVertexMethodExecutions().get(0).getCell(); - standardX = standardCell.getGeometry().getX(); - standardY = standardCell.getGeometry().getY(); - time-=1; - } - - Object vertex = mxgraph.insertDeltaVertex(object, methodSignature, methodSignature, "fillColor=white"); //creates a white vertex. - mxgraph.orderCells(false, new Object[] {vertex}); - System.out.println("makeVertexMethodExecution: " + ((mxICell)vertex).getId() + " in " + objId + " (" + standardX + ", " + yCor * (time + 1) + standardY + ")"); - - MethodExecutionVertex vertexMethodExecution = new MethodExecutionVertex(methodSignature, vertex, standardX , yCor * (time + 1) + standardY, VERTEX_METHOD_EXECUTION_SIZE.getWidth(), VERTEX_METHOD_EXECUTION_SIZE.getHeight()); - // Object vertex = mxgraph.insertVertex(object, methodSignature, methodSignature, 0, 0, 0, 0, "fillColor=white", true); //creates a white vertex. - // Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, methodSignature, methodSignature, "fillColor=white"); //creates a white vertex. - // VertexMethodExecution vertexMethodExecution = new VertexMethodExecution(methodSignature, vertex, getXForCell(objectId) + (xCor * (time + 1)), getYForCell(objectId) + (yCor * (time + 1)), VERTEX_METHOD_EXECUTION_SIZE.getWidth(), VERTEX_METHOD_EXECUTION_SIZE.getHeight()); - methodExecToVertexMap.put(methodExec, vertexMethodExecution); + MethodExecutionVertex methodExecVertex = + new MethodExecutionVertex(methodSignature, cell, stdX, coordY * (time + 1) + stdY, + DEFAULT_METHOD_EXECUTION_VERTEX_SIZE.getWidth(), DEFAULT_METHOD_EXECUTION_VERTEX_SIZE.getHeight()); + methodExecToVertexMap.put(methodExecution, methodExecVertex); if(methodExecToVertexMap.size() > 1) { - ((mxICell)vertex).setVisible(false); + cell.setVisible(false); createEdgeToMethodExecution(); } - objectToVertexMap.get(objId).addMethodExecution(vertexMethodExecution); -// } + objectToVertexMap.get(objectId).addMethodExecution(methodExecVertex); } finally { mxgraph.getModel().endUpdate(); } - setCellsStyle(); +// setCellsStyle(); + update(); } /** - * Remove VertexMethodExecution on AliasType is MethodInvocation of alias. + * Remove {@code MethodExecutionVertex} on AliasType is {@code AliasType.METHOD_INVOCATION}. * * @param alias */ private void removeMethodExecutionVertex(Alias alias) { - // sourceVertex - ObjectVertex sourceVertexObject = objectToVertexMap.get(alias.getObjectId()); + // source {@code ObjectVertex} + ObjectVertex srcObjVertex = objectToVertexMap.get(alias.getObjectId()); MethodExecution methodExec = alias.getMethodExecution(); if(alias.getAliasType().equals(AliasType.METHOD_INVOCATION) || alias.getAliasType().equals(AliasType.CONSTRACTOR_INVOCATION)) { @@ -780,15 +812,16 @@ List locals = new ArrayList<>(methodExecToVertexMap.get(calledMethodExec).getLocals()); if (arguments.size() != 0) { for (ObjectVertex vo: arguments) { - if (vo != sourceVertexObject) { + if (vo != srcObjVertex) { + // Test code (will be deleted) System.out.println("argumentRemove"); mxICell cell = (mxICell)vo.getCell(); if (!cell.getParent().equals(mxDefaultParent)) { - Point absolutePointCell = getAbsolutePointforCell(cell); + Point cellAbsPt = getAbsolutePointforCell(cell); cell.getParent().remove(cell); cell.setParent(mxDefaultParent); - cell.getGeometry().setX(absolutePointCell.getX()); - cell.getGeometry().setY(absolutePointCell.getY()); + cell.getGeometry().setX(cellAbsPt.getX()); + cell.getGeometry().setY(cellAbsPt.getY()); deltaAnimation.setVertexAnimation(cell, new mxPoint(vo.getInitialX(), vo.getInitialY())); deltaAnimation.startVertexAnimation(); } @@ -798,14 +831,15 @@ } if (locals.size() != 0) { for (ObjectVertex vo: locals) { - if (vo != sourceVertexObject) { + if (vo != srcObjVertex) { + // Test code (will be deleted) System.out.println("localRemove"); mxICell cell = (mxICell)vo.getCell(); - Point absolutePointCell = getAbsolutePointforCell(cell); + Point cellAbsPt = getAbsolutePointforCell(cell); cell.getParent().remove(cell); cell.setParent(mxDefaultParent); - cell.getGeometry().setX(absolutePointCell.getX()); - cell.getGeometry().setY(absolutePointCell.getY()); + cell.getGeometry().setX(cellAbsPt.getX()); + cell.getGeometry().setY(cellAbsPt.getY()); deltaAnimation.setVertexAnimation(cell, new mxPoint(vo.getInitialX(), vo.getInitialY())); deltaAnimation.startVertexAnimation(); methodExecToVertexMap.get(calledMethodExec).getLocals().remove(vo); @@ -816,210 +850,244 @@ mxgraph.getModel().endUpdate(); } - - removeCalledMethodExecutionVertex(sourceVertexObject, methodExec, calledMethodExec); + removeCalledMethodExecutionVertex(srcObjVertex, methodExec, calledMethodExec); } else { - removeMethodExecutionVertex(sourceVertexObject, methodExec); + removeMethodExecutionVertex(srcObjVertex, methodExec); } } /** - * Remove VertexMethodExecution on AliasType is MethodInvocation of alias. + * Remove {@code MethodExecutionVertex} on AliasType is {@code AliasType.METHOD_INVOCATION}. * - * @param sourceVertexObject - * @param methodExec + * @param sourceObjectVertex + * @param methodExecution */ - private void removeMethodExecutionVertex(ObjectVertex sourceVertexObject, MethodExecution methodExec) { - // Remove sourceVertex from Locals and Arguments Vertex of CalledMethodExecution's Vertex. - if (methodExecToVertexMap.containsKey(methodExec)) { - mxCell targetVertexCell = (mxCell)methodExecToVertexMap.get(methodExec).getCell(); - targetVertexCell.getParent().remove(targetVertexCell); - targetVertexCell.setParent(mxDefaultParent); - mxgraph.removeCells(new Object[] {targetVertexCell}); - objectToVertexMap.get(methodExec.getThisObjId()).getVertexMethodExecutions().remove(methodExecToVertexMap.get(methodExec)); - methodExecToVertexMap.remove(methodExec); - edgeMap.remove(methodExec.getSignature()); - updateObjectVertices(); + private void removeMethodExecutionVertex(ObjectVertex sourceObjectVertex, MethodExecution methodExecution) { + mxgraph.getModel().beginUpdate(); + try { + // Remove source {@code ObjectVertex} from Locals and Arguments of called {@code MethodExecution}'s Vertex. + if (methodExecToVertexMap.containsKey(methodExecution)) { + mxCell dstMethodExecVertexCell = (mxCell)methodExecToVertexMap.get(methodExecution).getCell(); + dstMethodExecVertexCell.getParent().remove(dstMethodExecVertexCell); + dstMethodExecVertexCell.setParent(mxDefaultParent); + mxgraph.removeCells(new Object[] {dstMethodExecVertexCell}); + objectToVertexMap.get(methodExecution.getThisObjId()).getVertexMethodExecutions().remove(methodExecToVertexMap.get(methodExecution)); + methodExecToVertexMap.remove(methodExecution); + edgeMap.remove(methodExecution.getSignature()); + updateObjectVertices(); + } + } finally { + mxgraph.getModel().endUpdate(); } } /** - * Remove CalledVertexMethodExecution on AliasType is MethodInvocation of alias. + * Remove called {@code MethodExecutionVertex} with alias type {@code AliasType#METHOD_INVOCATION}. * - * @param sourceVertexObject - * @param methodExec - * @param calledMethodExec + * @param sourceVertexObject: source object vertex that a called method execution has temporarily + * @param methodExec: current method execution + * @param calledMethodExec: called method execution */ - protected void removeCalledMethodExecutionVertex(ObjectVertex sourceVertexObject, MethodExecution methodExec, MethodExecution calledMethodExec) { + protected void removeCalledMethodExecutionVertex(ObjectVertex sourceObjectVertex, MethodExecution methodExecution, MethodExecution calledMethodExecution) { + // Test code (will be deleted) outputLog(); - // Remove sourceVertex from Locals and Arguments Vertex of CalledMethodExecution's Vertex. - if (methodExecToVertexMap.containsKey(calledMethodExec)) { - mxICell sourceVertexCell = null; - mxCell targetVertexCell = null; - - if (methodExec != null) { - sourceVertexCell = (mxICell)methodExecToVertexMap.get(methodExec).getCell(); - targetVertexCell = (mxCell)methodExecToVertexMap.get(calledMethodExec).getCell(); - } -// if(!calledMethodExec.isStatic()) { + // Remove ObjectVertex other than sourceObjectVertex from locals and arguments of called MethodExecutionVertex. + if (methodExecToVertexMap.containsKey(calledMethodExecution)) { + MethodExecutionVertex calledMethodExecVertex = methodExecToVertexMap.get(calledMethodExecution); + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. mxgraph.getModel().beginUpdate(); try { - // Dangerous - List arguments = new ArrayList<>(methodExecToVertexMap.get(calledMethodExec).getArguments()); - List locals = new ArrayList<>(methodExecToVertexMap.get(calledMethodExec).getLocals()); + // TODO: Confirm bug. + List arguments = new ArrayList<>(calledMethodExecVertex.getArguments()); if (arguments.size() != 0) { for (ObjectVertex vo: arguments) { - if (vo != sourceVertexObject) { + if (vo != sourceObjectVertex) { mxICell cell = (mxICell)vo.getCell(); - Point absolutePointCell = getAbsolutePointforCell(cell); + Point cellAbsPt = getAbsolutePointforCell(cell); + // Test code (will be deleted) System.out.println(cell); System.out.println(vo.getInitialX() + ", " + vo.getInitialY()); System.out.println(cell.getGeometry().getX() + ", " + cell.getGeometry().getY()); - System.out.println(absolutePointCell); + System.out.println(cellAbsPt); if (cell.getParent() != mxDefaultParent) { cell.getParent().remove(cell); cell.setParent(mxDefaultParent); } - if (!absolutePointCell.equals(vo.getInitialPoint())) { - cell.getGeometry().setX(absolutePointCell.getX()); - cell.getGeometry().setY(absolutePointCell.getY()); + if (!cellAbsPt.equals(vo.getInitialPoint())) { + cell.getGeometry().setX(cellAbsPt.getX()); + cell.getGeometry().setY(cellAbsPt.getY()); deltaAnimation.setVertexAnimation(cell, new mxPoint(vo.getInitialX(), vo.getInitialY())); deltaAnimation.startVertexAnimation(); + deltaAnimation.sleepThread(DEFAULT_THREAD_SLEEP_MILLIS); } - methodExecToVertexMap.get(calledMethodExec).getArguments().remove(vo); + methodExecToVertexMap.get(calledMethodExecution).getArguments().remove(vo); } } } + + List locals = new ArrayList<>(calledMethodExecVertex.getLocals()); if (locals.size() != 0) { for (ObjectVertex vo: locals) { - if (vo != sourceVertexObject) { + if (vo != sourceObjectVertex) { mxICell cell = (mxICell)vo.getCell(); - Point absolutePointCell = getAbsolutePointforCell(cell); + Point cellAbsPt = getAbsolutePointforCell(cell); + // Test code (will be deleted) System.out.println(cell); System.out.println(vo.getInitialX() + ", " + vo.getInitialY()); System.out.println(cell.getGeometry().getX() + ", " + cell.getGeometry().getY()); - System.out.println(absolutePointCell); + System.out.println(cellAbsPt); if (cell.getParent() != mxDefaultParent) { cell.getParent().remove(cell); cell.setParent(mxDefaultParent); } - if (!absolutePointCell.equals(vo.getInitialPoint())) { - cell.getGeometry().setX(absolutePointCell.getX()); - cell.getGeometry().setY(absolutePointCell.getY()); + if (!cellAbsPt.equals(vo.getInitialPoint())) { + cell.getGeometry().setX(cellAbsPt.getX()); + cell.getGeometry().setY(cellAbsPt.getY()); deltaAnimation.setVertexAnimation(cell, new mxPoint(vo.getInitialX(), vo.getInitialY())); deltaAnimation.startVertexAnimation(); + deltaAnimation.sleepThread(DEFAULT_THREAD_SLEEP_MILLIS); } - methodExecToVertexMap.get(calledMethodExec).getLocals().remove(vo); + methodExecToVertexMap.get(calledMethodExecution).getLocals().remove(vo); } } } - - if (sourceVertexCell == null || targetVertexCell == null) return; - - mxgraph.removeCells(mxgraph.getEdgesBetween(sourceVertexCell, targetVertexCell)); - try { - mxICell cloneTargetVertexCell = (mxICell) mxgraph.addCell(targetVertexCell.clone()); - Point absolutPointSourceVertexCell = getAbsolutePointforCell(sourceVertexCell); - Point absolutPointTargetVertexCell = getAbsolutePointforCell(targetVertexCell); - cloneTargetVertexCell.getGeometry().setX(absolutPointTargetVertexCell.getX()); - cloneTargetVertexCell.getGeometry().setY(absolutPointTargetVertexCell.getY()); - cloneTargetVertexCell.setStyle("fillColor=none;strokeColor=none;fontColor=#008000;"); - cloneTargetVertexCell.setValue(null); - Object tempEdge = mxgraph.insertEdge(mxDefaultParent, null, null, sourceVertexCell, cloneTargetVertexCell); - ((mxCell)tempEdge).setStyle("dashed=1;strokeColor=#008000;exitX=0.5;exitY=1;exitPerimeter=1;entryX=0.5;entryY=0;entryPerimeter=1;endArrow=none"); - deltaAnimation.setReductionEdgeAnimation(cloneTargetVertexCell, new mxPoint(absolutPointSourceVertexCell.getX(), absolutPointSourceVertexCell.getY() + sourceVertexCell.getGeometry().getHeight())); - deltaAnimation.startReductionEdgeAnimation(); -// deltaAnimation.setReductionEdgeAnimation(new mxPoint(absolutPointSourceVertexCell.getX() + (sourceVertexCell.getGeometry().getWidth() / 2), absolutPointSourceVertexCell.getY() + sourceVertexCell.getGeometry().getHeight()), new mxPoint(absolutPointTargetVertexCell.getX() + (targetVertexCell.getGeometry().getWidth() / 2), absolutPointTargetVertexCell.getY())); -// deltaAnimation.startReductionEdgeAnimation(); - mxgraph.removeCells(new Object[]{cloneTargetVertexCell}); - } catch (CloneNotSupportedException e) { - e.printStackTrace(); - } } finally { mxgraph.getModel().endUpdate(); } - ((mxCell)targetVertexCell.getParent()).remove(targetVertexCell); - targetVertexCell.setParent(mxDefaultParent); - mxgraph.removeCells(new Object[] {targetVertexCell}); - if (!calledMethodExec.isStatic()) { - objectToVertexMap.get(calledMethodExec.getThisObjId()).getVertexMethodExecutions().remove(methodExecToVertexMap.get(calledMethodExec)); - } else { - objectToVertexMap.get(calledMethodExec.getCallerMethodExecution().getThisObjId()).getVertexMethodExecutions().remove(methodExecToVertexMap.get(calledMethodExec)); + + if (methodExecution == null) { + return; } - methodExecToVertexMap.get(calledMethodExec).getLocals().remove(sourceVertexObject); - methodExecToVertexMap.remove(calledMethodExec); - edgeMap.remove(methodExec.getSignature()); -// moveInitialVertexObject(methodExec); -// updateObjectVerticesSize(); -// } else { -// ((mxCell)targetVertexCell.getParent()).remove(targetVertexCell); -// targetVertexCell.setParent(mxDefaultParent); -// mxgraph.removeCells(new Object[] {targetVertexCell}); -// methodExecToVertexMap.get(calledMethodExec).getLocals().remove(sourceVertexObject); -// methodExecToVertexMap.remove(calledMethodExec); -// } + + mxICell srcMethodExecVertexCell = (mxICell)methodExecToVertexMap.get(methodExecution).getCell(); + mxICell dstMethodExecVertexCell = (mxICell)calledMethodExecVertex.getCell(); + + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + mxgraph.getModel().beginUpdate(); + try { + mxgraph.removeCells(mxgraph.getEdgesBetween(srcMethodExecVertexCell, dstMethodExecVertexCell)); + Point srcMethodExecVertexCellAbsPt = getAbsolutePointforCell(srcMethodExecVertexCell); + Point dstMethodExecVertexCellAbsPt = getAbsolutePointforCell(dstMethodExecVertexCell); + mxICell clonedstMethodExecVertexCell = (mxICell) mxgraph.addCell(dstMethodExecVertexCell.clone()); + clonedstMethodExecVertexCell.getGeometry().setX(dstMethodExecVertexCellAbsPt.getX()); + clonedstMethodExecVertexCell.getGeometry().setY(dstMethodExecVertexCellAbsPt.getY()); + clonedstMethodExecVertexCell.setStyle("fillColor=none;strokeColor=none;fontColor=#008000;"); + clonedstMethodExecVertexCell.setValue(null); + mxICell tmpEdge = (mxICell) mxgraph.insertEdge(mxDefaultParent, null, null, srcMethodExecVertexCell, clonedstMethodExecVertexCell); + tmpEdge.setStyle("dashed=1;strokeColor=#008000;exitX=0.5;exitY=1;exitPerimeter=1;entryX=0.5;entryY=0;entryPerimeter=1;endArrow=none"); + + // Animate an edge to shrink. + edgeAnimation.init(clonedstMethodExecVertexCell, new Point2D.Double(srcMethodExecVertexCellAbsPt.getX(), srcMethodExecVertexCellAbsPt.getY() + srcMethodExecVertexCell.getGeometry().getHeight()), threadPoolExecutor); + // Test code (will be deleted) + System.out.println("absPointSourceVertexCell: " + srcMethodExecVertexCellAbsPt); + edgeAnimation.setOnFinished(new ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent e) { + // Test code (will be deleted) + System.out.println("Shrink edge animation action performed. "); + mxgraph.removeCells(new Object[]{clonedstMethodExecVertexCell}); + + // TODO: Confirm execution order. + dstMethodExecVertexCell.getParent().remove(dstMethodExecVertexCell); + dstMethodExecVertexCell.setParent(mxDefaultParent); + mxgraph.removeCells(new Object[] {dstMethodExecVertexCell}); + } + }); + edgeAnimation.play(); + + if (!calledMethodExecution.isStatic()) { + objectToVertexMap.get(calledMethodExecution.getThisObjId()).getVertexMethodExecutions().remove(methodExecToVertexMap.get(calledMethodExecution)); + } else { + objectToVertexMap.get(calledMethodExecution.getCallerMethodExecution().getThisObjId()).getVertexMethodExecutions().remove(methodExecToVertexMap.get(calledMethodExecution)); + } + methodExecToVertexMap.get(calledMethodExecution).getLocals().remove(sourceObjectVertex); + methodExecToVertexMap.remove(calledMethodExecution); + edgeMap.remove(methodExecution.getSignature()); + + edgeAnimation.sleepThread(201); + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + } finally { + mxgraph.getModel().endUpdate(); + } } + // Test code (will be deleted) outputLog(); } - - /** Make EdgeMethodExecution. */ + + /** + * Create an edge between method execution While animating the edge to stretch. + */ private void createEdgeToMethodExecution() { List methodExecList = new ArrayList<>(methodExecToVertexMap.keySet()); - // BUG : Edge Orientation Reverse. + // TODO: Fix a bug where an edge orientation is reversed. for (int i = 0; i < methodExecList.size() - 1; i++) { - MethodExecution sourceMethodExec = methodExecList.get(i); - MethodExecution targetMethodExec = methodExecList.get(i + 1); - String methodSignature = sourceMethodExec.getSignature(); - if (!edgeMap.containsKey(methodSignature)) { - mxICell sourceVertexCell = (mxICell)methodExecToVertexMap.get(sourceMethodExec).getCell(); - mxICell targetVertexCell = (mxICell)methodExecToVertexMap.get(targetMethodExec).getCell(); -// if (!targetMethodExec.isStatic()) { - Point absolutPointSourceVertexCell = getAbsolutePointforCell(sourceVertexCell); - Point absolutPointTargetVertexCell = getAbsolutePointforCell(targetVertexCell); - // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology + MethodExecution srcMethodExec = methodExecList.get(i); + MethodExecution dstMethodExec = methodExecList.get(i + 1); + String methodSig = srcMethodExec.getSignature(); + if (!edgeMap.containsKey(methodSig)) { + // Draw an edge from sourceVertexCell to destinationVertexCell. + mxICell srcMethodExecVertexCell = (mxICell)methodExecToVertexMap.get(srcMethodExec).getCell(); + mxICell dstMethodExecVertexCell = (mxICell)methodExecToVertexMap.get(dstMethodExec).getCell(); + Point srcMethodExecVertexCellAbsPt = getAbsolutePointforCell(srcMethodExecVertexCell); + Point dstMethodExecVertexCellAbsPt = getAbsolutePointforCell(dstMethodExecVertexCell); + + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. mxgraph.getModel().beginUpdate(); try { - try { - mxICell cloneTargetVertexCell = (mxICell) mxgraph.addCell(targetVertexCell.clone()); - cloneTargetVertexCell.getGeometry().setX(absolutPointSourceVertexCell.getX()); - cloneTargetVertexCell.getGeometry().setY(absolutPointSourceVertexCell.getY() + targetVertexCell.getGeometry().getHeight()); - cloneTargetVertexCell.setStyle("fillColor=none;strokeColor=none;fontColor=#008000;"); - cloneTargetVertexCell.setValue(null); - cloneTargetVertexCell.setVisible(true); - Object tempEdge = mxgraph.insertEdge(mxDefaultParent, null, null, sourceVertexCell, cloneTargetVertexCell); - ((mxCell)tempEdge).setStyle("dashed=1;strokeColor=#008000;exitX=0.5;exitY=1;exitPerimeter=1;entryX=0.5;entryY=0;entryPerimeter=1;endArrow=none"); - deltaAnimation.setExpandEdgeAnimation(cloneTargetVertexCell, new mxPoint(absolutPointTargetVertexCell.getX(), absolutPointTargetVertexCell.getY())); - deltaAnimation.startExpandEdgeAnimation(); - targetVertexCell.setVisible(true); -// deltaAnimation.setExpandEdgeAnimation(new mxPoint(absolutPointSourceVertexCell.getX() + (sourceVertexCell.getGeometry().getWidth() / 2), absolutPointSourceVertexCell.getY() + sourceVertexCell.getGeometry().getHeight()), new mxPoint(absolutPointTargetVertexCell.getX() + (targetVertexCell.getGeometry().getWidth() / 2), absolutPointTargetVertexCell.getY())); -// deltaAnimation.startExpandEdgeAnimation(); - Object edge = mxgraph.insertDeltaEdge(mxDefaultParent, methodSignature, null, sourceVertexCell, targetVertexCell); - ((mxCell)edge).getParent().remove(((mxCell)edge)); - ((mxCell)edge).setParent(mxDefaultParent); - mxgraph.orderCells(false, new Object[] {edge}); - ((mxCell)edge).setStyle("exitX=0.5;exitY=1;exitPerimeter=1;entryX=0.5;entryY=0;entryPerimeter=1;"); - mxgraph.removeCells(new Object[]{cloneTargetVertexCell}); - edgeMap.put(methodSignature, new Edge(methodSignature, TypeName.Call, edge)); - } catch (CloneNotSupportedException e) { - e.printStackTrace(); - } + mxICell clonedstMethodExecVertexCell = (mxICell) mxgraph.addCell(dstMethodExecVertexCell.clone()); + clonedstMethodExecVertexCell.getGeometry().setX(srcMethodExecVertexCellAbsPt.getX()); + clonedstMethodExecVertexCell.getGeometry().setY(srcMethodExecVertexCellAbsPt.getY() + dstMethodExecVertexCell.getGeometry().getHeight()); + clonedstMethodExecVertexCell.setStyle("fillColor=none;strokeColor=none;fontColor=#008000;"); + clonedstMethodExecVertexCell.setValue(null); + clonedstMethodExecVertexCell.setVisible(true); + mxICell tmpEdge = (mxICell) mxgraph.insertEdge(mxDefaultParent, null, null, srcMethodExecVertexCell, clonedstMethodExecVertexCell); + tmpEdge.setStyle("dashed=1;strokeColor=#008000;exitX=0.5;exitY=1;exitPerimeter=1;entryX=0.5;entryY=0;entryPerimeter=1;endArrow=none"); + dstMethodExecVertexCell.setVisible(true); + + // Animate an edge to stretch. + edgeAnimation.init(clonedstMethodExecVertexCell, dstMethodExecVertexCellAbsPt, threadPoolExecutor); + // Test code (will be deleted) + System.out.println("absPointSourceVertexCell: " + srcMethodExecVertexCellAbsPt); + edgeAnimation.setOnFinished(new ActionListener() { + @Override + public void actionPerformed(java.awt.event.ActionEvent e) { + // Test code (will be deleted) + System.out.println("Stretch edge animation action performed. "); + mxICell edge = (mxICell) mxgraph.insertDeltaEdge(mxDefaultParent, methodSig, null, srcMethodExecVertexCell, dstMethodExecVertexCell); + edge.getParent().remove(((mxCell)edge)); + edge.setParent(mxDefaultParent); + mxgraph.orderCells(false, new Object[] {edge}); + edge.setStyle("exitX=0.5;exitY=1;exitPerimeter=1;entryX=0.5;entryY=0;entryPerimeter=1;"); + edgeMap.put(methodSig, new Edge(methodSig, TypeName.Call, edge)); + mxgraph.removeCells(new Object[]{clonedstMethodExecVertexCell}); + update(); + } + }); + edgeAnimation.play(); + update(); + edgeAnimation.sleepThread(201); + } catch (CloneNotSupportedException e) { + e.printStackTrace(); } finally { mxgraph.getModel().endUpdate(); } -// } else { -// targetVertexCell.setVisible(true); -// } - } } } - protected void setEdgePoint(mxICell edge, Point absPtSrcCell, Point absPtTgtCell) { + /** + * + * @param edge + * @param srcCellAbsPt + * @param dstCellAbsPt + */ + protected void setEdgePoint(mxICell edge, Point srcCellAbsPt, Point dstCellAbsPt) { // mxgraph.orderCells(true, new Object[] {edge}); -// if(absPtSrcCell.getX() <= absPtTgtCell.getX()) { +// if(srcCellAbsPt.getX() <= dstCellAbsPt.getX()) { // // �E�����獶��փG�b�W������ // edge.setStyle("exitX=0.5;exitY=0.5;exitPerimeter=1;entryX=0;entryY=0.5;entryPerimeter=1;"); // } else { @@ -1028,50 +1096,52 @@ // } } - /** Set style of All cells. */ + /** + * Styles all cells on the graph. + */ protected void setCellsStyle() { - List vertexObject = new ArrayList<>(); - List staticVertexObject = new ArrayList<>(); - List alignMiddleVertex = new ArrayList<>(); - List alignTopVertex = new ArrayList<>(); - List edgeObject = new ArrayList<>(); - List edgeObjectCreate = new ArrayList<>(); - List edgeMethodExec = new ArrayList<>(); + List objectVertex = new ArrayList<>(); + List staticObjectVertex = new ArrayList<>(); + List alignMidObjectVertex = new ArrayList<>(); + List alignTopObjectVertex = new ArrayList<>(); + List refEdge = new ArrayList<>(); + List refCreateEdge = new ArrayList<>(); + List methodExecEdge = new ArrayList<>(); List roundEdge = new ArrayList<>(); for (Entry objectToVertexEntry: objectToVertexMap.entrySet()) { String key = objectToVertexEntry.getKey(); - ObjectVertex objectVertex = objectToVertexEntry.getValue(); + ObjectVertex ov = objectToVertexEntry.getValue(); if (key.matches("0")) { - staticVertexObject.add(objectVertex.getCell()); + staticObjectVertex.add(ov.getCell()); } else { - vertexObject.add(objectVertex.getCell()); + objectVertex.add(ov.getCell()); } - if(objectVertex.getVertexMethodExecutions().size() == 0) { - alignMiddleVertex.add(objectVertex.getCell()); + if(ov.getVertexMethodExecutions().size() == 0) { + alignMidObjectVertex.add(ov.getCell()); } else { - alignTopVertex.add(objectVertex.getCell()); + alignTopObjectVertex.add(ov.getCell()); } } - List vertexMethodExecList = new ArrayList<>(methodExecToVertexMap.values()); - Collections.reverse(vertexMethodExecList); - for (int i = 0; i < vertexMethodExecList.size(); i++) { + List methodExecVertexList = new ArrayList<>(methodExecToVertexMap.values()); + Collections.reverse(methodExecVertexList); + for (int i = 0; i < methodExecVertexList.size(); i++) { switch(i) { case 0: - ((mxICell)vertexMethodExecList.get(i).getCell()).setStyle("fillColor=#ff7fbf"); + ((mxICell)methodExecVertexList.get(i).getCell()).setStyle("fillColor=#ff7fbf"); break; case 1: - ((mxICell)vertexMethodExecList.get(i).getCell()).setStyle("fillColor=#ff99cc"); + ((mxICell)methodExecVertexList.get(i).getCell()).setStyle("fillColor=#ff99cc"); break; case 2: - ((mxICell)vertexMethodExecList.get(i).getCell()).setStyle("fillColor=#ffb2d8"); + ((mxICell)methodExecVertexList.get(i).getCell()).setStyle("fillColor=#ffb2d8"); break; case 3: - ((mxICell)vertexMethodExecList.get(i).getCell()).setStyle("fillColor=#ffcce5"); + ((mxICell)methodExecVertexList.get(i).getCell()).setStyle("fillColor=#ffcce5"); break; case 4: - ((mxICell)vertexMethodExecList.get(i).getCell()).setStyle("fillColor=#ffe0ef"); + ((mxICell)methodExecVertexList.get(i).getCell()).setStyle("fillColor=#ffe0ef"); break; default: break; @@ -1082,43 +1152,39 @@ roundEdge.add(edge.getCell()); switch(edge.getTypeName()) { case Reference: - edgeObject.add(edge.getCell()); + refEdge.add(edge.getCell()); break; case Create: - edgeObject.add(edge.getCell()); - edgeObjectCreate.add(edge.getCell()); + refEdge.add(edge.getCell()); + refCreateEdge.add(edge.getCell()); break; case Call: - edgeMethodExec.add(edge.getCell()); + methodExecEdge.add(edge.getCell()); break; default: break; } } - /*Given a cell, we can change it's style attributes, for example the color. NOTE that you have to call the graphComponent.refresh() function, otherwise you won't see the difference! */ - mxgraph.setCellStyles(mxConstants.STYLE_SHAPE, mxConstants.SHAPE_ELLIPSE, vertexObject.toArray(new Object[vertexObject.size()])); - mxgraph.setCellStyles(mxConstants.STYLE_PERIMETER, mxConstants.PERIMETER_ELLIPSE, vertexObject.toArray(new Object[vertexObject.size()])); - mxgraph.setCellStyleFlags(mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_UNDERLINE, true, vertexObject.toArray(new Object[vertexObject.size()])); - mxgraph.setCellStyles(mxConstants.STYLE_VERTICAL_ALIGN, mxConstants.ALIGN_MIDDLE, alignMiddleVertex.toArray(new Object[alignMiddleVertex.size()])); - mxgraph.setCellStyles(mxConstants.STYLE_VERTICAL_ALIGN, mxConstants.ALIGN_TOP, alignTopVertex.toArray(new Object[alignTopVertex.size()])); - mxgraph.setCellStyles(mxConstants.STYLE_EDGE, mxConstants.EDGESTYLE_TOPTOBOTTOM, edgeObject.toArray(new Object[edgeObject.size()])); - mxgraph.setCellStyleFlags(mxConstants.STYLE_DASHED, 1, true, edgeObjectCreate.toArray(new Object[edgeObjectCreate.size()])); - // mxgraph.setCellStyles(mxConstants.STYLE_EDGE, mxConstants.EDGESTYLE_ENTITY_RELATION, edgeObject.toArray(new Object[edgeObject.size()])); - // mxgraph.setCellStyles(mxConstants.STYLE_EDGE, mxConstants.EDGESTYLE_ORTHOGONAL, edgeObject.toArray(new Object[edgeObject.size()])); + // Styles ObjectVertex. + mxgraph.setCellStyles(mxConstants.STYLE_SHAPE, mxConstants.SHAPE_ELLIPSE, objectVertex.toArray(new Object[objectVertex.size()])); + mxgraph.setCellStyles(mxConstants.STYLE_PERIMETER, mxConstants.PERIMETER_ELLIPSE, objectVertex.toArray(new Object[objectVertex.size()])); + mxgraph.setCellStyleFlags(mxConstants.STYLE_FONTSTYLE, mxConstants.FONT_UNDERLINE, true, objectVertex.toArray(new Object[objectVertex.size()])); + mxgraph.setCellStyles(mxConstants.STYLE_VERTICAL_ALIGN, mxConstants.ALIGN_MIDDLE, alignMidObjectVertex.toArray(new Object[alignMidObjectVertex.size()])); + mxgraph.setCellStyles(mxConstants.STYLE_VERTICAL_ALIGN, mxConstants.ALIGN_TOP, alignTopObjectVertex.toArray(new Object[alignTopObjectVertex.size()])); + // Styles Edge. + mxgraph.setCellStyles(mxConstants.STYLE_EDGE, mxConstants.EDGESTYLE_TOPTOBOTTOM, refEdge.toArray(new Object[refEdge.size()])); + mxgraph.setCellStyleFlags(mxConstants.STYLE_DASHED, 1, true, refCreateEdge.toArray(new Object[refCreateEdge.size()])); mxgraph.setCellStyleFlags(mxConstants.STYLE_ROUNDED, 1, true, roundEdge.toArray(new Object[roundEdge.size()])); mxgraph.setCellStyles(mxConstants.STYLE_VERTICAL_ALIGN, mxConstants.ALIGN_TOP, roundEdge.toArray(new Object[roundEdge.size()])); mxgraph.setCellStyles(mxConstants.STYLE_VERTICAL_LABEL_POSITION, mxConstants.ALIGN_BOTTOM, roundEdge.toArray(new Object[roundEdge.size()])); - // mxgraph.setCellStyles(mxConstants.STYLE_EDGE, mxConstants.SHAPE_CURVE, edgeObject.toArray(new Object[edgeObject.size()])); - mxgraph.setCellStyles(mxConstants.STYLE_STROKECOLOR, "#008000", edgeMethodExec.toArray(new Object[edgeMethodExec.size()])); - mxgraph.setCellStyleFlags(mxConstants.STYLE_DASHED, 1, true, edgeMethodExec.toArray(new Object[edgeMethodExec.size()])); - // mxgraph.setCellStyleFlags(mxConstants.STYLE_AUTOSIZE, 1, true, vertexObject.toArray(new Object[vertexObject.size()])); - // mxgraph.setCellStyles(mxConstants.STYLE_EDGE, mxConstants.EDGESTYLE_ORTHOGONAL, edgeMethodExec.toArray(new Object[edgeMethodExec.size()])); - // mxgraph.setCellStyles(mxConstants.STYLE_ELBOW, mxConstants.ELBOW_VERTICAL, edgeMethodExec.toArray(new Object[edgeMethodExec.size()])); + // Styles MethodExecutionVertex. + mxgraph.setCellStyles(mxConstants.STYLE_STROKECOLOR, "#008000", methodExecEdge.toArray(new Object[methodExecEdge.size()])); + mxgraph.setCellStyleFlags(mxConstants.STYLE_DASHED, 1, true, methodExecEdge.toArray(new Object[methodExecEdge.size()])); } - private void setFrameSize(int width, int height) { - DEFAULT_SIZE.setSize(width, height); + private void setWindowSize(int width, int height) { + DEFAULT_WINDOW_SIZE.setSize(width, height); } protected Point getAbsolutePointforCell(mxICell cell) { @@ -1126,36 +1192,38 @@ if(cell.getParent().getValue() == null || cell == cell.getParent()) { return p1; } + // Test code (will be deleted) System.out.println(cell.getId() + ", " + cell.getParent().getId()); Point p2 = getAbsolutePointforCell(cell.getParent()); return new Point((int) (p1.getX() + p2.getX()), (int) (p1.getY() + p2.getY())); } - /** Update graph on JFrame and set Cell style. */ + /** + * Update the graph on the JFrame by styling the cells and refreshing the mxgraphComponent. + */ protected void update() { + /* Given a cell, we can change it's style attributes, for example the color. + * NOTE that you have to call the graphComponent.refresh() function, + * otherwise you won't see the difference! */ setCellsStyle(); mxgraphComponent.refresh(); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } } - private int countChildVertex(ObjectVertex vertexObject) { - int time = vertexObject.getVertexMethodExecutions().size(); + private int countChildVertex(ObjectVertex objectVertex) { + int time = objectVertex.getVertexMethodExecutions().size(); if(time == 0) { return 1; } - for(MethodExecutionVertex vertexMethodExecution: vertexObject.getVertexMethodExecutions()) { - for(ObjectVertex vo: vertexMethodExecution.getLocals()) { - time += countChildVertex(vo); + for(MethodExecutionVertex mev: objectVertex.getVertexMethodExecutions()) { + for(ObjectVertex ov: mev.getLocals()) { + time += countChildVertex(ov); } - for(ObjectVertex vo: vertexMethodExecution.getArguments()) { - return countChildVertex(vo); + for(ObjectVertex ov: mev.getArguments()) { + return countChildVertex(ov); } } - System.out.println(vertexObject.getLabel() + ": " + time); + // Test code (will be deleted) + System.out.println(objectVertex.getLabel() + ": " + time); return time; } @@ -1169,28 +1237,27 @@ } protected String formatMethodSignature(String methodSignature, String thisClassName) { - // TODO Modify algorithm formatMethodSignature(). + // TODO: Modify algorithm formatMethodSignature(). // Step1 : split "(" -// String[] methodSignatures = methodSignature.split("\\("); methodSignature = methodSignature.substring(0, methodSignature.lastIndexOf('(')); // Step2 : split " " - String[] methodSignatures = methodSignature.split(" "); - String tmpMethodSignature = methodSignatures[methodSignatures.length-1]; + String[] methodSigs = methodSignature.split(" "); + String tmpMethodSig = methodSigs[methodSigs.length-1]; // Step3 : split "." String[] thisClassNames = thisClassName.split("\\."); - methodSignatures = tmpMethodSignature.split("\\."); + methodSigs = tmpMethodSig.split("\\."); StringBuffer sb = new StringBuffer(); - int i = methodSignatures.length - 2; + int i = methodSigs.length - 2; int count = methodSignature.split("\\(").length - 1; if (count > 0) i -= count; - if (i >= 0 && !thisClassNames[thisClassNames.length - 1].equals(methodSignatures[i])) { - if (thisClassNames[thisClassNames.length - 1].equals(methodSignatures[i + 1])) i += 1; - sb.append(methodSignatures[i]); - if (methodSignatures.length - i > 1) sb.append("."); + if (i >= 0 && !thisClassNames[thisClassNames.length - 1].equals(methodSigs[i])) { + if (thisClassNames[thisClassNames.length - 1].equals(methodSigs[i + 1])) i += 1; + sb.append(methodSigs[i]); + if (methodSigs.length - i > 1) sb.append("."); } - for (i = i + 1; i < methodSignatures.length; i++) { - sb.append(methodSignatures[i]); - if (methodSignatures.length - i > 1) sb.append("."); + for (i = i + 1; i < methodSigs.length; i++) { + sb.append(methodSigs[i]); + if (methodSigs.length - i > 1) sb.append("."); } sb.append("()"); @@ -1217,11 +1284,14 @@ return sb.toString(); } + /** + * Test code (will be deleted) + */ protected void outputLog() { - for (Object object: mxgraph.getChildCells(mxDefaultParent)) { - System.out.println(object + " " + object.hashCode()); - for (int i = 0; i < ((mxICell)object).getChildCount(); i++) { - System.out.println(" " + ((mxICell)object).getChildAt(i) + " " + object.hashCode()); + for (Object obj: mxgraph.getChildCells(mxDefaultParent)) { + System.out.println(obj + " " + obj.hashCode()); + for (int i = 0; i < ((mxICell)obj).getChildCount(); i++) { + System.out.println(" " + ((mxICell)obj).getChildAt(i) + " " + obj.hashCode()); } } System.out.println("\nObject"); @@ -1253,29 +1323,31 @@ } /** - * Whether sourceCell parents contain targetCell. + * Whether sourceCell parents contain destinationCell. + * * @param sourceCell - * @param targetCell + * @param destinationCell * @return */ - private boolean isParent(mxICell sourceCell, mxICell targetCell) { - mxICell sourceParentCell = sourceCell.getParent(); - if (sourceParentCell == null || sourceParentCell.getValue() == null) { + private boolean isParent(mxICell sourceCell, mxICell destinationCell) { + mxICell srcPtCell = sourceCell.getParent(); + if (srcPtCell == null || srcPtCell.getValue() == null) { return false; } - if (sourceParentCell == targetCell) { + if (srcPtCell == destinationCell) { return true; } - System.out.println(sourceCell.getId() + ", " + sourceParentCell.getId()); - return isParent(sourceParentCell, targetCell); + // Test code (will be deleted) + System.out.println(sourceCell.getId() + ", " + srcPtCell.getId()); + return isParent(srcPtCell, destinationCell); } protected void reflectCoordinates(DeltaGraphAdapter mxgraph) { // TODO Auto-generated method stub } - public static Map.Entry getRelatedInformation(TracePoint rp) { - Statement rpStatement = rp.getStatement(); + public static Map.Entry getRelatedInformation(TracePoint relatedPoint) { + Statement rpStatement = relatedPoint.getStatement(); String rpSrcObjId = null; String rpDstObjId = null; String rpSrcClassName = null; @@ -1329,7 +1401,7 @@ } return new AbstractMap.SimpleEntry<>(new Reference(rpSrcObjId, rpDstObjId, rpSrcClassName, rpDstClassName), rpFieldName); } - + protected class CurvedCanvas extends mxInteractiveCanvas { mxIShape shape = new CurvedConnector(); @@ -1392,8 +1464,8 @@ if (state.getAbsolutePointCount() == 4) { double sx = state.getAbsolutePoint(0).getX(); double sy = state.getAbsolutePoint(0).getY(); - double tx1 = state.getAbsolutePoint(1).getX(); - double ty1 = state.getAbsolutePoint(1).getY(); +// double tx1 = state.getAbsolutePoint(1).getX(); +// double ty1 = state.getAbsolutePoint(1).getY(); double tx2 = state.getAbsolutePoint(2).getX(); double ty2 = state.getAbsolutePoint(2).getY(); double ex = state.getAbsolutePoint(3).getX();