package view; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JLayeredPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.JTree; import javax.swing.UIManager; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import animation.Action; import animation.AnimationController; import bk.BKNodePlacement; import bk.ExtremalLayoutCalc.LayoutType; import graph.LayeredGraphEdge; import graph.LayeredGraphNode; import graph.io.Writer; /** * The main window of the application. * There should only be one instance of this class at the same time. * The JFrame of that single instance can be accessed by the static field {code MainView.frame}. * @author kolja * */ public class MainView { /** * The 'frame' of the main window. * The reason why there can only be one instance of this class. */ public static JFrame frame; private AnimationController controller; private JButton stepForward; private JButton stepForwardInto; private JButton stepForwardOut; private JButton stepBackward; private JButton stepBackwardInto; private JButton stepBackwardOut; private JButton runForward; private JButton runBackward; private JButton pause; private JButton debug; private JButton generateRandom; private JLabel delayText; private JTextField delay; public static JTree pseudoTree; private String strToLen( String s, int l ) { while( s.length() < l ) { s = " " + s + " "; } if( s.length() > l ) return s.substring( 0, l ); return s; } /** * Initialize the window and its contents. * @param graph the graph that is displayed in this window. */ public MainView( LayeredGraphNode graph ) { controller = new AnimationController(); controller.setTimeBetween( 50 ); BKNodePlacement algorithm = new BKNodePlacement( controller, graph ); // Create Menu GUI stepForward = new NiceButton( "stepForward" ); stepForward.setLocation( 10, 10 ); stepForward.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { controller.setContinuous( false ); controller.setNextAction( Action.FORWARD_OVER ); } }); stepForwardInto = new NiceButton( "stepForwardInto" ); stepForwardInto.setLocation( 60, 10 ); stepForwardInto.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { controller.setContinuous( false ); controller.setNextAction( Action.FORWARD ); } }); stepForwardOut = new NiceButton( "stepForwardOut" ); stepForwardOut.setLocation( 110, 10 ); stepForwardOut.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { controller.setContinuous( false ); controller.setNextAction( Action.FORWARD_OUT ); } }); runForward = new NiceButton( "runForward" ); runForward.setLocation( 160, 10 ); runForward.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { controller.setContinuous( true ); controller.setNextAction( Action.FORWARD ); } }); runBackward = new NiceButton( "runBackward" ); runBackward.setLocation( 160, 60 ); runBackward.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { controller.setContinuous( true ); controller.setNextAction( Action.BACKWARD ); } }); stepBackward = new NiceButton( "stepBackward" ); stepBackward.setLocation( 10, 60 ); stepBackward.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { controller.setContinuous( false ); controller.setNextAction( Action.BACKWARD_OVER ); } }); stepBackwardInto = new NiceButton( "stepBackwardInto" ); stepBackwardInto.setLocation( 60, 60 ); stepBackwardInto.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { controller.setContinuous( false ); controller.setNextAction( Action.BACKWARD ); } }); stepBackwardOut = new NiceButton( "stepBackwardOut" ); stepBackwardOut.setLocation( 110, 60 ); stepBackwardOut.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { controller.setContinuous( false ); controller.setNextAction( Action.BACKWARD_OUT ); } }); pause = new NiceButton( "pause" ); pause.setLocation( 210, 10 ); pause.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { controller.setContinuous( false ); } }); debug = new NiceButton( "debug" ); debug.setLocation( 350, 10 ); generateRandom = new NiceButton( "generateRandom" ); generateRandom.setLocation( 350, 60 ); generateRandom.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { } }); delayText = new JLabel( "Delay (ms)" ); delayText.setBounds( 260, 10, 80, 20 ); delay = new JTextField( "50" ); delay.setBounds( 260, 30, 80, 20 ); delay.getDocument().addDocumentListener( new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { try { controller.setTimeBetween( Integer.parseInt( delay.getText() ) ); delay.setBackground( Color.WHITE ); } catch( Exception e1 ) { delay.setBackground( Color.RED ); } } @Override public void removeUpdate(DocumentEvent e) { try { controller.setTimeBetween( Integer.parseInt( delay.getText() ) ); delay.setBackground( Color.WHITE ); } catch( Exception e1 ) { delay.setBackground( Color.RED ); } } @Override public void changedUpdate(DocumentEvent e) { try { controller.setTimeBetween( Integer.parseInt( delay.getText() ) ); delay.setBackground( Color.WHITE ); } catch( Exception e1 ) { delay.setBackground( Color.RED ); } } }); pseudoTree = new JTree( algorithm.createPseudocodeTree() ); pseudoTree.setEnabled( false ); pseudoTree.setCellRenderer( new PseudoCodeRenderer() ); JScrollPane treeView = new JScrollPane( pseudoTree ); treeView.setBounds( 10, 110, 380, 380 ); frame = new JFrame(); // this may write to a static field because there should be only one instance of this class. 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 ) ); frame.setLocation( 100, 100 ); frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); frame.setVisible( true ); frame.addKeyListener( new KeyListener() { @Override public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub } @Override public void keyPressed(KeyEvent e) { if( e.getKeyCode() == KeyEvent.VK_S ) { Writer w = new Writer( "save.json" ); w.writeOutputGraph( graph ); } if( e.getKeyCode() == KeyEvent.VK_LEFT ) controller.setNextAction( Action.BACKWARD ); if( e.getKeyCode() == KeyEvent.VK_RIGHT ) controller.setNextAction( Action.FORWARD ); if( e.getKeyCode() == KeyEvent.VK_P ) controller.setContinuous( !controller.isContinuous() ); frame.validate(); if( e.getKeyCode() == KeyEvent.VK_D ) { System.out.println( "Debug Information Table: " ); System.out.println( "_______________________________________________________________________________________________________________________________________________________________________________________________________________________" ); System.out.println( "|" + strToLen( "Top -> Bottom :> Left", 51 ) + "| |" + strToLen( "Top -> Bottom :> Right", 51 ) + "| |" + strToLen( "Bottom -> Top :> Left", 51 ) + "| |" + strToLen( "Bottom -> Top :> Right", 51 ) + "|" ); System.out.println( "|___________________________________________________| |___________________________________________________| |___________________________________________________| |___________________________________________________|" ); 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 |" ); for( LayeredGraphNode n : graph.getContainedNodes() ) { System.out.println( "|" + strToLen( n.getName(), 6 ) + "|" + strToLen( n.getShift( LayoutType.TOP_BOTTOM_LEFT ) + "", 7 ) + "|" + strToLen( n.getSink( LayoutType.TOP_BOTTOM_LEFT ).getName(), 6 ) + "|" + strToLen( n.getRoot( LayoutType.TOP_BOTTOM_LEFT ).getName(), 6 ) + "|" + strToLen( n.getAlignedTo( LayoutType.TOP_BOTTOM_LEFT ).getName(), 7 ) + "|" + strToLen( n.getX( LayoutType.TOP_BOTTOM_LEFT ) + "", 5 ) + "|" + strToLen( !n.isXUndefined( LayoutType.TOP_BOTTOM_LEFT ) + "", 8 ) + "| " + "|" + strToLen( n.getName(), 6 ) + "|" + strToLen( n.getShift( LayoutType.TOP_BOTTOM_RIGHT ) + "", 7 ) + "|" + strToLen( n.getSink( LayoutType.TOP_BOTTOM_RIGHT ).getName(), 6 ) + "|" + strToLen( n.getRoot( LayoutType.TOP_BOTTOM_RIGHT ).getName(), 6 ) + "|" + strToLen( n.getAlignedTo( LayoutType.TOP_BOTTOM_RIGHT ).getName(), 7 ) + "|" + strToLen( n.getX( LayoutType.TOP_BOTTOM_RIGHT ) + "", 5 ) + "|" + strToLen( !n.isXUndefined( LayoutType.TOP_BOTTOM_RIGHT ) + "", 8 ) + "| " + "|" + strToLen( n.getName(), 6 ) + "|" + strToLen( n.getShift( LayoutType.BOTTOM_TOP_LEFT ) + "", 7 ) + "|" + strToLen( n.getSink( LayoutType.BOTTOM_TOP_LEFT ).getName(), 6 ) + "|" + strToLen( n.getRoot( LayoutType.BOTTOM_TOP_LEFT ).getName(), 6 ) + "|" + strToLen( n.getAlignedTo( LayoutType.BOTTOM_TOP_LEFT ).getName(), 7 ) + "|" + strToLen( n.getX( LayoutType.BOTTOM_TOP_LEFT ) + "", 5 ) + "|" + strToLen( !n.isXUndefined( LayoutType.BOTTOM_TOP_LEFT ) + "", 8 ) + "| " + "|" + strToLen( n.getName(), 6 ) + "|" + strToLen( n.getShift( LayoutType.BOTTOM_TOP_RIGHT ) + "", 7 ) + "|" + strToLen( n.getSink( LayoutType.BOTTOM_TOP_RIGHT ).getName(), 6 ) + "|" + strToLen( n.getRoot( LayoutType.BOTTOM_TOP_RIGHT ).getName(), 6 ) + "|" + strToLen( n.getAlignedTo( LayoutType.BOTTOM_TOP_RIGHT ).getName(), 7 ) + "|" + strToLen( n.getX( LayoutType.BOTTOM_TOP_RIGHT ) + "", 5 ) + "|" + strToLen( !n.isXUndefined( LayoutType.BOTTOM_TOP_RIGHT ) + "", 8 ) + "|"); } System.out.println( "-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------" ); } } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub } }); JLayeredPane layne = new JLayeredPane(); JPanel pl = new JPanel(); GridLayout grout = new GridLayout( 2, 2, 10, 10 ); pl.setLayout( grout ); pl.setLocation( 0, 0 ); pl.setSize( frame.getSize() ); NodeView topLeft = createNodeView( graph, LayoutType.TOP_BOTTOM_LEFT ); NodeView topRight = createNodeView( graph, LayoutType.TOP_BOTTOM_RIGHT ); NodeView bottomLeft = createNodeView( graph, LayoutType.BOTTOM_TOP_LEFT ); NodeView bottomRight = createNodeView( graph, LayoutType.BOTTOM_TOP_RIGHT ); pl.add( topLeft ); pl.add( topRight ); pl.add( bottomLeft ); pl.add( bottomRight ); layne.add( pl, 1 ); NodeView combined = createNodeView( graph, LayoutType.COMBINED ); combined.setSize( 500, 500 ); layne.add( combined, 0 ); frame.add( layne ); JPanel menue = new JPanel(); menue.setLayout( null ); menue.setPreferredSize( new Dimension( 400, 500 ) ); menue.add( stepForward ); menue.add( stepForwardInto ); menue.add( stepForwardOut ); menue.add( runForward ); menue.add( pause ); menue.add( debug ); menue.add( stepBackward ); menue.add( delayText ); menue.add( delay ); menue.add( treeView ); //menue.add( stepBackwardInto ); menue.add( stepBackwardOut ); menue.add( runBackward ); frame.add( menue, BorderLayout.EAST ); frame.setSize( frame.getWidth() + 1, frame.getHeight() ); frame.setSize( frame.getWidth() - 1, frame.getHeight() ); frame.validate(); frame.repaint(); frame.addComponentListener(new ComponentAdapter() { public void componentResized(ComponentEvent evt) { pl.setSize( layne.getSize() ); menue.setSize( menue.getWidth(), layne.getHeight() ); treeView.setSize( treeView.getWidth(), layne.getHeight() - 120 ); if( graph.getColor( LayoutType.COMBINED ) == null ) { grout.setHgap( 10 ); grout.setVgap( 10 ); } else { grout.setHgap( layne.getWidth() / 3 ); grout.setVgap( layne.getHeight() / 3 ); } combined.setSize( layne.getWidth() / 3, layne.getHeight() / 3 ); combined.setLocation( layne.getWidth() / 3, layne.getHeight() / 3 ); frame.validate(); frame.repaint(); } }); algorithm.start(); } private NodeView createNodeView( LayeredGraphNode gNode, LayoutType lt ) { NodeView graphView = new NodeView( gNode, lt ); graphView.setLayout( null ); graphView.setOpaque( true ); for( LayeredGraphNode n : gNode.getContainedNodes() ) { NodeView nv = createNodeView( n, lt ); nv.setBounds( nv.getX(), nv.getY(), nv.getWidth(), nv.getHeight() ); graphView.add( nv ); } for( LayeredGraphEdge e : gNode.getContainedEdges() ) { EdgeView ev = new EdgeView( e, lt ); ev.setOpaque( true ); graphView.add( ev ); } return graphView; } }