MainView.java 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  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.GridLayout;
  7. import java.awt.event.ActionEvent;
  8. import java.awt.event.ActionListener;
  9. import java.awt.event.ComponentAdapter;
  10. import java.awt.event.ComponentEvent;
  11. import java.awt.event.KeyEvent;
  12. import java.awt.event.MouseAdapter;
  13. import java.awt.event.MouseEvent;
  14. import java.beans.PropertyChangeEvent;
  15. import java.beans.PropertyChangeListener;
  16. import javax.swing.JButton;
  17. import javax.swing.JFileChooser;
  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.JSplitPane;
  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 javax.swing.tree.TreePath;
  32. import org.eclipse.elk.graph.ElkNode;
  33. import animation.Action;
  34. import animation.AnimationController;
  35. import animation.PseudoCodeNode;
  36. import bk.BKNodePlacement;
  37. import bk.ExtremalLayoutCalc.LayoutType;
  38. import graph.InitializeNodePositions;
  39. import graph.LayeredGraphEdge;
  40. import graph.LayeredGraphNode;
  41. import graph.LayeredNode;
  42. import graph.io.Reader;
  43. import graph.io.Writer;
  44. import lib.TextLayoutHelper;
  45. /**
  46. * The main window of the application.
  47. * There should only be one instance of this class at the same time.
  48. * The JFrame of that single instance can be accessed by the static field {code MainView.frame}.
  49. * @author kolja
  50. *
  51. */
  52. public class MainView {
  53. /**
  54. * The 'frame' of the main window.
  55. * The reason why there can only be one instance of this class.
  56. */
  57. private static int frameCounter = 0;
  58. /**
  59. * Random Graph Generator should olny exist once for all windows (so the values will be stored)
  60. */
  61. private static final RandomGraphDialog randomDialog = new RandomGraphDialog();
  62. private JFrame frame;
  63. private AnimationController controller;
  64. private JButton stepForward;
  65. private JButton stepForwardInto;
  66. private JButton stepForwardOut;
  67. private JButton stepBackward;
  68. private JButton stepBackwardInto;
  69. private JButton stepBackwardOut;
  70. private JButton runForward;
  71. private JButton runBackward;
  72. private JButton pause;
  73. private JButton load;
  74. private JButton save;
  75. private JButton debug;
  76. private JButton options;
  77. private JButton randomGraph;
  78. private JLabel delayText;
  79. private JTextField delay;
  80. private JTree pseudoTree;
  81. private LayeredGraphNode graph;
  82. private OptionsDialog optionsDialog;
  83. private String debugInfo()
  84. {
  85. String info = "Debug Information Table: \n";
  86. info += "_______________________________________________________________________________________________________________________________________________________________________________________________________________________\n";
  87. info += "|" + TextLayoutHelper.strToLen( "Top -> Bottom :> Left", 51 ) + "| |" + TextLayoutHelper.strToLen( "Top -> Bottom :> Right", 51 ) + "| |" + TextLayoutHelper.strToLen( "Bottom -> Top :> Left", 51 ) + "| |" + TextLayoutHelper.strToLen( "Bottom -> Top :> Right", 51 ) + "|\n";
  88. info += "|___________________________________________________| |___________________________________________________| |___________________________________________________| |___________________________________________________|\n";
  89. 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";
  90. for( LayeredGraphNode n : graph.getContainedNodes() )
  91. {
  92. info += "|" + TextLayoutHelper.strToLen( n.getName(), 6 ) +
  93. "|" + TextLayoutHelper.strToLen( n.getShift( LayoutType.TOP_BOTTOM_LEFT ) + "", 7 ) +
  94. "|" + TextLayoutHelper.strToLen( n.getSink( LayoutType.TOP_BOTTOM_LEFT ).getName(), 6 ) +
  95. "|" + TextLayoutHelper.strToLen( n.getRoot( LayoutType.TOP_BOTTOM_LEFT ).getName(), 6 ) +
  96. "|" + TextLayoutHelper.strToLen( n.getAlign( LayoutType.TOP_BOTTOM_LEFT ).getName(), 7 ) +
  97. "|" + TextLayoutHelper.strToLen( n.getX( LayoutType.TOP_BOTTOM_LEFT ) + "", 5 ) +
  98. "|" + TextLayoutHelper.strToLen( !n.isXUndefined( LayoutType.TOP_BOTTOM_LEFT ) + "", 8 ) + "| " +
  99. "|" + TextLayoutHelper.strToLen( n.getName(), 6 ) +
  100. "|" + TextLayoutHelper.strToLen( n.getShift( LayoutType.TOP_BOTTOM_RIGHT ) + "", 7 ) +
  101. "|" + TextLayoutHelper.strToLen( n.getSink( LayoutType.TOP_BOTTOM_RIGHT ).getName(), 6 ) +
  102. "|" + TextLayoutHelper.strToLen( n.getRoot( LayoutType.TOP_BOTTOM_RIGHT ).getName(), 6 ) +
  103. "|" + TextLayoutHelper.strToLen( n.getAlign( LayoutType.TOP_BOTTOM_RIGHT ).getName(), 7 ) +
  104. "|" + TextLayoutHelper.strToLen( n.getX( LayoutType.TOP_BOTTOM_RIGHT ) + "", 5 ) +
  105. "|" + TextLayoutHelper.strToLen( !n.isXUndefined( LayoutType.TOP_BOTTOM_RIGHT ) + "", 8 ) + "| " +
  106. "|" + TextLayoutHelper.strToLen( n.getName(), 6 ) +
  107. "|" + TextLayoutHelper.strToLen( n.getShift( LayoutType.BOTTOM_TOP_LEFT ) + "", 7 ) +
  108. "|" + TextLayoutHelper.strToLen( n.getSink( LayoutType.BOTTOM_TOP_LEFT ).getName(), 6 ) +
  109. "|" + TextLayoutHelper.strToLen( n.getRoot( LayoutType.BOTTOM_TOP_LEFT ).getName(), 6 ) +
  110. "|" + TextLayoutHelper.strToLen( n.getAlign( LayoutType.BOTTOM_TOP_LEFT ).getName(), 7 ) +
  111. "|" + TextLayoutHelper.strToLen( n.getX( LayoutType.BOTTOM_TOP_LEFT ) + "", 5 ) +
  112. "|" + TextLayoutHelper.strToLen( !n.isXUndefined( LayoutType.BOTTOM_TOP_LEFT ) + "", 8 ) + "| " +
  113. "|" + TextLayoutHelper.strToLen( n.getName(), 6 ) +
  114. "|" + TextLayoutHelper.strToLen( n.getShift( LayoutType.BOTTOM_TOP_RIGHT ) + "", 7 ) +
  115. "|" + TextLayoutHelper.strToLen( n.getSink( LayoutType.BOTTOM_TOP_RIGHT ).getName(), 6 ) +
  116. "|" + TextLayoutHelper.strToLen( n.getRoot( LayoutType.BOTTOM_TOP_RIGHT ).getName(), 6 ) +
  117. "|" + TextLayoutHelper.strToLen( n.getAlign( LayoutType.BOTTOM_TOP_RIGHT ).getName(), 7 ) +
  118. "|" + TextLayoutHelper.strToLen( n.getX( LayoutType.BOTTOM_TOP_RIGHT ) + "", 5 ) +
  119. "|" + TextLayoutHelper.strToLen( !n.isXUndefined( LayoutType.BOTTOM_TOP_RIGHT ) + "", 8 ) + "|\n";
  120. }
  121. info += "-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------";
  122. return info;
  123. }
  124. private void showDebugInfo()
  125. {
  126. JFrame debugFrame = new JFrame();
  127. JTextArea info = new JTextArea();
  128. info.setEditable( false );
  129. info.setFont( new Font( Font.MONOSPACED, Font.PLAIN, 11 ) );
  130. String infoS = debugInfo();
  131. info.setText( infoS );
  132. JScrollPane view = new JScrollPane( info );
  133. debugFrame.add( view );
  134. debugFrame.setSize( frame.getWidth(), frame.getHeight() );
  135. debugFrame.setVisible( true );
  136. System.out.println( infoS );
  137. }
  138. public MainView( ElkNode graph )
  139. {
  140. this( LayeredNode.convertToLayeredGraph( graph ) );
  141. }
  142. /**
  143. * Initialize the window and its contents.
  144. * There is good reason not to split up this method to smaller methods:
  145. * Imagine a tree with a fixed number of nodes, but limited degree of branching.
  146. * The the height of the tree is at least inversely proportional to the degree of branching.
  147. * This means halving the maximum method size by splitting methods would make the call stack twice as high
  148. * and this way debugging twice as time-consuming.
  149. * @param graph the graph that is displayed in this window.
  150. */
  151. public MainView( LayeredGraphNode graph )
  152. {
  153. frameCounter++;
  154. this.graph = graph;
  155. controller = new AnimationController();
  156. frame = new JFrame( "NodeShuffler" );
  157. frame.addWindowListener(new java.awt.event.WindowAdapter() {
  158. @Override
  159. public void windowClosing(java.awt.event.WindowEvent windowEvent) {
  160. frameCounter--;
  161. if( frameCounter == 0 )
  162. System.exit( 0 );
  163. }
  164. });
  165. BKNodePlacement algorithm = new BKNodePlacement( controller, graph, frame );
  166. // Create Menu GUI
  167. stepForward = new NiceButton( "stepForward" );
  168. stepForward.setLocation( 10, 10 );
  169. stepForward.setMnemonic( KeyEvent.VK_DOWN );
  170. stepForward.setToolTipText( "Forward step over (alt + down arrow key)" );
  171. stepForward.addActionListener( new ActionListener() {
  172. @Override
  173. public void actionPerformed(ActionEvent e) {
  174. controller.setContinuous( false );
  175. controller.setNextAction( Action.FORWARD_OVER );
  176. }
  177. });
  178. stepForwardInto = new NiceButton( "stepForwardInto" );
  179. stepForwardInto.setLocation( 60, 10 );
  180. stepForwardInto.setMnemonic( KeyEvent.VK_RIGHT );
  181. stepForwardInto.setToolTipText( "Forward step into (alt + right arrow key)" );
  182. stepForwardInto.addActionListener( new ActionListener() {
  183. @Override
  184. public void actionPerformed(ActionEvent e) {
  185. controller.setContinuous( false );
  186. controller.setNextAction( Action.FORWARD );
  187. }
  188. });
  189. stepForwardOut = new NiceButton( "stepForwardOut" );
  190. stepForwardOut.setLocation( 110, 10 );
  191. stepForwardOut.setMnemonic( KeyEvent.VK_PAGE_DOWN );
  192. stepForwardOut.setToolTipText( "Forward step out (alt + page down key)" );
  193. stepForwardOut.addActionListener( new ActionListener() {
  194. @Override
  195. public void actionPerformed(ActionEvent e) {
  196. controller.setContinuous( false );
  197. controller.setNextAction( Action.FORWARD_OUT );
  198. }
  199. });
  200. runForward = new NiceButton( "runForward" );
  201. runForward.setLocation( 160, 10 );
  202. runForward.setMnemonic( KeyEvent.VK_P );
  203. runForward.setToolTipText( "Run forwards (alt + p)" );
  204. runForward.addActionListener( new ActionListener() {
  205. @Override
  206. public void actionPerformed(ActionEvent e) {
  207. controller.setContinuous( true );
  208. controller.setNextAction( Action.FORWARD );
  209. }
  210. });
  211. runBackward = new NiceButton( "runBackward" );
  212. runBackward.setLocation( 160, 60 );
  213. runBackward.setMnemonic( KeyEvent.VK_R );
  214. runBackward.setToolTipText( "Run backwards (alt + r)" );
  215. runBackward.addActionListener( new ActionListener() {
  216. @Override
  217. public void actionPerformed(ActionEvent e) {
  218. controller.setContinuous( true );
  219. controller.setNextAction( Action.BACKWARD );
  220. }
  221. });
  222. options = new NiceButton( "settings" );
  223. options.setLocation( 210, 60 );
  224. options.setMnemonic( KeyEvent.VK_O );
  225. options.setToolTipText( "Preferences (alt + o)" );
  226. options.addActionListener( new ActionListener() {
  227. @Override
  228. public void actionPerformed(ActionEvent e) {
  229. optionsDialog.setVisible( true );
  230. }
  231. });
  232. stepBackward = new NiceButton( "stepBackward" );
  233. stepBackward.setLocation( 10, 60 );
  234. stepBackward.setMnemonic( KeyEvent.VK_UP );
  235. stepBackward.setToolTipText( "Backward step over (alt + up arrow key)" );
  236. stepBackward.addActionListener( new ActionListener() {
  237. @Override
  238. public void actionPerformed(ActionEvent e) {
  239. controller.setContinuous( false );
  240. controller.setNextAction( Action.BACKWARD_OVER );
  241. }
  242. });
  243. stepBackwardInto = new NiceButton( "stepBackwardInto" );
  244. stepBackwardInto.setLocation( 60, 60 );
  245. stepBackwardInto.setMnemonic( KeyEvent.VK_LEFT );
  246. stepBackwardInto.setToolTipText( "Backward step into (alt + left arrow key)" );
  247. stepBackwardInto.addActionListener( new ActionListener() {
  248. @Override
  249. public void actionPerformed(ActionEvent e) {
  250. controller.setContinuous( false );
  251. controller.setNextAction( Action.BACKWARD );
  252. }
  253. });
  254. stepBackwardOut = new NiceButton( "stepBackwardOut" );
  255. stepBackwardOut.setLocation( 110, 60 );
  256. stepBackwardOut.setMnemonic( KeyEvent.VK_PAGE_UP );
  257. stepBackwardOut.setToolTipText( "Backward step out (alt + page up)" );
  258. stepBackwardOut.addActionListener( new ActionListener() {
  259. @Override
  260. public void actionPerformed(ActionEvent e) {
  261. controller.setContinuous( false );
  262. controller.setNextAction( Action.BACKWARD_OUT );
  263. }
  264. });
  265. pause = new NiceButton( "pause" );
  266. pause.setLocation( 210, 10 );
  267. pause.setMnemonic( KeyEvent.VK_PAUSE );
  268. pause.setToolTipText( "Pause (alt + pause)" );
  269. pause.addActionListener( new ActionListener() {
  270. @Override
  271. public void actionPerformed(ActionEvent e) {
  272. controller.setContinuous( false );
  273. }
  274. });
  275. debug = new NiceButton( "debug" );
  276. debug.setLocation( 360, 10 );
  277. debug.setMnemonic( KeyEvent.VK_D );
  278. debug.setToolTipText( "Show debug info (alt + d)" );
  279. debug.addActionListener( new ActionListener() {
  280. @Override
  281. public void actionPerformed(ActionEvent e) {
  282. showDebugInfo();
  283. }
  284. });
  285. randomGraph = new NiceButton( "random" );
  286. randomGraph.setLocation( 360, 60 );
  287. randomGraph.setMnemonic( KeyEvent.VK_G );
  288. randomGraph.setToolTipText( "Generate random graph (alt + g)" );
  289. randomGraph.addActionListener( new ActionListener() {
  290. @Override
  291. public void actionPerformed(ActionEvent e) {
  292. randomDialog.setVisible( true );
  293. }
  294. });
  295. delayText = new JLabel( "Delay (ms)" );
  296. delayText.setBounds( 260, 10, 80, 20 );
  297. delay = new JTextField( String.valueOf(AnimationController.DEFAULT_DELAY) );
  298. delay.setBounds( 260, 30, 90, 20 );
  299. delay.getDocument().addDocumentListener( new DocumentListener() {
  300. @Override
  301. public void insertUpdate(DocumentEvent e) {
  302. try
  303. {
  304. controller.setDelay( Integer.parseInt( delay.getText() ) );
  305. delay.setBackground( Color.WHITE );
  306. } catch( Exception e1 )
  307. {
  308. delay.setBackground( Color.RED );
  309. }
  310. }
  311. @Override
  312. public void removeUpdate(DocumentEvent e) {
  313. try
  314. {
  315. controller.setDelay( Integer.parseInt( delay.getText() ) );
  316. delay.setBackground( Color.WHITE );
  317. } catch( Exception e1 )
  318. {
  319. delay.setBackground( Color.RED );
  320. }
  321. }
  322. @Override
  323. public void changedUpdate(DocumentEvent e) {
  324. try
  325. {
  326. controller.setDelay( Integer.parseInt( delay.getText() ) );
  327. delay.setBackground( Color.WHITE );
  328. } catch( Exception e1 )
  329. {
  330. delay.setBackground( Color.RED );
  331. }
  332. }
  333. });
  334. load = new NiceButton( "load" );
  335. load.setLocation( 260, 60 );
  336. load.setMnemonic( KeyEvent.VK_L );
  337. load.setToolTipText( "Load a graph (alt + l)" );
  338. load.addActionListener( new ActionListener() {
  339. @Override
  340. public void actionPerformed(ActionEvent e) {
  341. JFileChooser chooser = new JFileChooser();
  342. chooser.setFileFilter( new FileNameExtensionFilter("Json Graph", "json") );
  343. chooser.showOpenDialog( frame );
  344. if( chooser.getSelectedFile() != null )
  345. {
  346. Reader r = new Reader( chooser.getSelectedFile().getAbsolutePath() );
  347. LayeredGraphNode graph = r.readInputGraph();
  348. InitializeNodePositions.placeNodes( graph );
  349. new MainView( graph );
  350. }
  351. }
  352. });
  353. save = new NiceButton( "save" );
  354. save.setLocation( 310, 60 );
  355. save.setMnemonic( KeyEvent.VK_S );
  356. save.setToolTipText( "Save graph (alt + s)" );
  357. save.addActionListener( new ActionListener() {
  358. @Override
  359. public void actionPerformed(ActionEvent e) {
  360. JFileChooser chooser = new JFileChooser();
  361. chooser.setFileFilter( new FileNameExtensionFilter("Json Graph", "json") );
  362. chooser.showSaveDialog( frame );
  363. if( chooser.getSelectedFile() != null )
  364. {
  365. Writer w = new Writer( chooser.getSelectedFile().getAbsolutePath() );
  366. w.writeOutputGraph( graph );
  367. }
  368. }
  369. });
  370. pseudoTree = new JTree();
  371. pseudoTree.setBackground(RenderHelper.BACKGROUND_COLOR);
  372. PseudoCodeNode tree = algorithm.createPseudocodeTree( pseudoTree );
  373. tree.setController( controller );
  374. pseudoTree.setModel( new DefaultTreeModel( tree ) );
  375. pseudoTree.setCellRenderer( new PseudoCodeRenderer() );
  376. pseudoTree.setSelectionModel( null );
  377. pseudoTree.setToolTipText("");
  378. pseudoTree.addMouseListener( new MouseAdapter() {
  379. public void mousePressed(MouseEvent e) {
  380. TreePath selPath = pseudoTree.getPathForLocation(e.getX(), e.getY());
  381. if( selPath != null && e.getClickCount() == 3 ) {
  382. ((PseudoCodeNode)selPath.getLastPathComponent()).setBreakPoint( !((PseudoCodeNode)selPath.getLastPathComponent()).hasBreakPoint() );
  383. if( !pseudoTree.isExpanded( selPath ) )
  384. {
  385. pseudoTree.collapsePath( selPath );
  386. pseudoTree.expandPath( selPath );
  387. }
  388. else
  389. {
  390. pseudoTree.expandPath( selPath );
  391. pseudoTree.collapsePath( selPath );
  392. }
  393. pseudoTree.repaint();
  394. frame.repaint();
  395. }
  396. }
  397. } );
  398. pseudoTree.setRowHeight(15);
  399. ((PseudoCodeRenderer)pseudoTree.getCellRenderer()).setMemory( algorithm.getProcessor().getMemory());
  400. JScrollPane treeView = new JScrollPane( pseudoTree );
  401. treeView.setBounds( 10, 110, 390, 380 );
  402. JTextArea debugText = new JTextArea();
  403. debugText.setFont( new Font( "Monospaced", Font.PLAIN, 12 ) );
  404. debugText.setEditable( false );
  405. debugText.setBackground( RenderHelper.BACKGROUND_COLOR );
  406. debugText.setForeground( RenderHelper.FOREGROUND_COLOR );
  407. JScrollPane debugView = new JScrollPane( debugText );
  408. debugView.setBounds( treeView.getX(), treeView.getY() + 500, treeView.getWidth(), 250 );
  409. frame.setSize( (int)graph.getWidth( LayoutType.TOP_BOTTOM_LEFT ) * 2 + 450, (int)graph.getHeight( LayoutType.TOP_BOTTOM_LEFT ) * 2 + 50 );
  410. frame.setLocation( 100, 100 );
  411. frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
  412. frame.setVisible( true );
  413. JLayeredPane layne = new JLayeredPane();
  414. layne.setLayout( new BorderLayout() );
  415. JPanel pl = new JPanel();
  416. GridLayout grout = new GridLayout( 2, 2, 10, 10 );
  417. pl.setLayout( grout );
  418. pl.setLocation( 0, 0 );
  419. pl.setSize( frame.getSize() );
  420. NodeView topLeft = createNodeView( graph, LayoutType.TOP_BOTTOM_LEFT );
  421. NodeView topRight = createNodeView( graph, LayoutType.TOP_BOTTOM_RIGHT );
  422. NodeView bottomLeft = createNodeView( graph, LayoutType.BOTTOM_TOP_LEFT );
  423. NodeView bottomRight = createNodeView( graph, LayoutType.BOTTOM_TOP_RIGHT );
  424. pl.add( topLeft );
  425. pl.add( topRight );
  426. pl.add( bottomLeft );
  427. pl.add( bottomRight );
  428. layne.add( pl, 1 );
  429. NodeView combined = createNodeView( graph, LayoutType.COMBINED );
  430. combined.setSize( 500, 500 );
  431. layne.add( combined, 0 );
  432. JSplitPane spane = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT );
  433. spane.setLeftComponent( layne );
  434. spane.setResizeWeight(0.5);
  435. JPanel menue = new JPanel();
  436. menue.setLayout( null );
  437. menue.setPreferredSize( new Dimension( 410, 500 ) );
  438. menue.add( stepForward );
  439. menue.add( stepForwardInto );
  440. menue.add( stepForwardOut );
  441. menue.add( runForward );
  442. menue.add( pause );
  443. menue.add( debug );
  444. menue.add( stepBackward );
  445. menue.add( delayText );
  446. menue.add( delay );
  447. menue.add( stepBackwardInto );
  448. menue.add( stepBackwardOut );
  449. menue.add( runBackward );
  450. menue.add( randomGraph );
  451. menue.add( save );
  452. menue.add( load );
  453. menue.add( options );
  454. JSplitPane spane2 = new JSplitPane( JSplitPane.VERTICAL_SPLIT );
  455. spane2.setBounds( 10, 110, 390, 650 );
  456. spane2.setTopComponent( treeView );
  457. spane2.setBottomComponent( debugView );
  458. spane2.setDividerLocation( 390 );
  459. spane2.setResizeWeight(0.5);
  460. menue.add( spane2 );
  461. spane.setRightComponent( menue);
  462. spane.setContinuousLayout( true );
  463. spane.setDividerLocation( frame.getWidth() - 430 );
  464. spane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() {
  465. @Override
  466. public void propertyChange(PropertyChangeEvent evt) {
  467. frame.getComponentListeners()[ 0 ].componentResized( null );
  468. }
  469. });
  470. frame.add( spane );
  471. frame.revalidate();
  472. frame.repaint();
  473. frame.addComponentListener(new ComponentAdapter()
  474. {
  475. public void componentResized(ComponentEvent evt) {
  476. menue.setSize( menue.getWidth(), layne.getHeight() );
  477. spane2.setSize( menue.getWidth() - 20, menue.getHeight() - 120 );
  478. if( graph.getColor( LayoutType.COMBINED ) == null )
  479. {
  480. grout.setHgap( 10 );
  481. grout.setVgap( 10 );
  482. }
  483. else
  484. {
  485. grout.setHgap( layne.getWidth() / 3 );
  486. grout.setVgap( layne.getHeight() / 3 );
  487. }
  488. combined.setSize( layne.getWidth() / 3, layne.getHeight() / 3 );
  489. combined.setLocation( layne.getWidth() / 3, layne.getHeight() / 3 );
  490. debugText.setText( algorithm.getDebugString().trim() );
  491. layne.remove( pl );
  492. layne.add( pl, 1 );
  493. if( optionsDialog != null && optionsDialog.getLayerDisplayOption() == 1 )
  494. {
  495. pl.remove( topLeft );
  496. pl.remove( topRight );
  497. pl.remove( bottomLeft );
  498. pl.remove( bottomRight );
  499. pl.remove( combined );
  500. switch( algorithm.getAlgorithmState() )
  501. {
  502. case CONFLICTS:
  503. pl.add( topLeft );
  504. break;
  505. case LAYOUT1:
  506. pl.add( topLeft );
  507. break;
  508. case LAYOUT2:
  509. pl.add( topRight );
  510. break;
  511. case LAYOUT3:
  512. pl.add( bottomLeft );
  513. break;
  514. case LAYOUT4:
  515. pl.add( bottomRight );
  516. break;
  517. case COMBINE:
  518. pl.add( combined );
  519. break;
  520. }
  521. pl.revalidate();
  522. }
  523. treeView.revalidate();
  524. frame.repaint();
  525. }
  526. });
  527. frame.setSize( frame.getWidth() + 1, frame.getHeight() );
  528. frame.setSize( frame.getWidth() - 1, frame.getHeight() );
  529. if( frame.getHeight() < (int)graph.getHeight( LayoutType.TOP_BOTTOM_LEFT ) * 2 + 50 )
  530. {
  531. double factor = (graph.getHeight( LayoutType.TOP_BOTTOM_LEFT ) * 2) / (frame.getHeight()-50);
  532. frame.setSize( (int)((frame.getWidth() - 450) / factor) + 450, frame.getHeight() );
  533. spane.setDividerLocation( frame.getWidth() - 330 );
  534. }
  535. optionsDialog = new OptionsDialog();
  536. optionsDialog.addActionListener( new ActionListener() {
  537. @Override
  538. public void actionPerformed(ActionEvent e) {
  539. pl.remove( topLeft );
  540. pl.remove( topRight );
  541. pl.remove( bottomLeft );
  542. pl.remove( bottomRight );
  543. pl.remove( combined );
  544. layne.remove( combined );
  545. controller.setStepOption( optionsDialog.getRunStepsOption() );
  546. if( optionsDialog.getLayerDisplayOption() == 0 )
  547. {
  548. pl.setLayout( grout );
  549. pl.add( topLeft );
  550. pl.add( topRight );
  551. pl.add( bottomLeft );
  552. pl.add( bottomRight );
  553. layne.add( combined, 0 );
  554. pl.revalidate();
  555. }
  556. else
  557. {
  558. pl.setLayout( new BorderLayout() );
  559. switch( algorithm.getAlgorithmState() )
  560. {
  561. case CONFLICTS:
  562. pl.add( topLeft );
  563. break;
  564. case LAYOUT1:
  565. pl.add( topLeft );
  566. break;
  567. case LAYOUT2:
  568. pl.add( topRight );
  569. break;
  570. case LAYOUT3:
  571. pl.add( bottomLeft );
  572. break;
  573. case LAYOUT4:
  574. pl.add( bottomRight );
  575. break;
  576. case COMBINE:
  577. pl.add( combined );
  578. break;
  579. }
  580. pl.revalidate();
  581. }
  582. frame.repaint();
  583. }
  584. });
  585. algorithm.start();
  586. }
  587. private NodeView createNodeView( LayeredGraphNode gNode, LayoutType lt )
  588. {
  589. NodeView graphView = new NodeView( gNode, lt );
  590. ((LayeredNode)gNode).setView( graphView, lt );
  591. graphView.setLayout( null );
  592. graphView.setOpaque( true );
  593. for( LayeredGraphNode n : gNode.getContainedNodes() )
  594. {
  595. NodeView nv = createNodeView( n, lt );
  596. nv.setBounds( nv.getX(), nv.getY(), nv.getWidth(), nv.getHeight() );
  597. graphView.add( nv );
  598. }
  599. for( LayeredGraphEdge e : gNode.getContainedEdges() )
  600. {
  601. EdgeView ev = new EdgeView( e, lt );
  602. ev.setOpaque( true );
  603. graphView.add( ev );
  604. }
  605. return graphView;
  606. }
  607. }