LayeredEdge.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. package graph;
  2. import java.awt.Point;
  3. import java.util.ArrayList;
  4. import org.eclipse.elk.graph.ElkEdge;
  5. import bk.LayoutType;
  6. import view.NodeView;
  7. /**
  8. * Die Implementation einer Kante aus einem Layered Graphen.
  9. * Implementiert {@link LayeredGraphEdge}.
  10. *
  11. * @author kolja
  12. *
  13. */
  14. public class LayeredEdge implements LayeredGraphEdge {
  15. private ElkEdge original;
  16. private ArrayList< LayeredGraphNode > sources;
  17. private ArrayList< LayeredGraphNode > targets;
  18. private LayeredGraphNode graph;
  19. private boolean reversed;
  20. private boolean dummy;
  21. private ArrayList< Point >[] bindPoints;
  22. private boolean[] conflicted;
  23. /**
  24. * creates a {@link LayeredEdge} from an {@link ElkEdge}.
  25. * @param original the original {@link ElkEdge}.
  26. * @param sources the sources of the edge.
  27. * @param targets the targets of the edge.
  28. * @param graph the graph containing the edge.
  29. */
  30. @SuppressWarnings("unchecked")
  31. public LayeredEdge( ElkEdge original, ArrayList< LayeredGraphNode > sources, ArrayList< LayeredGraphNode > targets, LayeredGraphNode graph )
  32. {
  33. this.original = original;
  34. this.sources = sources;
  35. this.targets = targets;
  36. this.graph = graph;
  37. reversed = false;
  38. dummy = false;
  39. bindPoints = new ArrayList[ 5 ];
  40. conflicted = new boolean[ 5 ];
  41. for( int i = 0; i < 5; i++ )
  42. {
  43. conflicted[ i ] = false;
  44. bindPoints[ i ] = new ArrayList<>();
  45. }
  46. for( ArrayList<Point> bps : bindPoints )
  47. {
  48. bps.add( null );
  49. bps.add( null );
  50. }
  51. }
  52. @Override
  53. public boolean isConflicted( LayoutType layout )
  54. { // see javadoc for better understanding of what this does
  55. if( layout == LayoutType.LEFTMOST_UPPER )
  56. return conflicted[ 0 ];
  57. if( layout == LayoutType.RIGHTMOST_UPPER )
  58. return conflicted[ 1 ];
  59. if( layout == LayoutType.LEFTMOST_LOWER )
  60. return conflicted[ 2 ];
  61. if( layout == LayoutType.RIGHTMOST_LOWER )
  62. return conflicted[ 3 ];
  63. if( layout == LayoutType.COMBINED )
  64. return conflicted[ 4 ];
  65. return false;
  66. }
  67. @Override
  68. public void setConflicted( boolean conflicted, LayoutType layout )
  69. { // see javadoc for better understanding of what this does
  70. if( layout == null )
  71. {
  72. this.conflicted[ 0 ] = conflicted;
  73. this.conflicted[ 1 ] = conflicted;
  74. this.conflicted[ 2 ] = conflicted;
  75. this.conflicted[ 3 ] = conflicted;
  76. this.conflicted[ 4 ] = conflicted;
  77. }
  78. if( layout == LayoutType.LEFTMOST_UPPER )
  79. this.conflicted[ 0 ] = conflicted;
  80. if( layout == LayoutType.RIGHTMOST_UPPER )
  81. this.conflicted[ 1 ] = conflicted;
  82. if( layout == LayoutType.LEFTMOST_LOWER )
  83. this.conflicted[ 2 ] = conflicted;
  84. if( layout == LayoutType.RIGHTMOST_LOWER )
  85. this.conflicted[ 3 ] = conflicted;
  86. if( layout == LayoutType.COMBINED )
  87. this.conflicted[ 4 ] = conflicted;
  88. }
  89. @Override
  90. public void setStartPoint( int x, int y, LayoutType layout )
  91. { // see javadoc for better understanding of what this does
  92. if( layout == null )
  93. {
  94. bindPoints[ 0 ].set( 0, new Point( x, y ) );
  95. bindPoints[ 1 ].set( 0, new Point( x, y ) );
  96. bindPoints[ 2 ].set( 0, new Point( x, y ) );
  97. bindPoints[ 3 ].set( 0, new Point( x, y ) );
  98. bindPoints[ 4 ].set( 0, new Point( x, y ) );
  99. }
  100. if( layout == LayoutType.LEFTMOST_UPPER )
  101. bindPoints[ 0 ].set( 0, new Point( x, y ) );
  102. if( layout == LayoutType.RIGHTMOST_UPPER )
  103. bindPoints[ 1 ].set( 0, new Point( x, y ) );
  104. if( layout == LayoutType.LEFTMOST_LOWER )
  105. bindPoints[ 2 ].set( 0, new Point( x, y ) );
  106. if( layout == LayoutType.RIGHTMOST_LOWER )
  107. bindPoints[ 3 ].set( 0, new Point( x, y ) );
  108. if( layout == LayoutType.COMBINED )
  109. bindPoints[ 4 ].set( 0, new Point( x, y ) );
  110. }
  111. @Override
  112. public void addBindPoint( int x, int y, LayoutType layout )
  113. { // see javadoc for better understanding of what this does
  114. if( layout == null )
  115. {
  116. bindPoints[ 0 ].add( bindPoints[ 0 ].size() - 1, new Point( x, y ) );
  117. bindPoints[ 1 ].add( bindPoints[ 1 ].size() - 1, new Point( x, y ) );
  118. bindPoints[ 2 ].add( bindPoints[ 2 ].size() - 1, new Point( x, y ) );
  119. bindPoints[ 3 ].add( bindPoints[ 3 ].size() - 1, new Point( x, y ) );
  120. bindPoints[ 4 ].add( bindPoints[ 4 ].size() - 1, new Point( x, y ) );
  121. }
  122. if( layout == LayoutType.LEFTMOST_UPPER )
  123. bindPoints[ 0 ].add( bindPoints[ 0 ].size() - 1, new Point( x, y ) );
  124. if( layout == LayoutType.RIGHTMOST_UPPER )
  125. bindPoints[ 1 ].add( bindPoints[ 1 ].size() - 1, new Point( x, y ) );
  126. if( layout == LayoutType.LEFTMOST_LOWER )
  127. bindPoints[ 2 ].add( bindPoints[ 2 ].size() - 1, new Point( x, y ) );
  128. if( layout == LayoutType.RIGHTMOST_LOWER )
  129. bindPoints[ 3 ].add( bindPoints[ 3 ].size() - 1, new Point( x, y ) );
  130. if( layout == LayoutType.COMBINED )
  131. bindPoints[ 4 ].add( bindPoints[ 4 ].size() - 1, new Point( x, y ) );
  132. }
  133. @Override
  134. public void setEndPoint( int x, int y, LayoutType layout )
  135. { // see javadoc for better understanding of what this does
  136. if( layout == null )
  137. {
  138. bindPoints[ 0 ].set( bindPoints[ 0 ].size() - 1, new Point( x, y ) );
  139. bindPoints[ 1 ].set( bindPoints[ 1 ].size() - 1, new Point( x, y ) );
  140. bindPoints[ 2 ].set( bindPoints[ 2 ].size() - 1, new Point( x, y ) );
  141. bindPoints[ 3 ].set( bindPoints[ 3 ].size() - 1, new Point( x, y ) );
  142. bindPoints[ 4 ].set( bindPoints[ 4 ].size() - 1, new Point( x, y ) );
  143. }
  144. if( layout == LayoutType.LEFTMOST_UPPER )
  145. bindPoints[ 0 ].set( bindPoints[ 0 ].size() - 1, new Point( x, y ) );
  146. if( layout == LayoutType.RIGHTMOST_UPPER )
  147. bindPoints[ 1 ].set( bindPoints[ 1 ].size() - 1, new Point( x, y ) );
  148. if( layout == LayoutType.LEFTMOST_LOWER )
  149. bindPoints[ 2 ].set( bindPoints[ 2 ].size() - 1, new Point( x, y ) );
  150. if( layout == LayoutType.RIGHTMOST_LOWER )
  151. bindPoints[ 3 ].set( bindPoints[ 3 ].size() - 1, new Point( x, y ) );
  152. if( layout == LayoutType.COMBINED )
  153. bindPoints[ 4 ].set( bindPoints[ 4 ].size() - 1, new Point( x, y ) );
  154. }
  155. @Override
  156. public ArrayList<Point> getLinePoints( LayoutType layout )
  157. { // see javadoc for better understanding of what this does
  158. NodeView sourceView = ((LayeredNode)sources.get( 0 )).getView( layout );
  159. NodeView targetView = ((LayeredNode)targets.get( 0 )).getView( layout );
  160. setStartPoint( sourceView.getVirtualX() + sourceView.getVirtualWidth() / 2, sourceView.getVirtualY() + sourceView.getVirtualHeight(), layout );
  161. setEndPoint( targetView.getVirtualX() + targetView.getVirtualWidth() / 2, targetView.getVirtualY(), layout );
  162. if( layout == LayoutType.LEFTMOST_UPPER )
  163. return bindPoints[ 0 ];
  164. if( layout == LayoutType.RIGHTMOST_UPPER )
  165. return bindPoints[ 1 ];
  166. if( layout == LayoutType.LEFTMOST_LOWER )
  167. return bindPoints[ 2 ];
  168. if( layout == LayoutType.RIGHTMOST_LOWER )
  169. return bindPoints[ 3 ];
  170. if( layout == LayoutType.COMBINED )
  171. return bindPoints[ 4 ];
  172. return null;
  173. }
  174. @Override
  175. public ElkEdge getOriginalEdge() {
  176. return original;
  177. }
  178. @Override
  179. public void remove() {
  180. graph.removeEdge( this );
  181. }
  182. @Override
  183. public ArrayList<LayeredGraphNode> getSources() {
  184. return sources;
  185. }
  186. @Override
  187. public ArrayList<LayeredGraphNode> getTargets() {
  188. return targets;
  189. }
  190. @Override
  191. public boolean isCrossLayerEdge() {
  192. // check source
  193. int sl = sources.get( 0 ).getLayer();
  194. for( LayeredGraphNode s : sources )
  195. {
  196. if( sl != s.getLayer() )
  197. return true;
  198. }
  199. // check target
  200. int tl = targets.get( 0 ).getLayer();
  201. if( Math.abs( tl - sl ) != 1 )
  202. return true;
  203. for( LayeredGraphNode t : targets )
  204. {
  205. if( tl != t.getLayer() )
  206. return true;
  207. }
  208. return false;
  209. }
  210. @Override
  211. public void replaceByDummyNodes() {
  212. if( isCrossLayerEdge() ) // cross layer edge?
  213. {
  214. remove(); // remove this edge
  215. if( sources.size() == 1 && targets.size() == 1 )
  216. {
  217. LayeredGraphNode last = sources.get( 0 );
  218. int sl = last.getLayer();
  219. int tl = targets.get( 0 ).getLayer();
  220. for( int i = sl + 1; i < tl; i++ ) // for each layer
  221. {
  222. // add a dummy edge and a dummy node
  223. LayeredGraphNode n = graph.createNode( null );
  224. n.setLayer( i );
  225. LayeredGraphEdge e = graph.createSimpleEdge( original, last, n );
  226. e.setDummyEdge();
  227. if( reversed )
  228. e.setReversedEdge();
  229. last = n;
  230. }
  231. // create last dummy edge
  232. LayeredGraphEdge e = graph.createSimpleEdge( original, last, targets.get( 0 ) );
  233. e.setDummyEdge();
  234. if( reversed )
  235. e.setReversedEdge();
  236. }
  237. }
  238. }
  239. @Override
  240. public void reverse() {
  241. reversed = !reversed;
  242. ArrayList< LayeredGraphNode > tmp = sources;
  243. sources = targets;
  244. targets = tmp;
  245. }
  246. @Override
  247. public boolean isDummyEdge() {
  248. return dummy;
  249. }
  250. @Override
  251. public void removeDummyNodes() {
  252. if( isDummyEdge() )
  253. {
  254. // remove the dummy edge
  255. remove();
  256. // remove the sources
  257. ArrayList< LayeredGraphNode > sours = sources;
  258. for( int i = 0; i < sours.size(); i++ )
  259. {
  260. LayeredGraphNode n = sours.get( i );
  261. if( n.getOriginalNode() == null )
  262. {
  263. sours.remove( n );
  264. for( LayeredGraphEdge e : n.getIncomingEdges() )
  265. {
  266. if( e.isDummyEdge() && e.getOriginalEdge() == original )
  267. sours.addAll( e.getSources() );
  268. }
  269. }
  270. }
  271. // remove the targets
  272. ArrayList< LayeredGraphNode > targs = targets;
  273. for( int i = 0; i < targs.size(); i++ )
  274. {
  275. LayeredGraphNode n = targs.get( i );
  276. if( n.getOriginalNode() == null )
  277. {
  278. targs.remove( n );
  279. for( LayeredGraphEdge e : n.getOutgoingEdges() )
  280. {
  281. if( e.isDummyEdge() && e.getOriginalEdge() == original )
  282. targs.addAll( e.getTargets() );
  283. }
  284. }
  285. }
  286. // add old edge again
  287. LayeredGraphEdge e = graph.createEdge( original, sours, targs );
  288. if( reversed )
  289. e.setReversedEdge();
  290. }
  291. }
  292. @Override
  293. public void setDummyEdge() {
  294. dummy = true;
  295. }
  296. @Override
  297. public void setReversedEdge() {
  298. reversed = true;
  299. }
  300. @Override
  301. public void setGraph(LayeredGraphNode graph) {
  302. this.graph = graph;
  303. }
  304. @Override
  305. public boolean isReversedEdge() {
  306. return reversed;
  307. }
  308. @Override
  309. public String toString() {
  310. return "(" + sources.get( 0 ).toString() + "," + targets.get( 0 ).toString() + ")";
  311. }
  312. }