MainView.java 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776
  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.setSize( frame.getWidth(), frame.getHeight() );
  135. debugFrame.setVisible( true );
  136. }
  137. /**
  138. * Initialize the window and its contents.
  139. * @param graph the graph that is displayed in this window.
  140. */
  141. public MainView( LayeredGraphNode graph )
  142. {
  143. frameCounter++;
  144. this.graph = graph;
  145. controller = new AnimationController();
  146. controller.setTimeBetween( 50 );
  147. frame = new JFrame();
  148. frame.addWindowListener(new java.awt.event.WindowAdapter() {
  149. @Override
  150. public void windowClosing(java.awt.event.WindowEvent windowEvent) {
  151. frameCounter--;
  152. if( frameCounter == 0 )
  153. System.exit( 0 );
  154. }
  155. });
  156. BKNodePlacement algorithm = new BKNodePlacement( controller, graph, frame );
  157. // Create Menu GUI
  158. stepForward = new NiceButton( "stepForward" );
  159. stepForward.setLocation( 10, 10 );
  160. stepForward.setMnemonic( KeyEvent.VK_DOWN );
  161. stepForward.setToolTipText( "Forward step over (alt+down arrow key)" );
  162. stepForward.addActionListener( new ActionListener() {
  163. @Override
  164. public void actionPerformed(ActionEvent e) {
  165. controller.setContinuous( false );
  166. controller.setNextAction( Action.FORWARD_OVER );
  167. }
  168. });
  169. stepForwardInto = new NiceButton( "stepForwardInto" );
  170. stepForwardInto.setLocation( 60, 10 );
  171. stepForwardInto.setMnemonic( KeyEvent.VK_RIGHT );
  172. stepForwardInto.setToolTipText( "Forward step Into (alt+right arrow key)" );
  173. stepForwardInto.addActionListener( new ActionListener() {
  174. @Override
  175. public void actionPerformed(ActionEvent e) {
  176. controller.setContinuous( false );
  177. controller.setNextAction( Action.FORWARD );
  178. }
  179. });
  180. stepForwardOut = new NiceButton( "stepForwardOut" );
  181. stepForwardOut.setLocation( 110, 10 );
  182. stepForwardOut.setMnemonic( KeyEvent.VK_PAGE_DOWN );
  183. stepForwardOut.setToolTipText( "Forward step out (alt+page down key)" );
  184. stepForwardOut.addActionListener( new ActionListener() {
  185. @Override
  186. public void actionPerformed(ActionEvent e) {
  187. controller.setContinuous( false );
  188. controller.setNextAction( Action.FORWARD_OUT );
  189. }
  190. });
  191. runForward = new NiceButton( "runForward" );
  192. runForward.setLocation( 160, 10 );
  193. runForward.setMnemonic( KeyEvent.VK_P );
  194. runForward.setToolTipText( "Run forward annimation (alt+p)" );
  195. runForward.addActionListener( new ActionListener() {
  196. @Override
  197. public void actionPerformed(ActionEvent e) {
  198. controller.setContinuous( true );
  199. controller.setNextAction( Action.FORWARD );
  200. }
  201. });
  202. runBackward = new NiceButton( "runBackward" );
  203. runBackward.setLocation( 160, 60 );
  204. runBackward.setMnemonic( KeyEvent.VK_R );
  205. runBackward.setToolTipText( "Run backward annimation (alt+r)" );
  206. runBackward.addActionListener( new ActionListener() {
  207. @Override
  208. public void actionPerformed(ActionEvent e) {
  209. controller.setContinuous( true );
  210. controller.setNextAction( Action.BACKWARD );
  211. }
  212. });
  213. stepBackward = new NiceButton( "stepBackward" );
  214. stepBackward.setLocation( 10, 60 );
  215. stepBackward.setMnemonic( KeyEvent.VK_UP );
  216. stepBackward.setToolTipText( "Backward step over (alt+up arrow key)" );
  217. stepBackward.addActionListener( new ActionListener() {
  218. @Override
  219. public void actionPerformed(ActionEvent e) {
  220. controller.setContinuous( false );
  221. controller.setNextAction( Action.BACKWARD_OVER );
  222. }
  223. });
  224. stepBackwardInto = new NiceButton( "stepBackwardInto" );
  225. stepBackwardInto.setLocation( 60, 60 );
  226. stepBackwardInto.setMnemonic( KeyEvent.VK_LEFT );
  227. stepBackwardInto.setToolTipText( "Backward step into (alt+left arrow key)" );
  228. stepBackwardInto.addActionListener( new ActionListener() {
  229. @Override
  230. public void actionPerformed(ActionEvent e) {
  231. controller.setContinuous( false );
  232. controller.setNextAction( Action.BACKWARD );
  233. }
  234. });
  235. stepBackwardOut = new NiceButton( "stepBackwardOut" );
  236. stepBackwardOut.setLocation( 110, 60 );
  237. stepBackwardOut.setMnemonic( KeyEvent.VK_PAGE_UP );
  238. stepBackwardOut.setToolTipText( "Backward step out (alt+page up key)" );
  239. stepBackwardOut.addActionListener( new ActionListener() {
  240. @Override
  241. public void actionPerformed(ActionEvent e) {
  242. controller.setContinuous( false );
  243. controller.setNextAction( Action.BACKWARD_OUT );
  244. }
  245. });
  246. pause = new NiceButton( "pause" );
  247. pause.setLocation( 210, 10 );
  248. pause.setMnemonic( KeyEvent.VK_PAUSE );
  249. pause.setToolTipText( "Animation stop (alt+pause key)" );
  250. pause.addActionListener( new ActionListener() {
  251. @Override
  252. public void actionPerformed(ActionEvent e) {
  253. controller.setContinuous( false );
  254. }
  255. });
  256. debug = new NiceButton( "debug" );
  257. debug.setLocation( 350, 10 );
  258. debug.setMnemonic( KeyEvent.VK_D );
  259. debug.setToolTipText( "Show debug info (alt+d)" );
  260. debug.addActionListener( new ActionListener() {
  261. @Override
  262. public void actionPerformed(ActionEvent e) {
  263. showDebugInfo();
  264. }
  265. });
  266. randomGraph = new NiceButton( "random" );
  267. randomGraph.setLocation( 350, 60 );
  268. randomGraph.setMnemonic( KeyEvent.VK_G );
  269. randomGraph.setToolTipText( "Generate random graph (alt+g)" );
  270. randomGraph.addActionListener( new ActionListener() {
  271. @Override
  272. public void actionPerformed(ActionEvent e) {
  273. JDialog diag = new JDialog( frame, "Zufälligen Graph gennerieren" );
  274. diag.setLayout( new GridBagLayout() );
  275. GridBagConstraints c = new GridBagConstraints();
  276. c.gridx = 0;
  277. c.gridy = 0;
  278. diag.add( new JLabel( "P(subgraph exists)"), c );
  279. c = new GridBagConstraints();
  280. c.gridx = 1;
  281. c.gridy = 0;
  282. JTextField pSubgraph = new JTextField( "0.1" );
  283. pSubgraph.setPreferredSize( new Dimension( 100, 20 ) );
  284. pSubgraph.addFocusListener( new FocusListener() {
  285. @Override
  286. public void focusGained(FocusEvent e) {
  287. pSubgraph.setBackground( Color.WHITE );
  288. }
  289. @Override
  290. public void focusLost(FocusEvent e) {
  291. try {
  292. double d = Double.parseDouble( pSubgraph.getText() );
  293. if( d > 1 || d < 0 )
  294. pSubgraph.setBackground( Color.RED );
  295. } catch( Exception e1 )
  296. {
  297. pSubgraph.setBackground( Color.RED );
  298. }
  299. }
  300. });
  301. diag.add( pSubgraph, c );
  302. c = new GridBagConstraints();
  303. c.gridx = 0;
  304. c.gridy = 1;
  305. diag.add( new JLabel( "P(edge exists)"), c );
  306. c = new GridBagConstraints();
  307. c.gridx = 1;
  308. c.gridy = 1;
  309. JTextField pEdge = new JTextField( "0.3" );
  310. pEdge.setPreferredSize( new Dimension( 100, 20 ) );
  311. pEdge.addFocusListener( new FocusListener() {
  312. @Override
  313. public void focusGained(FocusEvent e) {
  314. pEdge.setBackground( Color.WHITE );
  315. }
  316. @Override
  317. public void focusLost(FocusEvent e) {
  318. try {
  319. double d = Double.parseDouble( pEdge.getText() );
  320. if( d > 1 || d < 0 )
  321. pEdge.setBackground( Color.RED );
  322. } catch( Exception e1 )
  323. {
  324. pEdge.setBackground( Color.RED );
  325. }
  326. }
  327. });
  328. diag.add( pEdge, c );
  329. c = new GridBagConstraints();
  330. c.gridx = 0;
  331. c.gridy = 2;
  332. diag.add( new JLabel( "min. num. layers"), c );
  333. c = new GridBagConstraints();
  334. c.gridx = 1;
  335. c.gridy = 2;
  336. JTextField minLayers = new JTextField( "5" );
  337. JTextField maxLayers = new JTextField( "5" );
  338. minLayers.setPreferredSize( new Dimension( 100, 20 ) );
  339. minLayers.addFocusListener( new FocusListener() {
  340. @Override
  341. public void focusGained(FocusEvent e) {
  342. minLayers.setBackground( Color.WHITE );
  343. }
  344. @Override
  345. public void focusLost(FocusEvent e) {
  346. try {
  347. int i = Integer.parseInt( minLayers.getText() );
  348. int max = Integer.parseInt( maxLayers.getText() );
  349. if( i < 1 || i > max )
  350. minLayers.setBackground( Color.RED );
  351. else
  352. maxLayers.setBackground( Color.WHITE );
  353. } catch( Exception e1 )
  354. {
  355. minLayers.setBackground( Color.RED );
  356. }
  357. }
  358. });
  359. diag.add( minLayers, c );
  360. c = new GridBagConstraints();
  361. c.gridx = 0;
  362. c.gridy = 3;
  363. diag.add( new JLabel( "max. num. layers"), c );
  364. c = new GridBagConstraints();
  365. c.gridx = 1;
  366. c.gridy = 3;
  367. maxLayers.setPreferredSize( new Dimension( 100, 20 ) );
  368. maxLayers.addFocusListener( new FocusListener() {
  369. @Override
  370. public void focusGained(FocusEvent e) {
  371. maxLayers.setBackground( Color.WHITE );
  372. }
  373. @Override
  374. public void focusLost(FocusEvent e) {
  375. try {
  376. int i = Integer.parseInt( maxLayers.getText() );
  377. int min = Integer.parseInt( minLayers.getText() );
  378. if( i < min )
  379. maxLayers.setBackground( Color.RED );
  380. else if( min > 0 )
  381. minLayers.setBackground( Color.WHITE );
  382. } catch( Exception e1 )
  383. {
  384. maxLayers.setBackground( Color.RED );
  385. }
  386. }
  387. });
  388. diag.add( maxLayers, c );
  389. c = new GridBagConstraints();
  390. c.gridx = 0;
  391. c.gridy = 4;
  392. diag.add( new JLabel( "min. num. nodes"), c );
  393. c = new GridBagConstraints();
  394. c.gridx = 1;
  395. c.gridy = 4;
  396. JTextField minNodes = new JTextField( "5" );
  397. JTextField maxNodes = new JTextField( "5" );
  398. minNodes.setPreferredSize( new Dimension( 100, 20 ) );
  399. minNodes.setToolTipText( "between 1 and 'min. num. nodes'" );
  400. minNodes.addFocusListener( new FocusListener() {
  401. @Override
  402. public void focusGained(FocusEvent e) {
  403. minNodes.setBackground( Color.WHITE );
  404. }
  405. @Override
  406. public void focusLost(FocusEvent e) {
  407. try {
  408. int i = Integer.parseInt( minNodes.getText() );
  409. int max = Integer.parseInt( maxNodes.getText() );
  410. if( i < 1 || i > max )
  411. minNodes.setBackground( Color.RED );
  412. else
  413. minNodes.setBackground( Color.WHITE );
  414. } catch( Exception e1 )
  415. {
  416. minNodes.setBackground( Color.RED );
  417. }
  418. }
  419. });
  420. diag.add( minNodes, c );
  421. c = new GridBagConstraints();
  422. c.gridx = 0;
  423. c.gridy = 5;
  424. diag.add( new JLabel( "max. num. nodes"), c );
  425. c = new GridBagConstraints();
  426. c.gridx = 1;
  427. c.gridy = 5;
  428. maxNodes.setPreferredSize( new Dimension( 100, 20 ) );
  429. maxNodes.setToolTipText( "between 'min. num. nodes' and +Inf" );
  430. maxNodes.addFocusListener( new FocusListener() {
  431. @Override
  432. public void focusGained(FocusEvent e) {
  433. maxNodes.setBackground( Color.WHITE );
  434. }
  435. @Override
  436. public void focusLost(FocusEvent e) {
  437. try {
  438. int i = Integer.parseInt( maxNodes.getText() );
  439. int min = Integer.parseInt( minNodes.getText() );
  440. if( i < min )
  441. maxNodes.setBackground( Color.RED );
  442. else if( min > 0 )
  443. minNodes.setBackground( Color.WHITE );
  444. } catch( Exception e1 )
  445. {
  446. maxNodes.setBackground( Color.RED );
  447. }
  448. }
  449. });
  450. diag.add( maxNodes, c );
  451. c = new GridBagConstraints();
  452. c.gridx = 0;
  453. c.gridy = 6;
  454. diag.add( new JLabel( "max. hier. depth"), c );
  455. c = new GridBagConstraints();
  456. c.gridx = 1;
  457. c.gridy = 6;
  458. JTextField maxDepth = new JTextField( "1" );
  459. maxDepth.setPreferredSize( new Dimension( 100, 20 ) );
  460. maxDepth.setToolTipText( "between 1 and +Inf" );
  461. maxDepth.addFocusListener( new FocusListener() {
  462. @Override
  463. public void focusGained(FocusEvent e) {
  464. maxDepth.setBackground( Color.WHITE );
  465. }
  466. @Override
  467. public void focusLost(FocusEvent e) {
  468. try {
  469. int i = Integer.parseInt( maxDepth.getText() );
  470. if( i < 1 )
  471. maxDepth.setBackground( Color.RED );
  472. } catch( Exception e1 )
  473. {
  474. maxDepth.setBackground( Color.RED );
  475. }
  476. }
  477. });
  478. diag.add( maxDepth, c );
  479. c = new GridBagConstraints();
  480. c.gridx = 0;
  481. c.gridy = 7;
  482. c.gridwidth = 2;
  483. JButton gen = new JButton( "generate");
  484. gen.addActionListener( new ActionListener() {
  485. @Override
  486. public void actionPerformed(ActionEvent e) {
  487. double pSubGraphD = Double.parseDouble( pSubgraph.getText() );
  488. double pEdgeD = Double.parseDouble( pEdge.getText() );
  489. int minLayerI = Integer.parseInt( minLayers.getText() );
  490. int maxLayerI = Integer.parseInt( maxLayers.getText() );
  491. int minNodeI = Integer.parseInt( minNodes.getText() );
  492. int maxNodeI = Integer.parseInt( maxNodes.getText() );
  493. int maxDepthI = Integer.parseInt( maxDepth.getText() );
  494. boolean ok = true;
  495. if( pSubGraphD < 0 || pSubGraphD > 1 )
  496. {
  497. pSubgraph.setBackground( Color.RED );
  498. ok = false;
  499. }
  500. if( pEdgeD < 0 || pEdgeD > 1 )
  501. {
  502. pEdge.setBackground( Color.RED );
  503. ok = false;
  504. }
  505. if( minLayerI < 1 )
  506. {
  507. minLayers.setBackground( Color.RED );
  508. ok = false;
  509. }
  510. if( maxLayerI < minLayerI )
  511. {
  512. maxLayers.setBackground( Color.RED );
  513. ok = false;
  514. }
  515. if( minNodeI < 1 )
  516. {
  517. minNodes.setBackground( Color.RED );
  518. ok = false;
  519. }
  520. if( maxNodeI < minNodeI )
  521. {
  522. maxNodes.setBackground( Color.RED );
  523. ok = false;
  524. }
  525. if( maxDepthI < 1 )
  526. {
  527. maxDepth.setBackground( Color.RED );
  528. ok = false;
  529. }
  530. if( ok )
  531. {
  532. RandomGraphGenerator r = new RandomGraphGenerator( pSubGraphD, pEdgeD, minLayerI, maxLayerI, minNodeI, maxNodeI, maxDepthI );
  533. LayeredGraphNode graph = r.createRandomNode( null, 0 );
  534. SweepCrossingMinimizer cminzer = new SweepCrossingMinimizer();
  535. for( int i = 0; i < 10; i++ )
  536. cminzer.minimizeCrossings( graph );
  537. InitializeNodePositions.placeNodes( graph );
  538. new MainView( graph );
  539. diag.setVisible( false );
  540. }
  541. }
  542. });
  543. diag.add( gen, c );
  544. diag.setSize( 270, 220 );
  545. diag.setLocation( frame.getX() + frame.getWidth() / 2 - diag.getWidth() / 2, frame.getY() + frame.getHeight() / 2 - diag.getHeight() / 2 );
  546. diag.setVisible( true );
  547. }
  548. });
  549. delayText = new JLabel( "Delay (ms)" );
  550. delayText.setBounds( 260, 10, 80, 20 );
  551. delay = new JTextField( "50" );
  552. delay.setBounds( 260, 30, 80, 20 );
  553. delay.getDocument().addDocumentListener( new DocumentListener() {
  554. @Override
  555. public void insertUpdate(DocumentEvent e) {
  556. try
  557. {
  558. controller.setTimeBetween( Integer.parseInt( delay.getText() ) );
  559. delay.setBackground( Color.WHITE );
  560. } catch( Exception e1 )
  561. {
  562. delay.setBackground( Color.RED );
  563. }
  564. }
  565. @Override
  566. public void removeUpdate(DocumentEvent e) {
  567. try
  568. {
  569. controller.setTimeBetween( Integer.parseInt( delay.getText() ) );
  570. delay.setBackground( Color.WHITE );
  571. } catch( Exception e1 )
  572. {
  573. delay.setBackground( Color.RED );
  574. }
  575. }
  576. @Override
  577. public void changedUpdate(DocumentEvent e) {
  578. try
  579. {
  580. controller.setTimeBetween( Integer.parseInt( delay.getText() ) );
  581. delay.setBackground( Color.WHITE );
  582. } catch( Exception e1 )
  583. {
  584. delay.setBackground( Color.RED );
  585. }
  586. }
  587. });
  588. load = new NiceButton( "load" );
  589. load.setLocation( 230, 60 );
  590. load.setMnemonic( KeyEvent.VK_L );
  591. load.setToolTipText( "Load a graph (alt+l)" );
  592. load.addActionListener( new ActionListener() {
  593. @Override
  594. public void actionPerformed(ActionEvent e) {
  595. JFileChooser chooser = new JFileChooser();
  596. chooser.setFileFilter( new FileNameExtensionFilter("Json Graph", "json") );
  597. chooser.showOpenDialog( frame );
  598. if( chooser.getSelectedFile() != null )
  599. {
  600. Reader r = new Reader( chooser.getSelectedFile().getAbsolutePath() );
  601. LayeredGraphNode graph = r.readInputGraph();
  602. InitializeNodePositions.placeNodes( graph );
  603. new MainView( graph );
  604. }
  605. }
  606. });
  607. save = new NiceButton( "save" );
  608. save.setLocation( 285, 60 );
  609. save.setMnemonic( KeyEvent.VK_S );
  610. save.setToolTipText( "Save graph (alt+s)" );
  611. save.addActionListener( new ActionListener() {
  612. @Override
  613. public void actionPerformed(ActionEvent e) {
  614. JFileChooser chooser = new JFileChooser();
  615. chooser.setFileFilter( new FileNameExtensionFilter("Json Graph", "json") );
  616. chooser.showSaveDialog( frame );
  617. if( chooser.getSelectedFile() != null )
  618. {
  619. Writer w = new Writer( chooser.getSelectedFile().getAbsolutePath() );
  620. w.writeOutputGraph( graph );
  621. }
  622. }
  623. });
  624. pseudoTree = new JTree();
  625. pseudoTree.setModel( new DefaultTreeModel( algorithm.createPseudocodeTree( pseudoTree ) ) );
  626. pseudoTree.setCellRenderer( new PseudoCodeRenderer() );
  627. pseudoTree.setSelectionModel( null );
  628. JScrollPane treeView = new JScrollPane( pseudoTree );
  629. treeView.setBounds( 10, 110, 380, 380 );
  630. 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 ) );
  631. frame.setLocation( 100, 100 );
  632. frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
  633. frame.setVisible( true );
  634. JLayeredPane layne = new JLayeredPane();
  635. JPanel pl = new JPanel();
  636. GridLayout grout = new GridLayout( 2, 2, 10, 10 );
  637. pl.setLayout( grout );
  638. pl.setLocation( 0, 0 );
  639. pl.setSize( frame.getSize() );
  640. NodeView topLeft = createNodeView( graph, LayoutType.TOP_BOTTOM_LEFT );
  641. NodeView topRight = createNodeView( graph, LayoutType.TOP_BOTTOM_RIGHT );
  642. NodeView bottomLeft = createNodeView( graph, LayoutType.BOTTOM_TOP_LEFT );
  643. NodeView bottomRight = createNodeView( graph, LayoutType.BOTTOM_TOP_RIGHT );
  644. pl.add( topLeft );
  645. pl.add( topRight );
  646. pl.add( bottomLeft );
  647. pl.add( bottomRight );
  648. layne.add( pl, 1 );
  649. NodeView combined = createNodeView( graph, LayoutType.COMBINED );
  650. combined.setSize( 500, 500 );
  651. layne.add( combined, 0 );
  652. frame.add( layne );
  653. JPanel menue = new JPanel();
  654. menue.setLayout( null );
  655. menue.setPreferredSize( new Dimension( 400, 500 ) );
  656. menue.add( stepForward );
  657. menue.add( stepForwardInto );
  658. menue.add( stepForwardOut );
  659. menue.add( runForward );
  660. menue.add( pause );
  661. menue.add( debug );
  662. menue.add( stepBackward );
  663. menue.add( delayText );
  664. menue.add( delay );
  665. menue.add( treeView );
  666. menue.add( stepBackwardInto );
  667. menue.add( stepBackwardOut );
  668. menue.add( runBackward );
  669. menue.add( randomGraph );
  670. menue.add( save );
  671. menue.add( load );
  672. frame.add( menue, BorderLayout.EAST );
  673. frame.setSize( frame.getWidth() + 1, frame.getHeight() );
  674. frame.setSize( frame.getWidth() - 1, frame.getHeight() );
  675. frame.validate();
  676. frame.repaint();
  677. frame.addComponentListener(new ComponentAdapter()
  678. {
  679. public void componentResized(ComponentEvent evt) {
  680. pl.setSize( layne.getSize() );
  681. menue.setSize( menue.getWidth(), layne.getHeight() );
  682. treeView.setSize( treeView.getWidth(), layne.getHeight() - 120 );
  683. if( graph.getColor( LayoutType.COMBINED ) == null )
  684. {
  685. grout.setHgap( 10 );
  686. grout.setVgap( 10 );
  687. }
  688. else
  689. {
  690. grout.setHgap( layne.getWidth() / 3 );
  691. grout.setVgap( layne.getHeight() / 3 );
  692. }
  693. combined.setSize( layne.getWidth() / 3, layne.getHeight() / 3 );
  694. combined.setLocation( layne.getWidth() / 3, layne.getHeight() / 3 );
  695. layne.remove( pl );
  696. layne.add( pl, 1 );
  697. frame.repaint();
  698. }
  699. });
  700. algorithm.start();
  701. }
  702. private NodeView createNodeView( LayeredGraphNode gNode, LayoutType lt )
  703. {
  704. NodeView graphView = new NodeView( gNode, lt );
  705. graphView.setLayout( null );
  706. graphView.setOpaque( true );
  707. for( LayeredGraphNode n : gNode.getContainedNodes() )
  708. {
  709. NodeView nv = createNodeView( n, lt );
  710. nv.setBounds( nv.getX(), nv.getY(), nv.getWidth(), nv.getHeight() );
  711. graphView.add( nv );
  712. }
  713. for( LayeredGraphEdge e : gNode.getContainedEdges() )
  714. {
  715. EdgeView ev = new EdgeView( e, lt );
  716. ev.setOpaque( true );
  717. graphView.add( ev );
  718. }
  719. return graphView;
  720. }
  721. }