MainView.java 31 KB

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