BKNodePlacement.java 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. package bk;
  2. import java.lang.reflect.InvocationTargetException;
  3. import javax.swing.JFrame;
  4. import javax.swing.JTree;
  5. import animation.AnimatedAlgorithm;
  6. import animation.AnimationController;
  7. import animation.PseudoCodeNode;
  8. import animation.PseudoCodeNode.CodeAction;
  9. import graph.LayeredGraphNode;
  10. /**
  11. * The main stage of the BK node placement algorithm.
  12. * @author kolja
  13. *
  14. */
  15. public class BKNodePlacement extends AnimatedAlgorithm {
  16. /*
  17. * Private data structures to store the process of the algorithm
  18. */
  19. public enum State
  20. {
  21. CONFLICTS,
  22. LAYOUT1,
  23. LAYOUT2,
  24. LAYOUT3,
  25. LAYOUT4,
  26. COMBINE
  27. }
  28. private ConflictDetection conftion;
  29. private State state;
  30. private ExtremalLayoutCalc layouts[];
  31. private Combine combine;
  32. private PseudoCodeNode conflictsNode;
  33. private PseudoCodeNode layout1Node;
  34. private PseudoCodeNode layout2Node;
  35. private PseudoCodeNode layout3Node;
  36. private PseudoCodeNode layout4Node;
  37. private PseudoCodeNode combineNode;
  38. private boolean inside;
  39. public BKNodePlacement(AnimationController controller, LayeredGraphNode graph, JFrame view) {
  40. super(controller, graph, view);
  41. state = State.CONFLICTS;
  42. conftion = new ConflictDetection( graph );
  43. layouts = new ExtremalLayoutCalc[ 4 ];
  44. layouts[ 0 ] = new ExtremalLayoutCalc( ExtremalLayoutCalc.LayoutType.TOP_BOTTOM_LEFT, graph );
  45. layouts[ 1 ] = new ExtremalLayoutCalc( ExtremalLayoutCalc.LayoutType.TOP_BOTTOM_RIGHT, graph );
  46. layouts[ 2 ] = new ExtremalLayoutCalc( ExtremalLayoutCalc.LayoutType.BOTTOM_TOP_LEFT, graph );
  47. layouts[ 3 ] = new ExtremalLayoutCalc( ExtremalLayoutCalc.LayoutType.BOTTOM_TOP_RIGHT, graph );
  48. combine = new Combine( graph );
  49. inside = false;
  50. }
  51. public State getAlgorithmState()
  52. {
  53. return state;
  54. }
  55. @Override
  56. public StageStatus forwardStep() {
  57. return forward( "forwardStep" );
  58. }
  59. @Override
  60. public StageStatus backwardStep() {
  61. return backward( "backwardStep" );
  62. }
  63. @Override
  64. public PseudoCodeNode createPseudocodeTree( JTree tree )
  65. {
  66. PseudoCodeNode root = new PseudoCodeNode( "BK Node Placement Algorithm", tree );
  67. root.setSelected( true );
  68. conflictsNode = conftion.createPseudocodeTree( tree );
  69. layout1Node = layouts[ 0 ].createPseudocodeTree( tree );
  70. layout2Node = layouts[ 1 ].createPseudocodeTree( tree );
  71. layout3Node = layouts[ 2 ].createPseudocodeTree( tree );
  72. layout4Node = layouts[ 3 ].createPseudocodeTree( tree );
  73. combineNode = combine.createPseudocodeTree( tree );
  74. root.add( conflictsNode );
  75. root.add( layout1Node );
  76. root.add( layout2Node );
  77. root.add( layout3Node );
  78. root.add( layout4Node );
  79. root.add( combineNode );
  80. return root;
  81. }
  82. @Override
  83. public StageStatus forwardStepOver() {
  84. if( !inside )
  85. {
  86. State oldState = state;
  87. StageStatus status = StageStatus.UNFINISHED;
  88. while( state == oldState && status == StageStatus.UNFINISHED )
  89. status = forwardStep();
  90. return status;
  91. }
  92. else
  93. return forward( "forwardStepOver" );
  94. }
  95. @Override
  96. public StageStatus forwardStepOut() {
  97. if( !inside )
  98. {
  99. StageStatus status = StageStatus.UNFINISHED;
  100. while( status == StageStatus.UNFINISHED )
  101. status = forwardStep();
  102. return status;
  103. }
  104. else
  105. return forward( "forwardStepOut" );
  106. }
  107. @Override
  108. public StageStatus backwardStepOver() {
  109. if( !inside )
  110. {
  111. State oldState = state;
  112. StageStatus status = StageStatus.UNFINISHED;
  113. while( state == oldState && status == StageStatus.UNFINISHED )
  114. status = backwardStep();
  115. return status;
  116. }
  117. else
  118. return backward( "backwardStepOver" );
  119. }
  120. @Override
  121. public StageStatus backwardStepOut() {
  122. if( !inside )
  123. {
  124. StageStatus status = StageStatus.UNFINISHED;
  125. while( status == StageStatus.UNFINISHED )
  126. status = backwardStep();
  127. return status;
  128. }
  129. else
  130. return backward( "backwardStepOut" );
  131. }
  132. @Override
  133. public String getDebugString()
  134. {
  135. if( !inside )
  136. return "";
  137. switch( state )
  138. {
  139. case CONFLICTS:
  140. return combine.getDebugString();
  141. case LAYOUT1:
  142. return layouts[ 0 ].getDebugString();
  143. case LAYOUT2:
  144. return layouts[ 1 ].getDebugString();
  145. case LAYOUT3:
  146. return layouts[ 2 ].getDebugString();
  147. case LAYOUT4:
  148. return layouts[ 3 ].getDebugString();
  149. case COMBINE:
  150. return combine.getDebugString();
  151. }
  152. return "";
  153. }
  154. private StageStatus forward( String fName )
  155. {
  156. boolean breakpoint = false;
  157. CodeAction action = null;
  158. try {
  159. switch( state )
  160. {
  161. case CONFLICTS:
  162. action = conflictsNode.setSelected( true );
  163. if( !conflictsNode.isSelected() )
  164. breakpoint |= action == CodeAction.STOP;
  165. do {
  166. switch( (StageStatus)(ConflictDetection.class.getMethod( fName ).invoke( conftion ) ) )
  167. {
  168. case FINISHED:
  169. inside = false;
  170. conflictsNode.setSelected( false );
  171. CodeAction ca = layout1Node.setSelected( true );
  172. breakpoint |= ca == CodeAction.STOP;
  173. state = State.LAYOUT1;
  174. if( ca == CodeAction.SKIP && !breakpoint )
  175. return forward( fName );
  176. break;
  177. case BREAKPOINT:
  178. inside = true;
  179. return StageStatus.BREAKPOINT;
  180. case UNFINISHED:
  181. inside = true;
  182. }
  183. } while( !breakpoint && action == CodeAction.SKIP );
  184. break;
  185. case LAYOUT1:
  186. action = layout1Node.setSelected( true );
  187. do {
  188. switch( (StageStatus)(ExtremalLayoutCalc.class.getMethod( fName ).invoke( layouts[ 0 ] ) ) )
  189. {
  190. case FINISHED:
  191. inside = false;
  192. layout1Node.setSelected( false );
  193. CodeAction ca = layout2Node.setSelected( true );
  194. breakpoint |= ca == CodeAction.STOP;
  195. state = State.LAYOUT2;
  196. if( ca == CodeAction.SKIP && !breakpoint )
  197. return forward( fName );
  198. break;
  199. case BREAKPOINT:
  200. inside = true;
  201. return StageStatus.BREAKPOINT;
  202. case UNFINISHED:
  203. inside = true;
  204. }
  205. } while( !breakpoint && action == CodeAction.SKIP );
  206. break;
  207. case LAYOUT2:
  208. action = layout2Node.setSelected( true );
  209. do {
  210. switch( (StageStatus)(ExtremalLayoutCalc.class.getMethod( fName ).invoke( layouts[ 1 ] ) ) )
  211. {
  212. case FINISHED:
  213. inside = false;
  214. layout2Node.setSelected( false );
  215. CodeAction ca = layout3Node.setSelected( true );
  216. breakpoint |= ca == CodeAction.STOP;
  217. state = State.LAYOUT3;
  218. if( ca == CodeAction.SKIP && !breakpoint )
  219. return forward( fName );
  220. break;
  221. case BREAKPOINT:
  222. inside = true;
  223. return StageStatus.BREAKPOINT;
  224. case UNFINISHED:
  225. inside = true;
  226. }
  227. } while( !breakpoint && action == CodeAction.SKIP );
  228. break;
  229. case LAYOUT3:
  230. action = layout3Node.setSelected( true );
  231. do {
  232. switch( (StageStatus)(ExtremalLayoutCalc.class.getMethod( fName ).invoke( layouts[ 2 ] ) ) )
  233. {
  234. case FINISHED:
  235. inside = false;
  236. layout3Node.setSelected( false );
  237. CodeAction ca = layout4Node.setSelected( true );
  238. breakpoint |= ca == CodeAction.STOP;
  239. state = State.LAYOUT4;
  240. if( ca == CodeAction.SKIP && !breakpoint )
  241. return forward( fName );
  242. break;
  243. case BREAKPOINT:
  244. inside = true;
  245. return StageStatus.BREAKPOINT;
  246. case UNFINISHED:
  247. inside = true;
  248. }
  249. } while( !breakpoint && action == CodeAction.SKIP );
  250. break;
  251. case LAYOUT4:
  252. action = layout4Node.setSelected( true );
  253. do {
  254. switch( (StageStatus)(ExtremalLayoutCalc.class.getMethod( fName ).invoke( layouts[ 3 ] ) ) )
  255. {
  256. case FINISHED:
  257. inside = false;
  258. layout4Node.setSelected( false );
  259. CodeAction ca = combineNode.setSelected( true );
  260. breakpoint |= ca == CodeAction.STOP;
  261. state = State.COMBINE;
  262. if( ca == CodeAction.SKIP && !breakpoint )
  263. return forward( fName );
  264. break;
  265. case BREAKPOINT:
  266. inside = true;
  267. return StageStatus.BREAKPOINT;
  268. case UNFINISHED:
  269. inside = true;
  270. }
  271. } while( !breakpoint && action == CodeAction.SKIP );
  272. break;
  273. case COMBINE:
  274. action = combineNode.setSelected( true );
  275. do {
  276. switch( (StageStatus)(Combine.class.getMethod( fName ).invoke( combine ) ) )
  277. {
  278. case FINISHED:
  279. inside = false;
  280. return StageStatus.FINISHED;
  281. case BREAKPOINT:
  282. return StageStatus.BREAKPOINT;
  283. case UNFINISHED:
  284. inside = true;
  285. }
  286. } while( !breakpoint && action == CodeAction.SKIP );
  287. }
  288. } catch (IllegalAccessException e) {
  289. e.printStackTrace();
  290. } catch (IllegalArgumentException e) {
  291. e.printStackTrace();
  292. } catch (InvocationTargetException e) {
  293. e.printStackTrace();
  294. } catch (NoSuchMethodException e) {
  295. e.printStackTrace();
  296. } catch (SecurityException e) {
  297. e.printStackTrace();
  298. }
  299. if( breakpoint )
  300. return StageStatus.BREAKPOINT;
  301. return StageStatus.UNFINISHED;
  302. }
  303. private StageStatus backward( String fName ) {
  304. boolean breakpoint = false;
  305. CodeAction action = null;
  306. try {
  307. switch( state )
  308. {
  309. case CONFLICTS:
  310. action = conflictsNode.setSelected( true );
  311. do {
  312. switch( (StageStatus)(ConflictDetection.class.getMethod( fName ).invoke( conftion ) ) )
  313. {
  314. case FINISHED:
  315. inside = false;
  316. return StageStatus.FINISHED;
  317. case BREAKPOINT:
  318. inside = true;
  319. return StageStatus.BREAKPOINT;
  320. case UNFINISHED:
  321. inside = true;
  322. }
  323. } while( !breakpoint && action == CodeAction.SKIP );
  324. case LAYOUT1:
  325. action = layout1Node.setSelected( true );
  326. do {
  327. switch( (StageStatus)(ExtremalLayoutCalc.class.getMethod( fName ).invoke( layouts[ 0 ] ) ) )
  328. {
  329. case FINISHED:
  330. inside = false;
  331. layout1Node.setSelected( false );
  332. CodeAction ca = conflictsNode.setSelected( true );
  333. breakpoint |= ca == CodeAction.STOP;
  334. state = State.CONFLICTS;
  335. if( ca == CodeAction.SKIP && !breakpoint )
  336. return backward( fName );
  337. break;
  338. case BREAKPOINT:
  339. inside = true;
  340. return StageStatus.BREAKPOINT;
  341. case UNFINISHED:
  342. inside = true;
  343. }
  344. } while( !breakpoint && action == CodeAction.SKIP );
  345. break;
  346. case LAYOUT2:
  347. action = layout2Node.setSelected( true );
  348. do {
  349. switch( (StageStatus)(ExtremalLayoutCalc.class.getMethod( fName ).invoke( layouts[ 1 ] ) ) )
  350. {
  351. case FINISHED:
  352. inside = false;
  353. layout2Node.setSelected( false );
  354. CodeAction ca = layout1Node.setSelected( true );
  355. breakpoint |= ca == CodeAction.STOP;
  356. state = State.LAYOUT1;
  357. if( ca == CodeAction.SKIP && !breakpoint )
  358. return backward( fName );
  359. break;
  360. case BREAKPOINT:
  361. inside = true;
  362. return StageStatus.BREAKPOINT;
  363. case UNFINISHED:
  364. inside = true;
  365. }
  366. } while( !breakpoint && action == CodeAction.SKIP );
  367. break;
  368. case LAYOUT3:
  369. action = layout3Node.setSelected( true );
  370. do {
  371. switch( (StageStatus)(ExtremalLayoutCalc.class.getMethod( fName ).invoke( layouts[ 2 ] ) ) )
  372. {
  373. case FINISHED:
  374. inside = false;
  375. layout3Node.setSelected( false );
  376. CodeAction ca = layout2Node.setSelected( true );
  377. breakpoint |= ca == CodeAction.STOP;
  378. state = State.LAYOUT2;
  379. if( ca == CodeAction.SKIP && !breakpoint )
  380. return backward( fName );
  381. break;
  382. case BREAKPOINT:
  383. inside = true;
  384. return StageStatus.BREAKPOINT;
  385. case UNFINISHED:
  386. inside = true;
  387. }
  388. } while( !breakpoint && action == CodeAction.SKIP );
  389. break;
  390. case LAYOUT4:
  391. action = layout4Node.setSelected( true );
  392. do {
  393. switch( (StageStatus)(ExtremalLayoutCalc.class.getMethod( fName ).invoke( layouts[ 3 ] ) ) )
  394. {
  395. case FINISHED:
  396. inside = false;
  397. layout4Node.setSelected( false );
  398. CodeAction ca = layout3Node.setSelected( true );
  399. breakpoint |= ca == CodeAction.STOP;
  400. state = State.LAYOUT3;
  401. if( ca == CodeAction.SKIP && !breakpoint )
  402. return backward( fName );
  403. break;
  404. case BREAKPOINT:
  405. inside = true;
  406. return StageStatus.BREAKPOINT;
  407. case UNFINISHED:
  408. inside = true;
  409. }
  410. } while( !breakpoint && action == CodeAction.SKIP );
  411. break;
  412. case COMBINE:
  413. action = combineNode.setSelected( true );
  414. do {
  415. switch( (StageStatus)(Combine.class.getMethod( fName ).invoke( combine ) ) )
  416. {
  417. case FINISHED:
  418. inside = false;
  419. combineNode.setSelected( false );
  420. CodeAction ca = layout4Node.setSelected( true );
  421. breakpoint |= ca == CodeAction.STOP;
  422. state = State.LAYOUT4;
  423. if( ca == CodeAction.SKIP && !breakpoint )
  424. return backward( fName );
  425. break;
  426. case BREAKPOINT:
  427. inside = true;
  428. return StageStatus.BREAKPOINT;
  429. case UNFINISHED:
  430. inside = true;
  431. }
  432. } while( !breakpoint && action == CodeAction.SKIP );
  433. break;
  434. }
  435. } catch (IllegalAccessException e) {
  436. e.printStackTrace();
  437. } catch (IllegalArgumentException e) {
  438. e.printStackTrace();
  439. } catch (InvocationTargetException e) {
  440. e.printStackTrace();
  441. } catch (NoSuchMethodException e) {
  442. e.printStackTrace();
  443. } catch (SecurityException e) {
  444. e.printStackTrace();
  445. }
  446. if( breakpoint )
  447. return StageStatus.BREAKPOINT;
  448. return StageStatus.UNFINISHED;
  449. }
  450. }