MainView.java 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734
  1. package view;
  2. import java.awt.BorderLayout;
  3. import java.awt.Color;
  4. import java.awt.Dimension;
  5. import java.awt.Font;
  6. import java.awt.GridBagConstraints;
  7. import java.awt.GridBagLayout;
  8. import java.awt.GridLayout;
  9. import java.awt.event.ActionEvent;
  10. import java.awt.event.ActionListener;
  11. import java.awt.event.ComponentAdapter;
  12. import java.awt.event.ComponentEvent;
  13. import java.awt.event.FocusEvent;
  14. import java.awt.event.FocusListener;
  15. import java.awt.event.KeyEvent;
  16. import javax.swing.JButton;
  17. import javax.swing.JDialog;
  18. import javax.swing.JFrame;
  19. import javax.swing.JLabel;
  20. import javax.swing.JLayeredPane;
  21. import javax.swing.JPanel;
  22. import javax.swing.JScrollPane;
  23. import javax.swing.JTextArea;
  24. import javax.swing.JTextField;
  25. import javax.swing.JTree;
  26. import javax.swing.event.DocumentEvent;
  27. import javax.swing.event.DocumentListener;
  28. import javax.swing.tree.DefaultTreeModel;
  29. import animation.Action;
  30. import animation.AnimationController;
  31. import bk.BKNodePlacement;
  32. import bk.ExtremalLayoutCalc.LayoutType;
  33. import graph.InitializeNodePositions;
  34. import graph.LayeredGraphEdge;
  35. import graph.LayeredGraphNode;
  36. import graph.RandomGraphGenerator;
  37. import lib.SweepCrossingMinimizer;
  38. /**
  39. * The main window of the application.
  40. * There should only be one instance of this class at the same time.
  41. * The JFrame of that single instance can be accessed by the static field {code MainView.frame}.
  42. * @author kolja
  43. *
  44. */
  45. public class MainView {
  46. /**
  47. * The 'frame' of the main window.
  48. * The reason why there can only be one instance of this class.
  49. */
  50. private static int frameCounter = 0;
  51. private JFrame frame;
  52. private AnimationController controller;
  53. private JButton stepForward;
  54. private JButton stepForwardInto;
  55. private JButton stepForwardOut;
  56. private JButton stepBackward;
  57. private JButton stepBackwardInto;
  58. private JButton stepBackwardOut;
  59. private JButton runForward;
  60. private JButton runBackward;
  61. private JButton pause;
  62. private JButton load;
  63. private JButton save;
  64. private JButton debug;
  65. private JButton randomGraph;
  66. private JLabel delayText;
  67. private JTextField delay;
  68. public JTree pseudoTree;
  69. private LayeredGraphNode graph;
  70. private String strToLen( String s, int l )
  71. {
  72. while( s.length() < l )
  73. {
  74. s = " " + s + " ";
  75. }
  76. if( s.length() > l )
  77. return s.substring( 0, l );
  78. return s;
  79. }
  80. private String debugInfo()
  81. {
  82. String info = "Debug Information Table: \n";
  83. info += "_______________________________________________________________________________________________________________________________________________________________________________________________________________________\n";
  84. info += "|" + strToLen( "Top -> Bottom :> Left", 51 ) + "| |" + strToLen( "Top -> Bottom :> Right", 51 ) + "| |" + strToLen( "Bottom -> Top :> Left", 51 ) + "| |" + strToLen( "Bottom -> Top :> Right", 51 ) + "|\n";
  85. info += "|___________________________________________________| |___________________________________________________| |___________________________________________________| |___________________________________________________|\n";
  86. info += "| Node | Shift | Sink | Root | Align | x | xDef | | Node | Shift | Sink | Root | Align | x | xDef | | Node | Shift | Sink | Root | Align | x | xDef | | Node | Shift | Sink | Root | Align | x | xDef |\n";
  87. for( LayeredGraphNode n : graph.getContainedNodes() )
  88. {
  89. info += "|" + strToLen( n.getName(), 6 ) +
  90. "|" + strToLen( n.getShift( LayoutType.TOP_BOTTOM_LEFT ) + "", 7 ) +
  91. "|" + strToLen( n.getSink( LayoutType.TOP_BOTTOM_LEFT ).getName(), 6 ) +
  92. "|" + strToLen( n.getRoot( LayoutType.TOP_BOTTOM_LEFT ).getName(), 6 ) +
  93. "|" + strToLen( n.getAlignedTo( LayoutType.TOP_BOTTOM_LEFT ).getName(), 7 ) +
  94. "|" + strToLen( n.getX( LayoutType.TOP_BOTTOM_LEFT ) + "", 5 ) +
  95. "|" + strToLen( !n.isXUndefined( LayoutType.TOP_BOTTOM_LEFT ) + "", 8 ) + "| " +
  96. "|" + strToLen( n.getName(), 6 ) +
  97. "|" + strToLen( n.getShift( LayoutType.TOP_BOTTOM_RIGHT ) + "", 7 ) +
  98. "|" + strToLen( n.getSink( LayoutType.TOP_BOTTOM_RIGHT ).getName(), 6 ) +
  99. "|" + strToLen( n.getRoot( LayoutType.TOP_BOTTOM_RIGHT ).getName(), 6 ) +
  100. "|" + strToLen( n.getAlignedTo( LayoutType.TOP_BOTTOM_RIGHT ).getName(), 7 ) +
  101. "|" + strToLen( n.getX( LayoutType.TOP_BOTTOM_RIGHT ) + "", 5 ) +
  102. "|" + strToLen( !n.isXUndefined( LayoutType.TOP_BOTTOM_RIGHT ) + "", 8 ) + "| " +
  103. "|" + strToLen( n.getName(), 6 ) +
  104. "|" + strToLen( n.getShift( LayoutType.BOTTOM_TOP_LEFT ) + "", 7 ) +
  105. "|" + strToLen( n.getSink( LayoutType.BOTTOM_TOP_LEFT ).getName(), 6 ) +
  106. "|" + strToLen( n.getRoot( LayoutType.BOTTOM_TOP_LEFT ).getName(), 6 ) +
  107. "|" + strToLen( n.getAlignedTo( LayoutType.BOTTOM_TOP_LEFT ).getName(), 7 ) +
  108. "|" + strToLen( n.getX( LayoutType.BOTTOM_TOP_LEFT ) + "", 5 ) +
  109. "|" + strToLen( !n.isXUndefined( LayoutType.BOTTOM_TOP_LEFT ) + "", 8 ) + "| " +
  110. "|" + strToLen( n.getName(), 6 ) +
  111. "|" + strToLen( n.getShift( LayoutType.BOTTOM_TOP_RIGHT ) + "", 7 ) +
  112. "|" + strToLen( n.getSink( LayoutType.BOTTOM_TOP_RIGHT ).getName(), 6 ) +
  113. "|" + strToLen( n.getRoot( LayoutType.BOTTOM_TOP_RIGHT ).getName(), 6 ) +
  114. "|" + strToLen( n.getAlignedTo( LayoutType.BOTTOM_TOP_RIGHT ).getName(), 7 ) +
  115. "|" + strToLen( n.getX( LayoutType.BOTTOM_TOP_RIGHT ) + "", 5 ) +
  116. "|" + strToLen( !n.isXUndefined( LayoutType.BOTTOM_TOP_RIGHT ) + "", 8 ) + "|\n";
  117. }
  118. info += "-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------";
  119. return info;
  120. }
  121. private void showDebugInfo()
  122. {
  123. JFrame debugFrame = new JFrame();
  124. JTextArea info = new JTextArea();
  125. info.setEditable( false );
  126. info.setFont( new Font( Font.MONOSPACED, Font.PLAIN, 11 ) );
  127. info.setText( debugInfo() );
  128. JScrollPane view = new JScrollPane( info );
  129. debugFrame.add( view );
  130. debugFrame.setVisible( true );
  131. }
  132. /**
  133. * Initialize the window and its contents.
  134. * @param graph the graph that is displayed in this window.
  135. */
  136. public MainView( LayeredGraphNode graph )
  137. {
  138. frameCounter++;
  139. this.graph = graph;
  140. controller = new AnimationController();
  141. controller.setTimeBetween( 50 );
  142. frame = new JFrame();
  143. frame.addWindowListener(new java.awt.event.WindowAdapter() {
  144. @Override
  145. public void windowClosing(java.awt.event.WindowEvent windowEvent) {
  146. frameCounter--;
  147. if( frameCounter == 0 )
  148. System.exit( 0 );
  149. }
  150. });
  151. BKNodePlacement algorithm = new BKNodePlacement( controller, graph, frame );
  152. // Create Menu GUI
  153. stepForward = new NiceButton( "stepForward" );
  154. stepForward.setLocation( 10, 10 );
  155. stepForward.setMnemonic( KeyEvent.VK_DOWN );
  156. stepForward.addActionListener( new ActionListener() {
  157. @Override
  158. public void actionPerformed(ActionEvent e) {
  159. controller.setContinuous( false );
  160. controller.setNextAction( Action.FORWARD_OVER );
  161. }
  162. });
  163. stepForwardInto = new NiceButton( "stepForwardInto" );
  164. stepForwardInto.setLocation( 60, 10 );
  165. stepForwardInto.setMnemonic( KeyEvent.VK_RIGHT );
  166. stepForwardInto.addActionListener( new ActionListener() {
  167. @Override
  168. public void actionPerformed(ActionEvent e) {
  169. controller.setContinuous( false );
  170. controller.setNextAction( Action.FORWARD );
  171. }
  172. });
  173. stepForwardOut = new NiceButton( "stepForwardOut" );
  174. stepForwardOut.setLocation( 110, 10 );
  175. stepForwardOut.addActionListener( new ActionListener() {
  176. @Override
  177. public void actionPerformed(ActionEvent e) {
  178. controller.setContinuous( false );
  179. controller.setNextAction( Action.FORWARD_OUT );
  180. }
  181. });
  182. runForward = new NiceButton( "runForward" );
  183. runForward.setLocation( 160, 10 );
  184. runForward.setMnemonic( KeyEvent.VK_P );
  185. runForward.addActionListener( new ActionListener() {
  186. @Override
  187. public void actionPerformed(ActionEvent e) {
  188. controller.setContinuous( true );
  189. controller.setNextAction( Action.FORWARD );
  190. }
  191. });
  192. runBackward = new NiceButton( "runBackward" );
  193. runBackward.setLocation( 160, 60 );
  194. runBackward.setMnemonic( KeyEvent.VK_R );
  195. runBackward.addActionListener( new ActionListener() {
  196. @Override
  197. public void actionPerformed(ActionEvent e) {
  198. controller.setContinuous( true );
  199. controller.setNextAction( Action.BACKWARD );
  200. }
  201. });
  202. stepBackward = new NiceButton( "stepBackward" );
  203. stepBackward.setLocation( 10, 60 );
  204. stepBackward.setMnemonic( KeyEvent.VK_UP );
  205. stepBackward.addActionListener( new ActionListener() {
  206. @Override
  207. public void actionPerformed(ActionEvent e) {
  208. controller.setContinuous( false );
  209. controller.setNextAction( Action.BACKWARD_OVER );
  210. }
  211. });
  212. stepBackwardInto = new NiceButton( "stepBackwardInto" );
  213. stepBackwardInto.setLocation( 60, 60 );
  214. stepBackwardInto.setMnemonic( KeyEvent.VK_LEFT );
  215. stepBackwardInto.addActionListener( new ActionListener() {
  216. @Override
  217. public void actionPerformed(ActionEvent e) {
  218. controller.setContinuous( false );
  219. controller.setNextAction( Action.BACKWARD );
  220. }
  221. });
  222. stepBackwardOut = new NiceButton( "stepBackwardOut" );
  223. stepBackwardOut.setLocation( 110, 60 );
  224. stepBackwardOut.addActionListener( new ActionListener() {
  225. @Override
  226. public void actionPerformed(ActionEvent e) {
  227. controller.setContinuous( false );
  228. controller.setNextAction( Action.BACKWARD_OUT );
  229. }
  230. });
  231. pause = new NiceButton( "pause" );
  232. pause.setLocation( 210, 10 );
  233. pause.addActionListener( new ActionListener() {
  234. @Override
  235. public void actionPerformed(ActionEvent e) {
  236. controller.setContinuous( false );
  237. }
  238. });
  239. debug = new NiceButton( "debug" );
  240. debug.setLocation( 350, 10 );
  241. debug.setMnemonic( KeyEvent.VK_D );
  242. debug.addActionListener( new ActionListener() {
  243. @Override
  244. public void actionPerformed(ActionEvent e) {
  245. showDebugInfo();
  246. }
  247. });
  248. randomGraph = new NiceButton( "random" );
  249. randomGraph.setLocation( 350, 60 );
  250. randomGraph.addActionListener( new ActionListener() {
  251. @Override
  252. public void actionPerformed(ActionEvent e) {
  253. JDialog diag = new JDialog( frame, "Zufälligen Graph gennerieren" );
  254. diag.setLayout( new GridBagLayout() );
  255. GridBagConstraints c = new GridBagConstraints();
  256. c.gridx = 0;
  257. c.gridy = 0;
  258. diag.add( new JLabel( "P(Subgraph exists)="), c );
  259. c = new GridBagConstraints();
  260. c.gridx = 1;
  261. c.gridy = 0;
  262. JTextField pSubgraph = new JTextField( "0.1" );
  263. pSubgraph.setPreferredSize( new Dimension( 100, 20 ) );
  264. pSubgraph.addFocusListener( new FocusListener() {
  265. @Override
  266. public void focusGained(FocusEvent e) {
  267. pSubgraph.setBackground( Color.WHITE );
  268. }
  269. @Override
  270. public void focusLost(FocusEvent e) {
  271. try {
  272. double d = Double.parseDouble( pSubgraph.getText() );
  273. if( d > 1 || d < 0 )
  274. pSubgraph.setBackground( Color.RED );
  275. } catch( Exception e1 )
  276. {
  277. pSubgraph.setBackground( Color.RED );
  278. }
  279. }
  280. });
  281. diag.add( pSubgraph, c );
  282. c = new GridBagConstraints();
  283. c.gridx = 0;
  284. c.gridy = 1;
  285. diag.add( new JLabel( "P(Edge exists)="), c );
  286. c = new GridBagConstraints();
  287. c.gridx = 1;
  288. c.gridy = 1;
  289. JTextField pEdge = new JTextField( "0.3" );
  290. pEdge.setPreferredSize( new Dimension( 100, 20 ) );
  291. pEdge.addFocusListener( new FocusListener() {
  292. @Override
  293. public void focusGained(FocusEvent e) {
  294. pEdge.setBackground( Color.WHITE );
  295. }
  296. @Override
  297. public void focusLost(FocusEvent e) {
  298. try {
  299. double d = Double.parseDouble( pEdge.getText() );
  300. if( d > 1 || d < 0 )
  301. pEdge.setBackground( Color.RED );
  302. } catch( Exception e1 )
  303. {
  304. pEdge.setBackground( Color.RED );
  305. }
  306. }
  307. });
  308. diag.add( pEdge, c );
  309. c = new GridBagConstraints();
  310. c.gridx = 0;
  311. c.gridy = 2;
  312. diag.add( new JLabel( "Minimal Layers="), c );
  313. c = new GridBagConstraints();
  314. c.gridx = 1;
  315. c.gridy = 2;
  316. JTextField minLayers = new JTextField( "5" );
  317. JTextField maxLayers = new JTextField( "5" );
  318. minLayers.setPreferredSize( new Dimension( 100, 20 ) );
  319. minLayers.addFocusListener( new FocusListener() {
  320. @Override
  321. public void focusGained(FocusEvent e) {
  322. minLayers.setBackground( Color.WHITE );
  323. }
  324. @Override
  325. public void focusLost(FocusEvent e) {
  326. try {
  327. int i = Integer.parseInt( minLayers.getText() );
  328. int max = Integer.parseInt( maxLayers.getText() );
  329. if( i < 1 || i > max )
  330. minLayers.setBackground( Color.RED );
  331. else
  332. maxLayers.setBackground( Color.WHITE );
  333. } catch( Exception e1 )
  334. {
  335. minLayers.setBackground( Color.RED );
  336. }
  337. }
  338. });
  339. diag.add( minLayers, c );
  340. c = new GridBagConstraints();
  341. c.gridx = 0;
  342. c.gridy = 3;
  343. diag.add( new JLabel( "Maximal Layers="), c );
  344. c = new GridBagConstraints();
  345. c.gridx = 1;
  346. c.gridy = 3;
  347. maxLayers.setPreferredSize( new Dimension( 100, 20 ) );
  348. maxLayers.addFocusListener( new FocusListener() {
  349. @Override
  350. public void focusGained(FocusEvent e) {
  351. maxLayers.setBackground( Color.WHITE );
  352. }
  353. @Override
  354. public void focusLost(FocusEvent e) {
  355. try {
  356. int i = Integer.parseInt( maxLayers.getText() );
  357. int min = Integer.parseInt( minLayers.getText() );
  358. if( i < min )
  359. maxLayers.setBackground( Color.RED );
  360. else if( min > 0 )
  361. minLayers.setBackground( Color.WHITE );
  362. } catch( Exception e1 )
  363. {
  364. maxLayers.setBackground( Color.RED );
  365. }
  366. }
  367. });
  368. diag.add( maxLayers, c );
  369. c = new GridBagConstraints();
  370. c.gridx = 0;
  371. c.gridy = 4;
  372. diag.add( new JLabel( "Minimal Nodes="), c );
  373. c = new GridBagConstraints();
  374. c.gridx = 1;
  375. c.gridy = 4;
  376. JTextField minNodes = new JTextField( "5" );
  377. JTextField maxNodes = new JTextField( "5" );
  378. minNodes.setPreferredSize( new Dimension( 100, 20 ) );
  379. minNodes.setToolTipText( "Zwischen 1 und 'Maximal Nodes'" );
  380. minNodes.addFocusListener( new FocusListener() {
  381. @Override
  382. public void focusGained(FocusEvent e) {
  383. minNodes.setBackground( Color.WHITE );
  384. }
  385. @Override
  386. public void focusLost(FocusEvent e) {
  387. try {
  388. int i = Integer.parseInt( minNodes.getText() );
  389. int max = Integer.parseInt( maxNodes.getText() );
  390. if( i < 1 || i > max )
  391. minNodes.setBackground( Color.RED );
  392. else
  393. minNodes.setBackground( Color.WHITE );
  394. } catch( Exception e1 )
  395. {
  396. minNodes.setBackground( Color.RED );
  397. }
  398. }
  399. });
  400. diag.add( minNodes, c );
  401. c = new GridBagConstraints();
  402. c.gridx = 0;
  403. c.gridy = 5;
  404. diag.add( new JLabel( "Maximal Nodes="), c );
  405. c = new GridBagConstraints();
  406. c.gridx = 1;
  407. c.gridy = 5;
  408. maxNodes.setPreferredSize( new Dimension( 100, 20 ) );
  409. maxNodes.setToolTipText( "Zwischen 'Minimal Nodes' und unendlich" );
  410. maxNodes.addFocusListener( new FocusListener() {
  411. @Override
  412. public void focusGained(FocusEvent e) {
  413. maxNodes.setBackground( Color.WHITE );
  414. }
  415. @Override
  416. public void focusLost(FocusEvent e) {
  417. try {
  418. int i = Integer.parseInt( maxNodes.getText() );
  419. int min = Integer.parseInt( minNodes.getText() );
  420. if( i < min )
  421. maxNodes.setBackground( Color.RED );
  422. else if( min > 0 )
  423. minNodes.setBackground( Color.WHITE );
  424. } catch( Exception e1 )
  425. {
  426. maxNodes.setBackground( Color.RED );
  427. }
  428. }
  429. });
  430. diag.add( maxNodes, c );
  431. c = new GridBagConstraints();
  432. c.gridx = 0;
  433. c.gridy = 6;
  434. diag.add( new JLabel( "Maximal depth="), c );
  435. c = new GridBagConstraints();
  436. c.gridx = 1;
  437. c.gridy = 6;
  438. JTextField maxDepth = new JTextField( "1" );
  439. maxDepth.setPreferredSize( new Dimension( 100, 20 ) );
  440. maxDepth.setToolTipText( "Zwischen 1 und unendlich" );
  441. maxDepth.addFocusListener( new FocusListener() {
  442. @Override
  443. public void focusGained(FocusEvent e) {
  444. maxDepth.setBackground( Color.WHITE );
  445. }
  446. @Override
  447. public void focusLost(FocusEvent e) {
  448. try {
  449. int i = Integer.parseInt( maxDepth.getText() );
  450. if( i < 1 )
  451. maxDepth.setBackground( Color.RED );
  452. } catch( Exception e1 )
  453. {
  454. maxDepth.setBackground( Color.RED );
  455. }
  456. }
  457. });
  458. diag.add( maxDepth, c );
  459. c = new GridBagConstraints();
  460. c.gridx = 0;
  461. c.gridy = 7;
  462. c.gridwidth = 2;
  463. JButton gen = new JButton( "generate");
  464. gen.addActionListener( new ActionListener() {
  465. @Override
  466. public void actionPerformed(ActionEvent e) {
  467. double pSubGraphD = Double.parseDouble( pSubgraph.getText() );
  468. double pEdgeD = Double.parseDouble( pEdge.getText() );
  469. int minLayerI = Integer.parseInt( minLayers.getText() );
  470. int maxLayerI = Integer.parseInt( maxLayers.getText() );
  471. int minNodeI = Integer.parseInt( minNodes.getText() );
  472. int maxNodeI = Integer.parseInt( maxNodes.getText() );
  473. int maxDepthI = Integer.parseInt( maxDepth.getText() );
  474. boolean ok = true;
  475. if( pSubGraphD < 0 || pSubGraphD > 1 )
  476. {
  477. pSubgraph.setBackground( Color.RED );
  478. ok = false;
  479. }
  480. if( pEdgeD < 0 || pEdgeD > 1 )
  481. {
  482. pEdge.setBackground( Color.RED );
  483. ok = false;
  484. }
  485. if( minLayerI < 1 )
  486. {
  487. minLayers.setBackground( Color.RED );
  488. ok = false;
  489. }
  490. if( maxLayerI < minLayerI )
  491. {
  492. maxLayers.setBackground( Color.RED );
  493. ok = false;
  494. }
  495. if( minNodeI < 1 )
  496. {
  497. minNodes.setBackground( Color.RED );
  498. ok = false;
  499. }
  500. if( maxNodeI < minNodeI )
  501. {
  502. maxNodes.setBackground( Color.RED );
  503. ok = false;
  504. }
  505. if( maxDepthI < 1 )
  506. {
  507. maxDepth.setBackground( Color.RED );
  508. ok = false;
  509. }
  510. if( ok )
  511. {
  512. RandomGraphGenerator r = new RandomGraphGenerator( pSubGraphD, pEdgeD, minLayerI, maxLayerI, minNodeI, maxNodeI, maxDepthI );
  513. LayeredGraphNode graph = r.createRandomNode( null, 0 );
  514. SweepCrossingMinimizer cminzer = new SweepCrossingMinimizer();
  515. for( int i = 0; i < 10; i++ )
  516. cminzer.minimizeCrossings( graph );
  517. InitializeNodePositions.placeNodes( graph );
  518. new MainView( graph );
  519. diag.setVisible( false );
  520. }
  521. }
  522. });
  523. diag.add( gen, c );
  524. diag.setSize( 270, 220 );
  525. diag.setLocation( frame.getX() + frame.getWidth() / 2 - diag.getWidth() / 2, frame.getY() + frame.getHeight() / 2 - diag.getHeight() / 2 );
  526. diag.setVisible( true );
  527. }
  528. });
  529. delayText = new JLabel( "Delay (ms)" );
  530. delayText.setBounds( 260, 10, 80, 20 );
  531. delay = new JTextField( "50" );
  532. delay.setBounds( 260, 30, 80, 20 );
  533. delay.getDocument().addDocumentListener( new DocumentListener() {
  534. @Override
  535. public void insertUpdate(DocumentEvent e) {
  536. try
  537. {
  538. controller.setTimeBetween( Integer.parseInt( delay.getText() ) );
  539. delay.setBackground( Color.WHITE );
  540. } catch( Exception e1 )
  541. {
  542. delay.setBackground( Color.RED );
  543. }
  544. }
  545. @Override
  546. public void removeUpdate(DocumentEvent e) {
  547. try
  548. {
  549. controller.setTimeBetween( Integer.parseInt( delay.getText() ) );
  550. delay.setBackground( Color.WHITE );
  551. } catch( Exception e1 )
  552. {
  553. delay.setBackground( Color.RED );
  554. }
  555. }
  556. @Override
  557. public void changedUpdate(DocumentEvent e) {
  558. try
  559. {
  560. controller.setTimeBetween( Integer.parseInt( delay.getText() ) );
  561. delay.setBackground( Color.WHITE );
  562. } catch( Exception e1 )
  563. {
  564. delay.setBackground( Color.RED );
  565. }
  566. }
  567. });
  568. load = new NiceButton( "load" );
  569. load.setLocation( 230, 60 );
  570. load.addActionListener( new ActionListener() {
  571. @Override
  572. public void actionPerformed(ActionEvent e) {
  573. }
  574. });
  575. save = new NiceButton( "save" );
  576. save.setLocation( 285, 60 );
  577. save.addActionListener( new ActionListener() {
  578. @Override
  579. public void actionPerformed(ActionEvent e) {
  580. }
  581. });
  582. pseudoTree = new JTree();
  583. pseudoTree.setModel( new DefaultTreeModel( algorithm.createPseudocodeTree( pseudoTree ) ) );
  584. pseudoTree.setCellRenderer( new PseudoCodeRenderer() );
  585. pseudoTree.setSelectionModel( null );
  586. JScrollPane treeView = new JScrollPane( pseudoTree );
  587. treeView.setBounds( 10, 110, 380, 380 );
  588. frame.setSize( Math.min( (int)graph.getWidth( LayoutType.TOP_BOTTOM_LEFT ) * 2 + 200, 1700 ), Math.min( (int)graph.getHeight( LayoutType.TOP_BOTTOM_LEFT ) * 2 + 200, 900 ) );
  589. frame.setLocation( 100, 100 );
  590. frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
  591. frame.setVisible( true );
  592. JLayeredPane layne = new JLayeredPane();
  593. JPanel pl = new JPanel();
  594. GridLayout grout = new GridLayout( 2, 2, 10, 10 );
  595. pl.setLayout( grout );
  596. pl.setLocation( 0, 0 );
  597. pl.setSize( frame.getSize() );
  598. NodeView topLeft = createNodeView( graph, LayoutType.TOP_BOTTOM_LEFT );
  599. NodeView topRight = createNodeView( graph, LayoutType.TOP_BOTTOM_RIGHT );
  600. NodeView bottomLeft = createNodeView( graph, LayoutType.BOTTOM_TOP_LEFT );
  601. NodeView bottomRight = createNodeView( graph, LayoutType.BOTTOM_TOP_RIGHT );
  602. pl.add( topLeft );
  603. pl.add( topRight );
  604. pl.add( bottomLeft );
  605. pl.add( bottomRight );
  606. layne.add( pl, 1 );
  607. NodeView combined = createNodeView( graph, LayoutType.COMBINED );
  608. combined.setSize( 500, 500 );
  609. layne.add( combined, 0 );
  610. frame.add( layne );
  611. JPanel menue = new JPanel();
  612. menue.setLayout( null );
  613. menue.setPreferredSize( new Dimension( 400, 500 ) );
  614. menue.add( stepForward );
  615. menue.add( stepForwardInto );
  616. menue.add( stepForwardOut );
  617. menue.add( runForward );
  618. menue.add( pause );
  619. menue.add( debug );
  620. menue.add( stepBackward );
  621. menue.add( delayText );
  622. menue.add( delay );
  623. menue.add( treeView );
  624. menue.add( stepBackwardInto );
  625. menue.add( stepBackwardOut );
  626. menue.add( runBackward );
  627. menue.add( randomGraph );
  628. menue.add( save );
  629. menue.add( load );
  630. frame.add( menue, BorderLayout.EAST );
  631. frame.setSize( frame.getWidth() + 1, frame.getHeight() );
  632. frame.setSize( frame.getWidth() - 1, frame.getHeight() );
  633. frame.validate();
  634. frame.repaint();
  635. frame.addComponentListener(new ComponentAdapter()
  636. {
  637. public void componentResized(ComponentEvent evt) {
  638. pl.setSize( layne.getSize() );
  639. menue.setSize( menue.getWidth(), layne.getHeight() );
  640. treeView.setSize( treeView.getWidth(), layne.getHeight() - 120 );
  641. if( graph.getColor( LayoutType.COMBINED ) == null )
  642. {
  643. grout.setHgap( 10 );
  644. grout.setVgap( 10 );
  645. }
  646. else
  647. {
  648. grout.setHgap( layne.getWidth() / 3 );
  649. grout.setVgap( layne.getHeight() / 3 );
  650. }
  651. combined.setSize( layne.getWidth() / 3, layne.getHeight() / 3 );
  652. combined.setLocation( layne.getWidth() / 3, layne.getHeight() / 3 );
  653. layne.remove( pl );
  654. layne.add( pl, 1 );
  655. frame.repaint();
  656. }
  657. });
  658. algorithm.start();
  659. }
  660. private NodeView createNodeView( LayeredGraphNode gNode, LayoutType lt )
  661. {
  662. NodeView graphView = new NodeView( gNode, lt );
  663. graphView.setLayout( null );
  664. graphView.setOpaque( true );
  665. for( LayeredGraphNode n : gNode.getContainedNodes() )
  666. {
  667. NodeView nv = createNodeView( n, lt );
  668. nv.setBounds( nv.getX(), nv.getY(), nv.getWidth(), nv.getHeight() );
  669. graphView.add( nv );
  670. }
  671. for( LayeredGraphEdge e : gNode.getContainedEdges() )
  672. {
  673. EdgeView ev = new EdgeView( e, lt );
  674. ev.setOpaque( true );
  675. graphView.add( ev );
  676. }
  677. return graphView;
  678. }
  679. }