MainView.java 16 KB

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