MainView.java 34 KB

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