MainView.java 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. package view;
  2. import java.awt.BorderLayout;
  3. import java.awt.Color;
  4. import java.awt.Dimension;
  5. import java.awt.GridLayout;
  6. import java.awt.event.ActionEvent;
  7. import java.awt.event.ActionListener;
  8. import java.awt.event.ComponentAdapter;
  9. import java.awt.event.ComponentEvent;
  10. import java.awt.event.KeyEvent;
  11. import java.awt.event.KeyListener;
  12. import javax.swing.JButton;
  13. import javax.swing.JFrame;
  14. import javax.swing.JLabel;
  15. import javax.swing.JLayeredPane;
  16. import javax.swing.JPanel;
  17. import javax.swing.JScrollPane;
  18. import javax.swing.JTextField;
  19. import javax.swing.JTree;
  20. import javax.swing.event.DocumentEvent;
  21. import javax.swing.event.DocumentListener;
  22. import animation.Action;
  23. import animation.AnimationController;
  24. import bk.BKNodePlacement;
  25. import bk.ExtremalLayoutCalc.LayoutType;
  26. import graph.LayeredGraphEdge;
  27. import graph.LayeredGraphNode;
  28. import graph.io.Writer;
  29. /**
  30. * The main window of the application.
  31. * There should only be one instance of this class at the same time.
  32. * The JFrame of that single instance can be accessed by the static field {code MainView.frame}.
  33. * @author kolja
  34. *
  35. */
  36. public class MainView {
  37. /**
  38. * The 'frame' of the main window.
  39. * The reason why there can only be one instance of this class.
  40. */
  41. public static JFrame frame;
  42. private AnimationController controller;
  43. private JButton stepForward;
  44. private JButton stepForwardInto;
  45. private JButton stepForwardOut;
  46. private JButton stepBackward;
  47. private JButton stepBackwardInto;
  48. private JButton stepBackwardOut;
  49. private JButton runForward;
  50. private JButton runBackward;
  51. private JButton pause;
  52. private JButton debug;
  53. private JButton generateRandom;
  54. private JLabel delayText;
  55. private JTextField delay;
  56. public static JTree pseudoTree;
  57. private String strToLen( String s, int l )
  58. {
  59. while( s.length() < l )
  60. {
  61. s = " " + s + " ";
  62. }
  63. if( s.length() > l )
  64. return s.substring( 0, l );
  65. return s;
  66. }
  67. /**
  68. * Initialize the window and its contents.
  69. * @param graph the graph that is displayed in this window.
  70. */
  71. public MainView( LayeredGraphNode graph )
  72. {
  73. controller = new AnimationController();
  74. controller.setTimeBetween( 50 );
  75. BKNodePlacement algorithm = new BKNodePlacement( controller, graph );
  76. // Create Menu GUI
  77. stepForward = new NiceButton( "stepForward" );
  78. stepForward.setLocation( 10, 10 );
  79. stepForward.addActionListener( new ActionListener() {
  80. @Override
  81. public void actionPerformed(ActionEvent e) {
  82. controller.setContinuous( false );
  83. controller.setNextAction( Action.FORWARD_OVER );
  84. }
  85. });
  86. stepForwardInto = new NiceButton( "stepForwardInto" );
  87. stepForwardInto.setLocation( 60, 10 );
  88. stepForwardInto.addActionListener( new ActionListener() {
  89. @Override
  90. public void actionPerformed(ActionEvent e) {
  91. controller.setContinuous( false );
  92. controller.setNextAction( Action.FORWARD );
  93. }
  94. });
  95. stepForwardOut = new NiceButton( "stepForwardOut" );
  96. stepForwardOut.setLocation( 110, 10 );
  97. stepForwardOut.addActionListener( new ActionListener() {
  98. @Override
  99. public void actionPerformed(ActionEvent e) {
  100. controller.setContinuous( false );
  101. controller.setNextAction( Action.FORWARD_OUT );
  102. }
  103. });
  104. runForward = new NiceButton( "runForward" );
  105. runForward.setLocation( 160, 10 );
  106. runForward.addActionListener( new ActionListener() {
  107. @Override
  108. public void actionPerformed(ActionEvent e) {
  109. controller.setContinuous( true );
  110. controller.setNextAction( Action.FORWARD );
  111. }
  112. });
  113. runBackward = new NiceButton( "runBackward" );
  114. runBackward.setLocation( 160, 60 );
  115. runBackward.addActionListener( new ActionListener() {
  116. @Override
  117. public void actionPerformed(ActionEvent e) {
  118. controller.setContinuous( true );
  119. controller.setNextAction( Action.BACKWARD );
  120. }
  121. });
  122. stepBackward = new NiceButton( "stepBackward" );
  123. stepBackward.setLocation( 10, 60 );
  124. stepBackward.addActionListener( new ActionListener() {
  125. @Override
  126. public void actionPerformed(ActionEvent e) {
  127. controller.setContinuous( false );
  128. controller.setNextAction( Action.BACKWARD_OVER );
  129. }
  130. });
  131. stepBackwardInto = new NiceButton( "stepBackwardInto" );
  132. stepBackwardInto.setLocation( 60, 60 );
  133. stepBackwardInto.addActionListener( new ActionListener() {
  134. @Override
  135. public void actionPerformed(ActionEvent e) {
  136. controller.setContinuous( false );
  137. controller.setNextAction( Action.BACKWARD );
  138. }
  139. });
  140. stepBackwardOut = new NiceButton( "stepBackwardOut" );
  141. stepBackwardOut.setLocation( 110, 60 );
  142. stepBackwardOut.addActionListener( new ActionListener() {
  143. @Override
  144. public void actionPerformed(ActionEvent e) {
  145. controller.setContinuous( false );
  146. controller.setNextAction( Action.BACKWARD_OUT );
  147. }
  148. });
  149. pause = new NiceButton( "pause" );
  150. pause.setLocation( 210, 10 );
  151. pause.addActionListener( new ActionListener() {
  152. @Override
  153. public void actionPerformed(ActionEvent e) {
  154. controller.setContinuous( false );
  155. }
  156. });
  157. debug = new NiceButton( "debug" );
  158. debug.setLocation( 350, 10 );
  159. generateRandom = new NiceButton( "generateRandom" );
  160. generateRandom.setLocation( 350, 60 );
  161. generateRandom.addActionListener( new ActionListener() {
  162. @Override
  163. public void actionPerformed(ActionEvent e) {
  164. }
  165. });
  166. delayText = new JLabel( "Delay (ms)" );
  167. delayText.setBounds( 260, 10, 80, 20 );
  168. delay = new JTextField( "50" );
  169. delay.setBounds( 260, 30, 80, 20 );
  170. delay.getDocument().addDocumentListener( new DocumentListener() {
  171. @Override
  172. public void insertUpdate(DocumentEvent e) {
  173. try
  174. {
  175. controller.setTimeBetween( Integer.parseInt( delay.getText() ) );
  176. delay.setBackground( Color.WHITE );
  177. } catch( Exception e1 )
  178. {
  179. delay.setBackground( Color.RED );
  180. }
  181. }
  182. @Override
  183. public void removeUpdate(DocumentEvent e) {
  184. try
  185. {
  186. controller.setTimeBetween( Integer.parseInt( delay.getText() ) );
  187. delay.setBackground( Color.WHITE );
  188. } catch( Exception e1 )
  189. {
  190. delay.setBackground( Color.RED );
  191. }
  192. }
  193. @Override
  194. public void changedUpdate(DocumentEvent e) {
  195. try
  196. {
  197. controller.setTimeBetween( Integer.parseInt( delay.getText() ) );
  198. delay.setBackground( Color.WHITE );
  199. } catch( Exception e1 )
  200. {
  201. delay.setBackground( Color.RED );
  202. }
  203. }
  204. });
  205. pseudoTree = new JTree( algorithm.createPseudocodeTree() );
  206. pseudoTree.setEnabled( false );
  207. pseudoTree.setCellRenderer( new PseudoCodeRenderer() );
  208. JScrollPane treeView = new JScrollPane( pseudoTree );
  209. treeView.setBounds( 10, 110, 380, 380 );
  210. frame = new JFrame(); // this may write to a static field because there should be only one instance of this class.
  211. 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 ) );
  212. frame.setLocation( 100, 100 );
  213. frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
  214. frame.setVisible( true );
  215. frame.addKeyListener( new KeyListener() {
  216. @Override
  217. public void keyTyped(KeyEvent e) {
  218. // TODO Auto-generated method stub
  219. }
  220. @Override
  221. public void keyPressed(KeyEvent e) {
  222. if( e.getKeyCode() == KeyEvent.VK_S )
  223. {
  224. Writer w = new Writer( "save.json" );
  225. w.writeOutputGraph( graph );
  226. }
  227. if( e.getKeyCode() == KeyEvent.VK_LEFT )
  228. controller.setNextAction( Action.BACKWARD );
  229. if( e.getKeyCode() == KeyEvent.VK_RIGHT )
  230. controller.setNextAction( Action.FORWARD );
  231. if( e.getKeyCode() == KeyEvent.VK_P )
  232. controller.setContinuous( !controller.isContinuous() );
  233. frame.validate();
  234. if( e.getKeyCode() == KeyEvent.VK_D )
  235. {
  236. System.out.println( "Debug Information Table: " );
  237. System.out.println( "_______________________________________________________________________________________________________________________________________________________________________________________________________________________" );
  238. System.out.println( "|" + strToLen( "Top -> Bottom :> Left", 51 ) + "| |" + strToLen( "Top -> Bottom :> Right", 51 ) + "| |" + strToLen( "Bottom -> Top :> Left", 51 ) + "| |" + strToLen( "Bottom -> Top :> Right", 51 ) + "|" );
  239. System.out.println( "|___________________________________________________| |___________________________________________________| |___________________________________________________| |___________________________________________________|" );
  240. System.out.println( "| 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 |" );
  241. for( LayeredGraphNode n : graph.getContainedNodes() )
  242. {
  243. System.out.println( "|" + strToLen( n.getName(), 6 ) +
  244. "|" + strToLen( n.getShift( LayoutType.TOP_BOTTOM_LEFT ) + "", 7 ) +
  245. "|" + strToLen( n.getSink( LayoutType.TOP_BOTTOM_LEFT ).getName(), 6 ) +
  246. "|" + strToLen( n.getRoot( LayoutType.TOP_BOTTOM_LEFT ).getName(), 6 ) +
  247. "|" + strToLen( n.getAlignedTo( LayoutType.TOP_BOTTOM_LEFT ).getName(), 7 ) +
  248. "|" + strToLen( n.getX( LayoutType.TOP_BOTTOM_LEFT ) + "", 5 ) +
  249. "|" + strToLen( !n.isXUndefined( LayoutType.TOP_BOTTOM_LEFT ) + "", 8 ) + "| " +
  250. "|" + strToLen( n.getName(), 6 ) +
  251. "|" + strToLen( n.getShift( LayoutType.TOP_BOTTOM_RIGHT ) + "", 7 ) +
  252. "|" + strToLen( n.getSink( LayoutType.TOP_BOTTOM_RIGHT ).getName(), 6 ) +
  253. "|" + strToLen( n.getRoot( LayoutType.TOP_BOTTOM_RIGHT ).getName(), 6 ) +
  254. "|" + strToLen( n.getAlignedTo( LayoutType.TOP_BOTTOM_RIGHT ).getName(), 7 ) +
  255. "|" + strToLen( n.getX( LayoutType.TOP_BOTTOM_RIGHT ) + "", 5 ) +
  256. "|" + strToLen( !n.isXUndefined( LayoutType.TOP_BOTTOM_RIGHT ) + "", 8 ) + "| " +
  257. "|" + strToLen( n.getName(), 6 ) +
  258. "|" + strToLen( n.getShift( LayoutType.BOTTOM_TOP_LEFT ) + "", 7 ) +
  259. "|" + strToLen( n.getSink( LayoutType.BOTTOM_TOP_LEFT ).getName(), 6 ) +
  260. "|" + strToLen( n.getRoot( LayoutType.BOTTOM_TOP_LEFT ).getName(), 6 ) +
  261. "|" + strToLen( n.getAlignedTo( LayoutType.BOTTOM_TOP_LEFT ).getName(), 7 ) +
  262. "|" + strToLen( n.getX( LayoutType.BOTTOM_TOP_LEFT ) + "", 5 ) +
  263. "|" + strToLen( !n.isXUndefined( LayoutType.BOTTOM_TOP_LEFT ) + "", 8 ) + "| " +
  264. "|" + strToLen( n.getName(), 6 ) +
  265. "|" + strToLen( n.getShift( LayoutType.BOTTOM_TOP_RIGHT ) + "", 7 ) +
  266. "|" + strToLen( n.getSink( LayoutType.BOTTOM_TOP_RIGHT ).getName(), 6 ) +
  267. "|" + strToLen( n.getRoot( LayoutType.BOTTOM_TOP_RIGHT ).getName(), 6 ) +
  268. "|" + strToLen( n.getAlignedTo( LayoutType.BOTTOM_TOP_RIGHT ).getName(), 7 ) +
  269. "|" + strToLen( n.getX( LayoutType.BOTTOM_TOP_RIGHT ) + "", 5 ) +
  270. "|" + strToLen( !n.isXUndefined( LayoutType.BOTTOM_TOP_RIGHT ) + "", 8 ) + "|");
  271. }
  272. System.out.println( "-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------" );
  273. }
  274. }
  275. @Override
  276. public void keyReleased(KeyEvent e) {
  277. // TODO Auto-generated method stub
  278. }
  279. });
  280. JLayeredPane layne = new JLayeredPane();
  281. JPanel pl = new JPanel();
  282. GridLayout grout = new GridLayout( 2, 2, 10, 10 );
  283. pl.setLayout( grout );
  284. pl.setLocation( 0, 0 );
  285. pl.setSize( frame.getSize() );
  286. NodeView topLeft = createNodeView( graph, LayoutType.TOP_BOTTOM_LEFT );
  287. NodeView topRight = createNodeView( graph, LayoutType.TOP_BOTTOM_RIGHT );
  288. NodeView bottomLeft = createNodeView( graph, LayoutType.BOTTOM_TOP_LEFT );
  289. NodeView bottomRight = createNodeView( graph, LayoutType.BOTTOM_TOP_RIGHT );
  290. pl.add( topLeft );
  291. pl.add( topRight );
  292. pl.add( bottomLeft );
  293. pl.add( bottomRight );
  294. layne.add( pl, 1 );
  295. NodeView combined = createNodeView( graph, LayoutType.COMBINED );
  296. combined.setSize( 500, 500 );
  297. layne.add( combined, 0 );
  298. frame.add( layne );
  299. JPanel menue = new JPanel();
  300. menue.setLayout( null );
  301. menue.setPreferredSize( new Dimension( 400, 500 ) );
  302. menue.add( stepForward );
  303. menue.add( stepForwardInto );
  304. menue.add( stepForwardOut );
  305. menue.add( runForward );
  306. menue.add( pause );
  307. menue.add( debug );
  308. menue.add( stepBackward );
  309. menue.add( delayText );
  310. menue.add( delay );
  311. menue.add( treeView );
  312. //menue.add( stepBackwardInto );
  313. menue.add( stepBackwardOut );
  314. menue.add( runBackward );
  315. frame.add( menue, BorderLayout.EAST );
  316. frame.validate();
  317. frame.repaint();
  318. frame.addComponentListener(new ComponentAdapter()
  319. {
  320. public void componentResized(ComponentEvent evt) {
  321. pl.setSize( layne.getSize() );
  322. menue.setSize( menue.getWidth(), layne.getHeight() );
  323. treeView.setSize( treeView.getWidth(), layne.getHeight() - 120 );
  324. if( graph.getColor( LayoutType.COMBINED ) == null )
  325. {
  326. grout.setHgap( 10 );
  327. grout.setVgap( 10 );
  328. }
  329. else
  330. {
  331. grout.setHgap( layne.getWidth() / 3 );
  332. grout.setVgap( layne.getHeight() / 3 );
  333. }
  334. combined.setSize( layne.getWidth() / 3, layne.getHeight() / 3 );
  335. combined.setLocation( layne.getWidth() / 3, layne.getHeight() / 3 );
  336. frame.validate();
  337. frame.repaint();
  338. }
  339. });
  340. algorithm.start();
  341. }
  342. private NodeView createNodeView( LayeredGraphNode gNode, LayoutType lt )
  343. {
  344. NodeView graphView = new NodeView( gNode, lt );
  345. graphView.setLayout( null );
  346. graphView.setOpaque( true );
  347. for( LayeredGraphNode n : gNode.getContainedNodes() )
  348. {
  349. NodeView nv = createNodeView( n, lt );
  350. nv.setBounds( nv.getX(), nv.getY(), nv.getWidth(), nv.getHeight() );
  351. graphView.add( nv );
  352. }
  353. for( LayeredGraphEdge e : gNode.getContainedEdges() )
  354. {
  355. EdgeView ev = new EdgeView( e, lt );
  356. ev.setOpaque( true );
  357. graphView.add( ev );
  358. }
  359. return graphView;
  360. }
  361. }