BKNodePlacement.java 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  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 conftion.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. boolean selected = conflictsNode.isSelected();
  163. action = conflictsNode.setSelected( true );
  164. if( !selected )
  165. breakpoint |= action == CodeAction.STOP;
  166. do {
  167. switch( (StageStatus)(ConflictDetection.class.getMethod( fName ).invoke( conftion ) ) )
  168. {
  169. case FINISHED:
  170. inside = false;
  171. conflictsNode.setSelected( false );
  172. CodeAction ca = layout1Node.setSelected( true );
  173. breakpoint |= ca == CodeAction.STOP;
  174. state = State.LAYOUT1;
  175. if( ca == CodeAction.SKIP && !breakpoint )
  176. return forward( fName );
  177. break;
  178. case BREAKPOINT:
  179. inside = true;
  180. return StageStatus.BREAKPOINT;
  181. case UNFINISHED:
  182. inside = true;
  183. }
  184. } while( !breakpoint && action == CodeAction.SKIP );
  185. break;
  186. case LAYOUT1:
  187. action = layout1Node.setSelected( true );
  188. do {
  189. switch( (StageStatus)(ExtremalLayoutCalc.class.getMethod( fName ).invoke( layouts[ 0 ] ) ) )
  190. {
  191. case FINISHED:
  192. inside = false;
  193. layout1Node.setSelected( false );
  194. CodeAction ca = layout2Node.setSelected( true );
  195. breakpoint |= ca == CodeAction.STOP;
  196. state = State.LAYOUT2;
  197. if( ca == CodeAction.SKIP && !breakpoint )
  198. return forward( fName );
  199. break;
  200. case BREAKPOINT:
  201. inside = true;
  202. return StageStatus.BREAKPOINT;
  203. case UNFINISHED:
  204. inside = true;
  205. }
  206. } while( !breakpoint && action == CodeAction.SKIP );
  207. break;
  208. case LAYOUT2:
  209. action = layout2Node.setSelected( true );
  210. do {
  211. switch( (StageStatus)(ExtremalLayoutCalc.class.getMethod( fName ).invoke( layouts[ 1 ] ) ) )
  212. {
  213. case FINISHED:
  214. inside = false;
  215. layout2Node.setSelected( false );
  216. CodeAction ca = layout3Node.setSelected( true );
  217. breakpoint |= ca == CodeAction.STOP;
  218. state = State.LAYOUT3;
  219. if( ca == CodeAction.SKIP && !breakpoint )
  220. return forward( fName );
  221. break;
  222. case BREAKPOINT:
  223. inside = true;
  224. return StageStatus.BREAKPOINT;
  225. case UNFINISHED:
  226. inside = true;
  227. }
  228. } while( !breakpoint && action == CodeAction.SKIP );
  229. break;
  230. case LAYOUT3:
  231. action = layout3Node.setSelected( true );
  232. do {
  233. switch( (StageStatus)(ExtremalLayoutCalc.class.getMethod( fName ).invoke( layouts[ 2 ] ) ) )
  234. {
  235. case FINISHED:
  236. inside = false;
  237. layout3Node.setSelected( false );
  238. CodeAction ca = layout4Node.setSelected( true );
  239. breakpoint |= ca == CodeAction.STOP;
  240. state = State.LAYOUT4;
  241. if( ca == CodeAction.SKIP && !breakpoint )
  242. return forward( fName );
  243. break;
  244. case BREAKPOINT:
  245. inside = true;
  246. return StageStatus.BREAKPOINT;
  247. case UNFINISHED:
  248. inside = true;
  249. }
  250. } while( !breakpoint && action == CodeAction.SKIP );
  251. break;
  252. case LAYOUT4:
  253. action = layout4Node.setSelected( true );
  254. do {
  255. switch( (StageStatus)(ExtremalLayoutCalc.class.getMethod( fName ).invoke( layouts[ 3 ] ) ) )
  256. {
  257. case FINISHED:
  258. inside = false;
  259. layout4Node.setSelected( false );
  260. CodeAction ca = combineNode.setSelected( true );
  261. breakpoint |= ca == CodeAction.STOP;
  262. state = State.COMBINE;
  263. if( ca == CodeAction.SKIP && !breakpoint )
  264. return forward( fName );
  265. break;
  266. case BREAKPOINT:
  267. inside = true;
  268. return StageStatus.BREAKPOINT;
  269. case UNFINISHED:
  270. inside = true;
  271. }
  272. } while( !breakpoint && action == CodeAction.SKIP );
  273. break;
  274. case COMBINE:
  275. action = combineNode.setSelected( true );
  276. do {
  277. switch( (StageStatus)(Combine.class.getMethod( fName ).invoke( combine ) ) )
  278. {
  279. case FINISHED:
  280. inside = false;
  281. return StageStatus.FINISHED;
  282. case BREAKPOINT:
  283. return StageStatus.BREAKPOINT;
  284. case UNFINISHED:
  285. inside = true;
  286. }
  287. } while( !breakpoint && action == CodeAction.SKIP );
  288. }
  289. } catch (IllegalAccessException e) {
  290. e.printStackTrace();
  291. } catch (IllegalArgumentException e) {
  292. e.printStackTrace();
  293. } catch (InvocationTargetException e) {
  294. e.printStackTrace();
  295. } catch (NoSuchMethodException e) {
  296. e.printStackTrace();
  297. } catch (SecurityException e) {
  298. e.printStackTrace();
  299. }
  300. if( breakpoint )
  301. return StageStatus.BREAKPOINT;
  302. return StageStatus.UNFINISHED;
  303. }
  304. private StageStatus backward( String fName ) {
  305. boolean breakpoint = false;
  306. CodeAction action = null;
  307. try {
  308. switch( state )
  309. {
  310. case CONFLICTS:
  311. action = conflictsNode.setSelected( true );
  312. do {
  313. switch( (StageStatus)(ConflictDetection.class.getMethod( fName ).invoke( conftion ) ) )
  314. {
  315. case FINISHED:
  316. inside = false;
  317. conflictsNode.setSelected( false );
  318. return StageStatus.FINISHED;
  319. case BREAKPOINT:
  320. inside = true;
  321. return StageStatus.BREAKPOINT;
  322. case UNFINISHED:
  323. inside = true;
  324. }
  325. } while( !breakpoint && action == CodeAction.SKIP );
  326. case LAYOUT1:
  327. action = layout1Node.setSelected( true );
  328. do {
  329. switch( (StageStatus)(ExtremalLayoutCalc.class.getMethod( fName ).invoke( layouts[ 0 ] ) ) )
  330. {
  331. case FINISHED:
  332. inside = false;
  333. layout1Node.setSelected( false );
  334. CodeAction ca = conflictsNode.setSelected( true );
  335. breakpoint |= ca == CodeAction.STOP;
  336. state = State.CONFLICTS;
  337. if( ca == CodeAction.SKIP && !breakpoint )
  338. return backward( fName );
  339. break;
  340. case BREAKPOINT:
  341. inside = true;
  342. return StageStatus.BREAKPOINT;
  343. case UNFINISHED:
  344. inside = true;
  345. }
  346. } while( !breakpoint && action == CodeAction.SKIP );
  347. break;
  348. case LAYOUT2:
  349. action = layout2Node.setSelected( true );
  350. do {
  351. switch( (StageStatus)(ExtremalLayoutCalc.class.getMethod( fName ).invoke( layouts[ 1 ] ) ) )
  352. {
  353. case FINISHED:
  354. inside = false;
  355. layout2Node.setSelected( false );
  356. CodeAction ca = layout1Node.setSelected( true );
  357. breakpoint |= ca == CodeAction.STOP;
  358. state = State.LAYOUT1;
  359. if( ca == CodeAction.SKIP && !breakpoint )
  360. return backward( fName );
  361. break;
  362. case BREAKPOINT:
  363. inside = true;
  364. return StageStatus.BREAKPOINT;
  365. case UNFINISHED:
  366. inside = true;
  367. }
  368. } while( !breakpoint && action == CodeAction.SKIP );
  369. break;
  370. case LAYOUT3:
  371. action = layout3Node.setSelected( true );
  372. do {
  373. switch( (StageStatus)(ExtremalLayoutCalc.class.getMethod( fName ).invoke( layouts[ 2 ] ) ) )
  374. {
  375. case FINISHED:
  376. inside = false;
  377. layout3Node.setSelected( false );
  378. CodeAction ca = layout2Node.setSelected( true );
  379. breakpoint |= ca == CodeAction.STOP;
  380. state = State.LAYOUT2;
  381. if( ca == CodeAction.SKIP && !breakpoint )
  382. return backward( fName );
  383. break;
  384. case BREAKPOINT:
  385. inside = true;
  386. return StageStatus.BREAKPOINT;
  387. case UNFINISHED:
  388. inside = true;
  389. }
  390. } while( !breakpoint && action == CodeAction.SKIP );
  391. break;
  392. case LAYOUT4:
  393. action = layout4Node.setSelected( true );
  394. do {
  395. switch( (StageStatus)(ExtremalLayoutCalc.class.getMethod( fName ).invoke( layouts[ 3 ] ) ) )
  396. {
  397. case FINISHED:
  398. inside = false;
  399. layout4Node.setSelected( false );
  400. CodeAction ca = layout3Node.setSelected( true );
  401. breakpoint |= ca == CodeAction.STOP;
  402. state = State.LAYOUT3;
  403. if( ca == CodeAction.SKIP && !breakpoint )
  404. return backward( fName );
  405. break;
  406. case BREAKPOINT:
  407. inside = true;
  408. return StageStatus.BREAKPOINT;
  409. case UNFINISHED:
  410. inside = true;
  411. }
  412. } while( !breakpoint && action == CodeAction.SKIP );
  413. break;
  414. case COMBINE:
  415. action = combineNode.setSelected( true );
  416. do {
  417. switch( (StageStatus)(Combine.class.getMethod( fName ).invoke( combine ) ) )
  418. {
  419. case FINISHED:
  420. inside = false;
  421. combineNode.setSelected( false );
  422. CodeAction ca = layout4Node.setSelected( true );
  423. breakpoint |= ca == CodeAction.STOP;
  424. state = State.LAYOUT4;
  425. if( ca == CodeAction.SKIP && !breakpoint )
  426. return backward( fName );
  427. break;
  428. case BREAKPOINT:
  429. inside = true;
  430. return StageStatus.BREAKPOINT;
  431. case UNFINISHED:
  432. inside = true;
  433. }
  434. } while( !breakpoint && action == CodeAction.SKIP );
  435. break;
  436. }
  437. } catch (IllegalAccessException e) {
  438. e.printStackTrace();
  439. } catch (IllegalArgumentException e) {
  440. e.printStackTrace();
  441. } catch (InvocationTargetException e) {
  442. e.printStackTrace();
  443. } catch (NoSuchMethodException e) {
  444. e.printStackTrace();
  445. } catch (SecurityException e) {
  446. e.printStackTrace();
  447. }
  448. if( breakpoint )
  449. return StageStatus.BREAKPOINT;
  450. return StageStatus.UNFINISHED;
  451. }
  452. }