diff --git a/src/org/ntlab/animations/MagnetRONAnimation.java b/src/org/ntlab/animations/MagnetRONAnimation.java
new file mode 100644
index 0000000..52e1200
--- /dev/null
+++ b/src/org/ntlab/animations/MagnetRONAnimation.java
@@ -0,0 +1,472 @@
+package org.ntlab.animations;
+
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.geom.Dimension2D;
+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 {
+
+ // Test code (will be deleted)
+ private static final String TAG = MagnetRONAnimation.class.getSimpleName();
+
+ 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 initial size of sourceCell.
+ */
+ private Dimension2D sourceInitDimension;
+
+ /**
+ * The possible state for MagnetRONAnimation.
+ */
+ protected static enum Status {
+ /**
+ * The paused state.
+ */
+ PAUSED,
+ /**
+ * The running state.
+ */
+ RUNNING,
+ /**
+ * The stopped state.
+ */
+ STOPPED
+ }
+
+ private static int animationCount = 0;
+
+ /**
+ * 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 setSourceInitialDimension(Dimension2D sourceInitDimension) {
+ this.sourceInitDimension = sourceInitDimension;
+ }
+
+ protected void setScheduledFuture(ScheduledFuture> scheduledFuture) {
+ this.scheduledFuture = scheduledFuture;
+ }
+
+ protected abstract void setDestination(double x, double y);
+
+ protected abstract void setVelocity(double x, double y);
+
+ 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 getSourceInitialPoint() {
+ return sourceInitPoint;
+ }
+
+ protected Dimension2D getSourceInitialDimension() {
+ return sourceInitDimension;
+ }
+
+ protected ScheduledFuture> getScheduledFuture() {
+ return scheduledFuture;
+ }
+
+ /**
+ * 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
+ */
+ public void init(mxICell sourceCell, double destinationX, double destinationY, ThreadPoolExecutor threadPoolExecutor) {
+ setSourceCell(sourceCell);
+ setDestination(destinationX, destinationY);
+ setThreadPoolExecutor(threadPoolExecutor);
+ setSourceInitialPoint(getSourceCell().getGeometry().getPoint());
+ setSourceInitialDimension(
+ new Dimension((int) getSourceCell().getGeometry().getWidth(),
+ (int) getSourceCell().getGeometry().getHeight()));
+ setCurrentCycleCount(0);
+ }
+
+ public void updateCurrentCycle() {
+ if (!getReverse()) { // Animation direction is forward.
+ setCurrentCycleCount((int) (currentCycleCount + Math.signum(getTotalCycleCount())));
+ } 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();
+ setThreadPoolExecutor(scheduledThreadPoolExecutor);
+ ScheduledFuture> scheduledFuture = scheduledThreadPoolExecutor.scheduleWithFixedDelay(new TimerTask() {
+ @Override
+ public void run() {
+ if(Math.abs(getCurrentCycleCount()) < Math.abs(getTotalCycleCount())) {
+ // Test code (will be deleted)
+ System.out.println(TAG + ": Run task " + getSourceCell().getId() + " " + MagnetRONAnimation.this.getClass().getSimpleName() + "-" + getCurrentCycleCount() + ". ThreadId=" + Thread.currentThread().getId());
+ updateCurrentCycle();
+ jumpTo(getCurrentCycleCount());
+ } else if(Math.abs(getCurrentCycleCount()) >= Math.abs(getTotalCycleCount())){
+ animationCount = 0;
+ onFinished();
+ }
+ }
+ }, getInitialDelay(), getDelay(), TimeUnit.MILLISECONDS);
+ setScheduledFuture(scheduledFuture);
+ setCurrentStatus(Status.RUNNING);
+ animationCount = 1;
+ };
+ break;
+ case PAUSED:
+ if (getThreadPoolExecutor() != null & getThreadPoolExecutor() instanceof MagnetRONScheduledThreadPoolExecutor) {
+ MagnetRONScheduledThreadPoolExecutor scheduledThreadPoolExecutor = (MagnetRONScheduledThreadPoolExecutor) getThreadPoolExecutor();
+ scheduledThreadPoolExecutor.resume();
+ setCurrentStatus(Status.RUNNING);
+ }
+ break;
+ default:
+ break;
+ };
+ }
+
+ /**
+ * Sleep main thread and wait for {@link MagnetRONAnimation#play()} to finish running.
+ */
+ public static void waitAnimationEnd() {
+ while (animationCount > 0) {
+ try {
+ Thread.sleep(1L);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ // Buffer for another waiting animation.
+ try {
+ Thread.sleep(30L);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Play animation in sync with main thread.
+ */
+ public void syncPlay() {
+ if (getCurrentStatus() == Status.STOPPED) {
+ try {
+ Thread.sleep(getInitialDelay());
+ while (true) {
+ while (getCurrentStatus() == Status.PAUSED) {
+ Thread.sleep(1L);
+ }
+ if(Math.abs(getCurrentCycleCount()) < Math.abs(getTotalCycleCount())) {
+ // Test code (will be deleted)
+ System.out.println(TAG + ": Run task " + getSourceCell().getId() + " " + MagnetRONAnimation.this.getClass().getSimpleName() + "-" + getCurrentCycleCount() + ". ThreadId=" + Thread.currentThread().getId());
+ updateCurrentCycle();
+ jumpTo(getCurrentCycleCount());
+ } else if(Math.abs(getCurrentCycleCount()) >= Math.abs(getTotalCycleCount())){
+ onFinished();
+ break;
+ }
+ Thread.sleep(getDelay());
+ }
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public void playFormStart() {
+
+ }
+
+ public void stop() {
+ if (getCurrentStatus() == Status.RUNNING) {
+ getScheduledFuture().cancel(true);
+ }
+ 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);
+}
diff --git a/src/org/ntlab/animations/TranslateAnimation.java b/src/org/ntlab/animations/TranslateAnimation.java
new file mode 100644
index 0000000..723e4d0
--- /dev/null
+++ b/src/org/ntlab/animations/TranslateAnimation.java
@@ -0,0 +1,108 @@
+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;
+
+/**
+ * Animation of edge stretching and shrinking, vertex translating.
+ *
+ * @author Nitta Lab.
+ */
+public class TranslateAnimation extends MagnetRONAnimation {
+
+ // Test code (will be deleted)
+ private static final String TAG = TranslateAnimation.class.getSimpleName();
+
+ /**
+ * The destination point where the sourceCell animates.
+ */
+ private Point2D destinationPoint;
+ /**
+ * The point to update for each cycle count.
+ */
+ private Point2D velocity;
+
+ /**
+ * The constructor of {@code TranslateAnimation}.
+ *
+ * @param mxgraph
+ * @param mxgraphComponent
+ */
+ public TranslateAnimation(DeltaGraphAdapter mxgraph, mxGraphComponent mxgraphComponent) {
+ super(mxgraph, mxgraphComponent);
+ }
+
+ @Override
+ protected void setDestination(double x, double y) {
+ setDestinationPoint(new Point2D.Double(x, y));
+ }
+
+ private void setDestinationPoint(Point2D destinationPoint) {
+ this.destinationPoint = destinationPoint;
+ }
+
+ @Override
+ protected void setVelocity(double x, double y) {
+ setVelocity(new Point2D.Double(x, y));
+ }
+
+ private void setVelocity(Point2D velocity) {
+ this.velocity = velocity;
+ }
+
+ private Point2D getDestinationPoint() {
+ return destinationPoint;
+ }
+
+ private Point2D getVelocity() {
+ return velocity;
+ }
+
+ public void init(mxICell sourceCell, Point2D destinationPoint, ThreadPoolExecutor threadPoolExecutor) {
+ init(sourceCell, destinationPoint.getX(), destinationPoint.getY(), threadPoolExecutor);
+ }
+
+ /**
+ * See {@code MagnetRONAnimation#init(mxICell, double, double, ThreadPoolExecutor)}
+ *
+ * @param sourceCell
+ * @param destinationPoint
+ * @param threadPoolExecutor
+ */
+ @Override
+ public void init(mxICell sourceCell, double x, double y, ThreadPoolExecutor threadPoolExecutor) {
+ super.init(sourceCell, x, y, threadPoolExecutor);
+
+ Point2D curPt = new Point(sourceCell.getGeometry().getPoint());
+
+ // Calculate resize line model
+ Point2D distancePoint = new Point();
+ distancePoint.setLocation(destinationPoint.getX() - curPt.getX(),
+ destinationPoint.getY() - curPt.getY());
+ Point2D velocity = new Point2D.Double();
+ velocity.setLocation(distancePoint.getX() / getTotalCycleCount(), distancePoint.getY() / getTotalCycleCount());
+ setVelocity(velocity);
+ }
+
+ @Override
+ protected void jumpTo(int currentCycleCount) {
+ // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology.
+ mxgraph.getModel().beginUpdate();
+ synchronized(mxgraph.getModel()) {
+ try {
+ getSourceCell().getGeometry().setX(getSourceInitialPoint().getX() + getVelocity().getX() * currentCycleCount);
+ getSourceCell().getGeometry().setY(getSourceInitialPoint().getY() + getVelocity().getY() * currentCycleCount);
+ } finally {
+ mxgraph.getModel().endUpdate();
+ }
+ mxgraphComponent.refresh();
+ }
+ }
+
+}
diff --git a/src/org/ntlab/animations/VertexResizeAnimation.java b/src/org/ntlab/animations/VertexResizeAnimation.java
new file mode 100644
index 0000000..4c020a3
--- /dev/null
+++ b/src/org/ntlab/animations/VertexResizeAnimation.java
@@ -0,0 +1,109 @@
+package org.ntlab.animations;
+
+import java.awt.Dimension;
+import java.awt.geom.Dimension2D;
+import java.util.concurrent.ThreadPoolExecutor;
+
+import org.ntlab.deltaViewer.DeltaGraphAdapter;
+
+import com.mxgraph.model.mxICell;
+import com.mxgraph.swing.mxGraphComponent;
+
+/**
+ * Animation to resize vertex.
+ *
+ * @author Nitta Lab.
+ */
+public class VertexResizeAnimation extends MagnetRONAnimation {
+
+ // Test code (will be deleted)
+ private static final String TAG = VertexResizeAnimation.class.getSimpleName();
+
+ /**
+ * The destination dimension where the sourceCell animates.
+ */
+ private Dimension2D destinationDimension;
+ /**
+ * The dimension to update for each cycle count.
+ */
+ private Dimension2D velocity;
+
+ /**
+ * The constructor of {@code VertexResizeAnimation}.
+ *
+ * @param mxgraph
+ * @param mxgraphComponent
+ */
+ public VertexResizeAnimation(DeltaGraphAdapter mxgraph, mxGraphComponent mxgraphComponent) {
+ super(mxgraph, mxgraphComponent);
+ }
+
+ @Override
+ protected void setDestination(double x, double y) {
+ setDestinationDimension(new Dimension((int) x, (int) y));
+ }
+
+ private void setDestinationDimension(Dimension2D destinationDimension) {
+ this.destinationDimension = destinationDimension;
+ }
+
+ @Override
+ protected void setVelocity(double x, double y) {
+ setVelocity(new Dimension((int) x, (int) y));
+ }
+
+ private void setVelocity(Dimension2D velocity) {
+ this.velocity = velocity;
+ }
+
+ private Dimension2D getDestinationDimension() {
+ return destinationDimension;
+ }
+
+ private Dimension2D getVelocity() {
+ return velocity;
+ }
+
+ public void init(mxICell sourceCell, Dimension2D destinationDimension, ThreadPoolExecutor threadPoolExecutor) {
+ init(sourceCell, destinationDimension.getWidth(), destinationDimension.getHeight(), threadPoolExecutor);
+ }
+
+ /**
+ * See {@code MagnetRONAnimation#init(mxICell, double, double, ThreadPoolExecutor)}
+ *
+ * @param sourceCell
+ * @param destinationDimension
+ * @param threadPoolExecutor
+ */
+ @Override
+ public void init(mxICell sourceCell, double width, double height, ThreadPoolExecutor threadPoolExecutor) {
+ super.init(sourceCell, width, height, threadPoolExecutor);
+
+ Dimension2D curDim = new Dimension();
+ curDim.setSize(sourceCell.getGeometry().getWidth(), sourceCell.getGeometry().getHeight());
+
+ // Calculate resize dimension model
+ Dimension2D distanceDimension = new Dimension();
+ distanceDimension.setSize(destinationDimension.getWidth() - curDim.getWidth(),
+ destinationDimension.getHeight() - curDim.getHeight());
+ Dimension2D velocity = new Dimension();
+ velocity.setSize(distanceDimension.getWidth() / getTotalCycleCount(), distanceDimension.getHeight() / getTotalCycleCount());
+ setVelocity(velocity);
+ }
+
+ @Override
+ protected void jumpTo(int currentCycleCount) {
+ // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology.
+ mxgraph.getModel().beginUpdate();
+ synchronized(mxgraph.getModel()) {
+ try {
+ getSourceCell().getGeometry().setWidth(getSourceInitialDimension().getWidth() + getVelocity().getWidth() * currentCycleCount);
+ getSourceCell().getGeometry().setHeight(getSourceInitialDimension().getHeight() + getVelocity().getHeight() * currentCycleCount);
+ } finally {
+ mxgraph.getModel().endUpdate();
+ }
+ mxgraphComponent.refresh();
+ }
+ }
+
+}
diff --git a/src/org/ntlab/deltaViewer/CollaborationViewer.java b/src/org/ntlab/deltaViewer/CollaborationViewer.java
index 19f68a0..6cbb48d 100644
--- a/src/org/ntlab/deltaViewer/CollaborationViewer.java
+++ b/src/org/ntlab/deltaViewer/CollaborationViewer.java
@@ -1,13 +1,13 @@
package org.ntlab.deltaViewer;
-import java.awt.BorderLayout;
-import java.awt.Dimension;
-import java.awt.Point;
+import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import org.ntlab.animations.MagnetRONAnimation;
+import org.ntlab.animations.TranslateAnimation;
import org.ntlab.deltaExtractor.Alias;
import org.ntlab.deltaExtractor.IAliasCollector;
import org.ntlab.deltaExtractor.Alias.AliasType;
@@ -22,10 +22,15 @@
import org.ntlab.trace.TracePoint;
import com.mxgraph.model.mxICell;
-import com.mxgraph.util.mxPoint;
import com.mxgraph.view.mxGraphView;
public class CollaborationViewer extends MagnetRONViewer {
+
+ private static final long serialVersionUID = 9123813231037494846L;
+
+ // Test code (will be deleted)
+ private static final String TAG = CollaborationViewer.class.getSimpleName();
+
private IObjectCallGraph objectCallGraph;
private double scale = 1;
@@ -69,7 +74,7 @@
System.out.println(", " + scale);
// scale = 1.5;
view.setScale(scale);
- deltaAnimation.setScale(scale);
+// deltaAnimation.setScale(scale);
update();
}
@@ -92,9 +97,9 @@
* @param numFrame Current animation frame.
*/
public void stepToAnimation(int numFrame) {
- // TODO Implement doLastAnimation to support plural Delta.
- // TOD curFrame debug.
- System.out.println("Frame: " + curFrame + "->" + numFrame);
+ // TODO: Implement doLastAnimation to support plural Delta.
+ // TODO: curFrame debug.
+ System.out.println(TAG + ": Frame=" + curFrame + "->" + numFrame);
// if (numFrame - curFrame == 1) {
List relatedPoints = objectCallGraph.getRelatedPoints();
List aliasList = aliasCollector.getAliasList();
@@ -105,7 +110,7 @@
if (curFrameAlias != null) {
for (TracePoint rp: relatedPoints) {
if (curFrameAlias.getTimeStamp() < rp.getStatement().getTimeStamp() && rp.getStatement().getTimeStamp() < numFrameAlias.getTimeStamp()) {
- System.out.println("\r\nLast Animation.");
+ System.out.println("\r\n" + TAG + ": Last Animation.");
doLastAnimation(numFrame, rp);
return;
}
@@ -113,19 +118,18 @@
}
doAnimation(curFrame, numFrame);
} else if (curFrameAlias != null && numFrameAlias == null) {
- System.out.println("\r\nLast Animation.");
+ System.out.println("\r\n" + TAG + ": Last Animation.");
doLastAnimation(numFrame, relatedPoints.get(relatedPoints.size() - 1));
} else {
- System.out.println("ERROR : Not exist alias.");
+ System.out.println(TAG + ": ERROR Not exist alias.");
}
// } else {
- // TODO Considering fast-forwarding animations.
+ // TODO: Considering fast-forwarding animations.
// }
}
private void doLastAnimation(int numFrame, TracePoint relatedPoint) {
- // TODO Implement doLastAnimation to support plural Delta.
- outputLog();
+ // TODO: Implement doLastAnimation to support plural Delta.
curFrame = numFrame;
List aliasList = aliasCollector.getAliasList();
Alias prevAlias = aliasList.get(numFrame - 1);
@@ -171,8 +175,8 @@
String tgtObjId = null;
//Array��List�̂Ƃ��������x����t����i�m���ɕ������Ă�����̂Ƃ�)getSignature->contains("List.get(") || "Map.get(") <�z���C�g���X�g>
-// if (methodExec.getSignature().contains("List.add(") ||
-// methodExec.getSignature().contains("Map.put(")) {
+// if (methodExec.getSignature().contains("List.add(") ||
+// methodExec.getSignature().contains("Map.put(")) {
if (calledMethodExec.isCollectionType()
&& (methodSignature.contains("add(")
|| methodSignature.contains("set(")
@@ -261,82 +265,119 @@
// updateObjectVertices();
// }
- // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology.
- mxgraph.getModel().beginUpdate();
- try {
- List meList = new ArrayList<>(methodExecToVertexMap.keySet());
- Collections.reverse(meList);
- System.out.println(meList.size());
- for(int i = 0; i < meList.size(); i++) {
- String objectId = meList.get(i).getThisObjId();
- ObjectVertex sourceVertexObject = objectToVertexMap.get(objectId); // sourceVertex
- MethodExecution me = meList.get(i);
- if (nextAlias != null && me.getSignature().equals(nextAlias.getMethodSignature())) break;
- if (i != meList.size()-1) {
- for(Statement st: me.getStatements()) {
- if(st instanceof MethodInvocation) {
- MethodExecution calledMethodExec = ((MethodInvocation) st).getCalledMethodExecution();
- String calledObjectId = calledMethodExec.getThisObjId();
- System.out.println(calledObjectId);
- if(objectToVertexMap.containsKey(calledObjectId)) {
- mxICell calledCell = (mxICell)objectToVertexMap.get(calledObjectId).getCell();
- Point absolutePointCalledCell = getAbsolutePointforCell(calledCell);
- System.out.println(objectId + ", " + me.getSignature());
-// objectToVertexMap.get(calledObjectId).resetCellPosition();
-// if (methodExecToVertexMap.get(methodExec).getArguments().contains(objectToVertexMap.get(calledObjectId)) || methodExecToVertexMap.get(methodExec).getLocals().contains(objectToVertexMap.get(calledObjectId))) {
-// calledCell.getParent().remove(calledCell);
-// calledCell.setParent(mxDefaultParent);
-// calledCell.getGeometry().setX(absolutePointCalledCell.getX());
-// calledCell.getGeometry().setY(absolutePointCalledCell.getY());
-// deltaAnimation.setVertexAnimation(calledCell, new mxPoint(objectToVertexMap.get(calledObjectId).getInitialX(), objectToVertexMap.get(calledObjectId).getInitialY()));
-// deltaAnimation.startVertexAnimation();
-// }
- removeCalledMethodExecutionVertex(sourceVertexObject, me.getCallerMethodExecution(), me);
- updateObjectVertices();
-// removeVertexMethodExecution(sourceVertexObject, methodExec);
-// update();
- break;
+ List meList = new ArrayList<>(methodExecToVertexMap.keySet());
+ Collections.reverse(meList);
+ System.out.println(meList.size());
+ for(int i = 0; i < meList.size(); i++) {
+ String objectId = meList.get(i).getThisObjId();
+ ObjectVertex sourceVertexObject = objectToVertexMap.get(objectId); // sourceVertex
+ MethodExecution me = meList.get(i);
+ if (nextAlias != null && me.getSignature().equals(nextAlias.getMethodSignature())) break;
+ if (i != meList.size()-1) {
+ for(Statement st: me.getStatements()) {
+ if(st instanceof MethodInvocation) {
+ MethodExecution calledMethodExec = ((MethodInvocation) st).getCalledMethodExecution();
+ String calledObjectId = calledMethodExec.getThisObjId();
+ System.out.println(calledObjectId);
+ if(objectToVertexMap.containsKey(calledObjectId)) {
+ mxICell calledCell = (mxICell)objectToVertexMap.get(calledObjectId).getCell();
+ Point2D absolutePointCalledCell = getAbsolutePointforCell(calledCell);
+ System.out.println(objectId + ", " + me.getSignature());
+// objectToVertexMap.get(calledObjectId).resetCellPosition();
+// if (methodExecToVertexMap.get(methodExec).getArguments().contains(objectToVertexMap.get(calledObjectId)) || methodExecToVertexMap.get(methodExec).getLocals().contains(objectToVertexMap.get(calledObjectId))) {
+// calledCell.getParent().remove(calledCell);
+// calledCell.setParent(mxDefaultParent);
+// calledCell.getGeometry().setX(absolutePointCalledCell.getX());
+// calledCell.getGeometry().setY(absolutePointCalledCell.getY());
+// deltaAnimation.setVertexAnimation(calledCell, new mxPoint(objectToVertexMap.get(calledObjectId).getInitialX(), objectToVertexMap.get(calledObjectId).getInitialY()));
+// deltaAnimation.startVertexAnimation();
+// }
+ removeCalledMethodExecutionVertex(sourceVertexObject, me.getCallerMethodExecution(), me);
+ updateObjectVertices();
+// removeVertexMethodExecution(sourceVertexObject, methodExec);
+// update();
+ break;
+ }
+ }
+ }
+ } else {
+ outputLog();
+
+ // Change!
+ List arguments = new ArrayList<>(methodExecToVertexMap.get(me).getArguments());
+ List locals = new ArrayList<>(methodExecToVertexMap.get(me).getLocals());
+ if (arguments.size() != 0) {
+ for (ObjectVertex vo: arguments) {
+ mxICell cell = (mxICell)vo.getCell();
+ Point2D absolutePointCell = getAbsolutePointforCell(cell);
+ // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology.
+ mxgraph.getModel().beginUpdate();
+ synchronized (mxgraph.getModel()) {
+ try {
+// cell.getParent().remove(cell);
+// cell.setParent(mxDefaultParent);
+ if (!cell.getParent().equals(getMxDefaultParent())) {
+ // If parent of ObjectVertex cell isn't mxDefaltParent, reset parent.
+ cell.getParent().remove(cell);
+ cell.setParent(getMxDefaultParent());
+ }
+ cell.getGeometry().setX(absolutePointCell.getX());
+ cell.getGeometry().setY(absolutePointCell.getY());
+ } finally {
+ mxgraph.getModel().endUpdate();
}
}
- }
- } else {
- outputLog();
- // Change!
- List arguments = new ArrayList<>(methodExecToVertexMap.get(me).getArguments());
- List locals = new ArrayList<>(methodExecToVertexMap.get(me).getLocals());
- if (arguments.size() != 0) {
- for (ObjectVertex vo: arguments) {
- mxICell cell = (mxICell)vo.getCell();
- Point absolutePointCell = getAbsolutePointforCell(cell);
- cell.getParent().remove(cell);
- cell.setParent(mxDefaultParent);
- cell.getGeometry().setX(absolutePointCell.getX());
- cell.getGeometry().setY(absolutePointCell.getY());
- deltaAnimation.setVertexAnimation(cell, new mxPoint(vo.getInitialX(), vo.getInitialY()));
- deltaAnimation.startVertexAnimation();
- methodExecToVertexMap.get(me).getArguments().remove(vo);
- }
- }else if (locals.size() != 0) {
- for (ObjectVertex vo: locals) {
- mxICell cell = (mxICell)vo.getCell();
- Point absolutePointCell = getAbsolutePointforCell(cell);
- cell.getParent().remove(cell);
- cell.setParent(mxDefaultParent);
- cell.getGeometry().setX(absolutePointCell.getX());
- cell.getGeometry().setY(absolutePointCell.getY());
- deltaAnimation.setVertexAnimation(cell, new mxPoint(vo.getInitialX(), vo.getInitialY()));
- deltaAnimation.startVertexAnimation();
- methodExecToVertexMap.get(me).getLocals().remove(vo);
- }
+// deltaAnimation.setVertexAnimation(cell, new mxPoint(vo.getInitialX(), vo.getInitialY()));
+// deltaAnimation.startVertexAnimation();
+// deltaAnimation.sleepThread(DEFAULT_THREAD_SLEEP_MILLIS);
+ MagnetRONAnimation vertexAnim = new TranslateAnimation(mxgraph, getGraphComponent());
+ vertexAnim.setTotalCycleCount(10);
+ vertexAnim.setDelay(100);
+ vertexAnim.init(cell, vo.getInitialX(), vo.getInitialY(), threadPoolExecutor);
+// vertexAnim.play();
+// sleepMainThread(DEFAULT_THREAD_SLEEP_MILLIS);
+ vertexAnim.syncPlay();
+ methodExecToVertexMap.get(me).getArguments().remove(vo);
}
- updateObjectVertices();
+ }else if (locals.size() != 0) {
+ for (ObjectVertex vo: locals) {
+ mxICell cell = (mxICell)vo.getCell();
+ Point2D absolutePointCell = getAbsolutePointforCell(cell);
+ // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology.
+ mxgraph.getModel().beginUpdate();
+ synchronized (mxgraph.getModel()) {
+ try {
+// cell.getParent().remove(cell);
+// cell.setParent(mxDefaultParent);
+ if (!cell.getParent().equals(getMxDefaultParent())) {
+ // If parent of ObjectVertex cell isn't mxDefaltParent, reset parent.
+ cell.getParent().remove(cell);
+ cell.setParent(getMxDefaultParent());
+ }
+ cell.getGeometry().setX(absolutePointCell.getX());
+ cell.getGeometry().setY(absolutePointCell.getY());
+ } finally {
+ mxgraph.getModel().endUpdate();
+ }
+ }
+// deltaAnimation.setVertexAnimation(cell, new mxPoint(vo.getInitialX(), vo.getInitialY()));
+// deltaAnimation.startVertexAnimation();
+// deltaAnimation.sleepThread(DEFAULT_THREAD_SLEEP_MILLIS);
+ MagnetRONAnimation vertexAnim = new TranslateAnimation(mxgraph, getGraphComponent());
+ vertexAnim.setTotalCycleCount(10);
+ vertexAnim.setDelay(100);
+ vertexAnim.init(cell, vo.getInitialX(), vo.getInitialY(), threadPoolExecutor);
+// vertexAnim.play();
+// sleepMainThread(DEFAULT_THREAD_SLEEP_MILLIS);
+ vertexAnim.syncPlay();
+ methodExecToVertexMap.get(me).getLocals().remove(vo);
+ }
}
+ updateObjectVertices();
}
- } finally {
- mxgraph.getModel().endUpdate();
}
- update();
+ update();
}
/**
@@ -350,14 +391,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(getMxDefaultParent(), 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));
}
@@ -371,7 +412,7 @@
if (srcClassName.contains("[L")) {
srcClassName = formatArrayName(srcClassName);
}
- Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, ref.getSrcObjectId(), srcClassName, 0, 0, vertexObjWidth, vertexObjHeight, "fillColor=white"); //creates a white vertex.
+ Object vertex = mxgraph.insertDeltaVertex(getMxDefaultParent(), ref.getSrcObjectId(), srcClassName, 0, 0, vertexObjWidth, vertexObjHeight, "fillColor=white"); //creates a white vertex.
objectToVertexMap.put(ref.getSrcObjectId(), new ObjectVertex(ref.getSrcClassName(), vertex, 0, 0));
}
// dstSide
@@ -381,7 +422,7 @@
if (dstClassName.contains("[L")) {
dstClassName = formatArrayName(dstClassName);
}
- Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, ref.getDstObjectId(), dstClassName, 0, 0, vertexObjWidth, vertexObjHeight, "fillColor=white"); //creates a white vertex.
+ Object vertex = mxgraph.insertDeltaVertex(getMxDefaultParent(), ref.getDstObjectId(), dstClassName, 0, 0, vertexObjWidth, vertexObjHeight, "fillColor=white"); //creates a white vertex.
objectToVertexMap.put(ref.getDstObjectId(), new ObjectVertex(ref.getDstClassName(), vertex, 0, 0));
}
} else {
@@ -390,7 +431,7 @@
if (srcClassName.contains("[L")) {
srcClassName = formatArrayName(srcClassName);
}
- Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, ref.getSrcObjectId(), srcClassName, 0, 0, vertexObjWidth, vertexObjHeight, "fillColor=white"); //creates a white vertex.
+ Object vertex = mxgraph.insertDeltaVertex(getMxDefaultParent(), ref.getSrcObjectId(), srcClassName, 0, 0, vertexObjWidth, vertexObjHeight, "fillColor=white"); //creates a white vertex.
objectToVertexMap.put(ref.getSrcObjectId(), new ObjectVertex(ref.getSrcClassName(), vertex, 0, 0));
}
if (!objectToVertexMap.containsKey(ref.getDstObjectId())) {
@@ -498,9 +539,9 @@
if (srcCell != null && dstCell != null) { // isCreation()
System.out.println("makeEdgeObject: " + fieldName + ", " + srcClassName + " (" + srcCell.hashCode() + "), " + " (" + dstCell.hashCode() + ")"/* + ", " + dstClassName*/);
// BUG:NullPointerException
- Object edge = mxgraph.insertDeltaEdge(mxDefaultParent, fieldName, fieldName, srcCell, dstCell);
- Point absPtSrcCell = getAbsolutePointforCell((mxICell)srcCell);
- Point absPtDstCell = getAbsolutePointforCell((mxICell)dstCell);
+ Object edge = mxgraph.insertDeltaEdge(getMxDefaultParent(), fieldName, fieldName, srcCell, dstCell);
+ Point2D absPtSrcCell = getAbsolutePointforCell((mxICell)srcCell);
+ Point2D absPtDstCell = getAbsolutePointforCell((mxICell)dstCell);
setEdgePoint((mxICell)edge, absPtSrcCell, absPtDstCell);
edgeMap.put(srcClassName + "." + fieldName, new Edge(fieldName, TypeName.Reference, edge));
}
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/DeltaGraphAdapter.java b/src/org/ntlab/deltaViewer/DeltaGraphAdapter.java
index 86046c3..ae7841d 100644
--- a/src/org/ntlab/deltaViewer/DeltaGraphAdapter.java
+++ b/src/org/ntlab/deltaViewer/DeltaGraphAdapter.java
@@ -1,17 +1,14 @@
package org.ntlab.deltaViewer;
-import java.util.AbstractMap.SimpleEntry;
-import java.util.HashMap;
-import java.util.Map.Entry;
import org.jgrapht.Graph;
import org.jgrapht.ext.JGraphXAdapter;
-import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.DirectedWeightedPseudograph;
import com.mxgraph.model.mxCell;
import com.mxgraph.model.mxGeometry;
import com.mxgraph.model.mxICell;
+import com.mxgraph.model.mxIGraphModel;
import com.mxgraph.util.mxConstants;
/**
@@ -21,10 +18,14 @@
*/
public class DeltaGraphAdapter extends JGraphXAdapter