package view; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Font; 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.ComponentListener; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JLayeredPane; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.JTree; import javax.swing.border.BevelBorder; import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreePath; import org.eclipse.elk.graph.ElkNode; import bk.BKNodePlacement; import bk.BKNodePlacement.Stage; import bk.LayoutType; import graph.LayeredGraphEdge; import graph.LayeredGraphNode; import graph.LayeredNode; import graph.io.Reader; import graph.io.Writer; import lib.SimpleNodePlacement; import lib.TextLayoutHelper; import processor.Action; import processor.ProcessController; import processor.PseudoCodeNode; import processor.PseudoCodeProcessor; /** * 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. */ private static int frameCounter = 0; /** * Random Graph Generator should olny exist once for all windows (so the values will be stored) */ private static final RandomGraphDialog randomDialog = new RandomGraphDialog(); private JFrame frame; private ProcessController 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 load; private JButton save; private JButton debug; private JButton options; private JButton randomGraph; private JLabel delayText; private JTextField delay; private JTree pseudoTree; private LayeredGraphNode graph; private OptionsDialog optionsDialog; private String debugInfo() { String info = "Debug Information Table: \n"; info += "_______________________________________________________________________________________________________________________________________________________________________________________________________________________\n"; 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"; info += "|___________________________________________________| |___________________________________________________| |___________________________________________________| |___________________________________________________|\n"; 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"; for( LayeredGraphNode n : graph.getContainedNodes() ) { info += "|" + TextLayoutHelper.strToLen( n.toString(), 6 ) + "|" + TextLayoutHelper.strToLen( n.getShift( LayoutType.LEFTMOST_UPPER ) + "", 7 ) + "|" + TextLayoutHelper.strToLen( n.getSink( LayoutType.LEFTMOST_UPPER ).toString(), 6 ) + "|" + TextLayoutHelper.strToLen( n.getRoot( LayoutType.LEFTMOST_UPPER ).toString(), 6 ) + "|" + TextLayoutHelper.strToLen( n.getAlign( LayoutType.LEFTMOST_UPPER ).toString(), 7 ) + "|" + TextLayoutHelper.strToLen( n.getX( LayoutType.LEFTMOST_UPPER ) + "", 5 ) + "|" + TextLayoutHelper.strToLen( !n.isXUndefined( LayoutType.LEFTMOST_UPPER ) + "", 8 ) + "| " + "|" + TextLayoutHelper.strToLen( n.toString(), 6 ) + "|" + TextLayoutHelper.strToLen( n.getShift( LayoutType.RIGHTMOST_UPPER ) + "", 7 ) + "|" + TextLayoutHelper.strToLen( n.getSink( LayoutType.RIGHTMOST_UPPER ).toString(), 6 ) + "|" + TextLayoutHelper.strToLen( n.getRoot( LayoutType.RIGHTMOST_UPPER ).toString(), 6 ) + "|" + TextLayoutHelper.strToLen( n.getAlign( LayoutType.RIGHTMOST_UPPER ).toString(), 7 ) + "|" + TextLayoutHelper.strToLen( n.getX( LayoutType.RIGHTMOST_UPPER ) + "", 5 ) + "|" + TextLayoutHelper.strToLen( !n.isXUndefined( LayoutType.RIGHTMOST_UPPER ) + "", 8 ) + "| " + "|" + TextLayoutHelper.strToLen( n.toString(), 6 ) + "|" + TextLayoutHelper.strToLen( n.getShift( LayoutType.LEFTMOST_LOWER ) + "", 7 ) + "|" + TextLayoutHelper.strToLen( n.getSink( LayoutType.LEFTMOST_LOWER ).toString(), 6 ) + "|" + TextLayoutHelper.strToLen( n.getRoot( LayoutType.LEFTMOST_LOWER ).toString(), 6 ) + "|" + TextLayoutHelper.strToLen( n.getAlign( LayoutType.LEFTMOST_LOWER ).toString(), 7 ) + "|" + TextLayoutHelper.strToLen( n.getX( LayoutType.LEFTMOST_LOWER ) + "", 5 ) + "|" + TextLayoutHelper.strToLen( !n.isXUndefined( LayoutType.LEFTMOST_LOWER ) + "", 8 ) + "| " + "|" + TextLayoutHelper.strToLen( n.toString(), 6 ) + "|" + TextLayoutHelper.strToLen( n.getShift( LayoutType.RIGHTMOST_LOWER ) + "", 7 ) + "|" + TextLayoutHelper.strToLen( n.getSink( LayoutType.RIGHTMOST_LOWER ).toString(), 6 ) + "|" + TextLayoutHelper.strToLen( n.getRoot( LayoutType.RIGHTMOST_LOWER ).toString(), 6 ) + "|" + TextLayoutHelper.strToLen( n.getAlign( LayoutType.RIGHTMOST_LOWER ).toString(), 7 ) + "|" + TextLayoutHelper.strToLen( n.getX( LayoutType.RIGHTMOST_LOWER ) + "", 5 ) + "|" + TextLayoutHelper.strToLen( !n.isXUndefined( LayoutType.RIGHTMOST_LOWER ) + "", 8 ) + "|\n"; } info += "-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"; return info; } private void showDebugInfo() { JFrame debugFrame = new JFrame(); JTextArea info = new JTextArea(); info.setEditable( false ); info.setFont( new Font( Font.MONOSPACED, Font.PLAIN, 11 ) ); String infoS = debugInfo(); info.setText( infoS ); JScrollPane view = new JScrollPane( info ); debugFrame.add( view ); debugFrame.setSize( frame.getWidth(), frame.getHeight() ); debugFrame.setVisible( true ); if (infoS.trim().equals("")) { System.out.println( "" ); System.out.println( "Debug info:" ); System.out.println( infoS ); System.out.println( "" ); } } public MainView( ElkNode graph ) { this( LayeredNode.convertToLayeredGraph( graph ) ); } /** * Initialize the window and its contents. * There is good reason not to split up this method to smaller methods: * Imagine a tree with a fixed number of nodes, but limited degree of branching. * The the height of the tree is at least inversely proportional to the degree of branching. * This means halving the maximum method size by splitting methods would make the call stack twice as high * and this way debugging twice as time-consuming. * @param graph the graph that is displayed in this window. */ public MainView( LayeredGraphNode graph ) { graph.setColor( null, null ); frameCounter++; this.graph = graph; frame = new JFrame( "NodeShuffler" ); frame.addWindowListener(new java.awt.event.WindowAdapter() { @Override public void windowClosing(java.awt.event.WindowEvent windowEvent) { frameCounter--; if( frameCounter == 0 ) System.exit( 0 ); } }); // Create Pseudo Code and Processor BKNodePlacement algorithm = new BKNodePlacement(); pseudoTree = new JTree(); PseudoCodeNode tree = algorithm.createPseudocodeTree( pseudoTree ); PseudoCodeProcessor processor = new PseudoCodeProcessor( tree, graph, frame ); controller = processor.getController(); // Create Menu GUI stepForward = new NiceButton( "stepForward" ); stepForward.setLocation( 10, 10 ); stepForward.setMnemonic( KeyEvent.VK_DOWN ); stepForward.setToolTipText( "Forward step over (alt + down arrow key)" ); 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.setMnemonic( KeyEvent.VK_RIGHT ); stepForwardInto.setToolTipText( "Forward step into (alt + right arrow key)" ); 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.setMnemonic( KeyEvent.VK_PAGE_DOWN ); stepForwardOut.setToolTipText( "Forward step out (alt + page down key)" ); 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.setMnemonic( KeyEvent.VK_P ); runForward.setToolTipText( "Run forwards (alt + p)" ); 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.setMnemonic( KeyEvent.VK_R ); runBackward.setToolTipText( "Run backwards (alt + r)" ); runBackward.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { controller.setContinuous( true ); controller.setNextAction( Action.BACKWARD ); } }); options = new NiceButton( "settings" ); options.setLocation( 210, 60 ); options.setMnemonic( KeyEvent.VK_O ); options.setToolTipText( "Preferences (alt + o)" ); options.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { optionsDialog.setVisible( true ); } }); stepBackward = new NiceButton( "stepBackward" ); stepBackward.setLocation( 10, 60 ); stepBackward.setMnemonic( KeyEvent.VK_UP ); stepBackward.setToolTipText( "Backward step over (alt + up arrow key)" ); 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.setMnemonic( KeyEvent.VK_LEFT ); stepBackwardInto.setToolTipText( "Backward step into (alt + left arrow key)" ); 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.setMnemonic( KeyEvent.VK_PAGE_UP ); stepBackwardOut.setToolTipText( "Backward step out (alt + page up)" ); 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.setMnemonic( KeyEvent.VK_PAUSE ); pause.setToolTipText( "Pause (alt + pause)" ); pause.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { controller.setContinuous( false ); } }); debug = new NiceButton( "debug" ); debug.setLocation( 360, 10 ); debug.setMnemonic( KeyEvent.VK_D ); debug.setToolTipText( "Show debug info (alt + d)" ); debug.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { showDebugInfo(); } }); randomGraph = new NiceButton( "random" ); randomGraph.setLocation( 360, 60 ); randomGraph.setMnemonic( KeyEvent.VK_G ); randomGraph.setToolTipText( "Generate random graph (alt + g)" ); randomGraph.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { randomDialog.setVisible( true ); } }); delayText = new JLabel( "Delay (ms)" ); delayText.setBounds( 260, 10, 80, 20 ); delay = new JTextField( String.valueOf(ProcessController.DEFAULT_DELAY) ); delay.setBounds( 260, 30, 90, 20 ); delay.getDocument().addDocumentListener( new NumberDocumentListener( new NumberDocumentListener.Action() { @Override public void action(int val) { controller.setDelay( Integer.parseInt( delay.getText() ) ); } }, delay ) ); load = new NiceButton( "load" ); load.setLocation( 260, 60 ); load.setMnemonic( KeyEvent.VK_L ); load.setToolTipText( "Load a graph (alt + l)" ); load.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { JFileChooser chooser = new JFileChooser(); chooser.setFileFilter( new FileNameExtensionFilter("Json Graph", "json") ); chooser.showOpenDialog( frame ); if( chooser.getSelectedFile() != null ) { Reader r = new Reader( chooser.getSelectedFile().getAbsolutePath() ); LayeredGraphNode graph = r.readInputGraph(); SimpleNodePlacement.placeNodes( graph ); new MainView( graph ); } } }); save = new NiceButton( "save" ); save.setLocation( 310, 60 ); save.setMnemonic( KeyEvent.VK_S ); save.setToolTipText( "Save graph (alt + s)" ); save.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { JFileChooser chooser = new JFileChooser(); chooser.setFileFilter( new FileNameExtensionFilter("Json Graph", "json") ); chooser.showSaveDialog( frame ); if( chooser.getSelectedFile() != null ) { Writer w = new Writer( chooser.getSelectedFile().getAbsolutePath() ); w.writeOutputGraph( graph ); } } }); pseudoTree.setBackground(RenderHelper.BACKGROUND_COLOR); tree.setController( controller ); pseudoTree.setModel( new DefaultTreeModel( tree ) ); pseudoTree.setCellRenderer( new PseudoCodeRenderer() ); pseudoTree.setSelectionModel( null ); pseudoTree.setToolTipText(""); pseudoTree.putClientProperty("JTree.lineStyle", "Angled"); pseudoTree.addMouseListener( new MouseAdapter() { public void mousePressed(MouseEvent e) { TreePath selPath = pseudoTree.getPathForLocation(e.getX(), e.getY()); if( selPath != null && e.getClickCount() == 3 ) { ((PseudoCodeNode)selPath.getLastPathComponent()).setBreakPoint( !((PseudoCodeNode)selPath.getLastPathComponent()).hasBreakPoint() ); if( !pseudoTree.isExpanded( selPath ) ) { pseudoTree.collapsePath( selPath ); pseudoTree.expandPath( selPath ); } else { pseudoTree.expandPath( selPath ); pseudoTree.collapsePath( selPath ); } pseudoTree.repaint(); frame.repaint(); } if( e.getButton() == MouseEvent.BUTTON3 ) { JPopupMenu menu = new JPopupMenu(); JMenu expandM = new JMenu( "expand ..." ); JMenuItem exAll = new JMenuItem( "all" ); exAll.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { for( int i = 0; i < pseudoTree.getRowCount(); i++ ) pseudoTree.expandRow( i ); } }); expandM.add( exAll ); JMenuItem exTop = new JMenuItem( "top level lines" ); exTop.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { for( int i = 0; i < pseudoTree.getRowCount(); i++ ) { if( pseudoTree.getPathForRow( i ).getPathCount() < 3 ) pseudoTree.expandRow( i ); } } }); expandM.add( exTop ); JMenuItem exSec = new JMenuItem( "second level lines" ); exSec.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { for( int i = 0; i < pseudoTree.getRowCount(); i++ ) { if( pseudoTree.getPathForRow( i ).getPathCount() < 4 ) pseudoTree.expandRow( i ); } } }); expandM.add( exSec ); JMenuItem exThi = new JMenuItem( "third level lines" ); exThi.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { for( int i = 0; i < pseudoTree.getRowCount(); i++ ) { if( pseudoTree.getPathForRow( i ).getPathCount() < 5 ) pseudoTree.expandRow( i ); } } }); expandM.add( exThi ); menu.add( expandM ); JMenu collapsM = new JMenu( "collapse ..." ); JMenuItem colAll = new JMenuItem( "all" ); colAll.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { for( int i = pseudoTree.getRowCount() - 1; i > 0; i-- ) pseudoTree.collapseRow( i ); } }); collapsM.add( colAll ); JMenuItem colTop = new JMenuItem( "top level lines" ); colTop.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { for( int i = pseudoTree.getRowCount() - 1; i > 0; i-- ) { if( pseudoTree.getPathForRow( i ).getPathCount() >= 2 ) pseudoTree.collapseRow( i ); } } }); collapsM.add( colTop ); JMenuItem colSec = new JMenuItem( "second level lines" ); colSec.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { for( int i = pseudoTree.getRowCount() - 1; i > 0; i-- ) { if( pseudoTree.getPathForRow( i ).getPathCount() >= 3 ) pseudoTree.collapseRow( i ); } } }); collapsM.add( colSec ); JMenuItem colThi = new JMenuItem( "third level lines" ); colThi.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { for( int i = pseudoTree.getRowCount() - 1; i > 0; i-- ) { if( pseudoTree.getPathForRow( i ).getPathCount() >= 4 ) pseudoTree.collapseRow( i ); } } }); collapsM.add( colThi ); menu.add( collapsM ); menu.show( e.getComponent(), e.getX(), e.getY() ); } } } ); pseudoTree.setRowHeight(15); ((PseudoCodeRenderer)pseudoTree.getCellRenderer()).setMemory( processor.getMemory()); JScrollPane treeView = new JScrollPane( pseudoTree ); PseudoCodeLines lineView = new PseudoCodeLines( pseudoTree ); treeView.setRowHeaderView( lineView ); treeView.setBounds( 10, 110, 390, 380 ); JTextArea debugText = new JTextArea(); debugText.setFont( RenderHelper.font ); debugText.setEditable( false ); debugText.setBackground( RenderHelper.BACKGROUND_COLOR ); debugText.setForeground( RenderHelper.FOREGROUND_COLOR ); JScrollPane debugView = new JScrollPane( debugText ); debugView.setBounds( treeView.getX(), treeView.getY() + 500, treeView.getWidth(), 250 ); frame.setSize( (int)graph.getWidth( LayoutType.LEFTMOST_UPPER ) * 2 + 450, (int)graph.getHeight( LayoutType.LEFTMOST_UPPER ) * 2 + 50 ); frame.setLocation( 100, 100 ); frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE ); frame.setVisible( true ); LegendView statusPanel = new LegendView(); statusPanel.setBorder(new BevelBorder(BevelBorder.LOWERED)); frame.add(statusPanel, BorderLayout.SOUTH); JLayeredPane layne = new JLayeredPane(); layne.setLayout( new BorderLayout() ); 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.LEFTMOST_UPPER ); NodeView topRight = createNodeView( graph, LayoutType.RIGHTMOST_UPPER ); NodeView bottomLeft = createNodeView( graph, LayoutType.LEFTMOST_LOWER ); NodeView bottomRight = createNodeView( graph, LayoutType.RIGHTMOST_LOWER ); pl.add( topLeft ); pl.add( topRight ); pl.add( bottomLeft ); pl.add( bottomRight ); NodeView combined = createNodeView( graph, LayoutType.COMBINED ); combined.setSize( 500, 500 ); layne.add( combined, 0 ); layne.add( pl, 1 ); JSplitPane spane = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT ); spane.setLeftComponent( layne ); spane.setResizeWeight(0.5); JPanel menue = new JPanel(); menue.setLayout( null ); menue.setPreferredSize( new Dimension( 410, 500 ) ); menue.setMinimumSize( new Dimension( 410, 300 ) ); 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( stepBackwardInto ); menue.add( stepBackwardOut ); menue.add( runBackward ); menue.add( randomGraph ); menue.add( save ); menue.add( load ); menue.add( options ); JSplitPane spane2 = new JSplitPane( JSplitPane.VERTICAL_SPLIT ); spane2.setBounds( 10, 110, 390, 650 ); spane2.setTopComponent( treeView ); spane2.setBottomComponent( debugView ); spane2.setDividerLocation( 390 ); spane2.setResizeWeight(0.5); menue.add( spane2 ); spane.setRightComponent( menue); spane.setContinuousLayout( true ); spane.setDividerLocation( frame.getWidth() - 430 ); spane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { frame.getComponentListeners()[ 0 ].componentResized( null ); } }); frame.add( spane ); frame.revalidate(); frame.repaint(); Stage old = algorithm.getAlgorithmState(); frame.addComponentListener(new ComponentAdapter() { public void componentResized(ComponentEvent evt) { menue.setSize( menue.getWidth(), layne.getHeight() ); spane2.setSize( menue.getWidth() - 20, menue.getHeight() - 120 ); if( graph.getColor( null ) == null ) { grout.setHgap( 10 ); grout.setVgap( 10 ); combined.setVisible( false ); } else { grout.setHgap( layne.getWidth() / 3 ); grout.setVgap( layne.getHeight() / 3 ); combined.setVisible( true ); combined.doLayout(); } combined.setSize( layne.getWidth() / 3, layne.getHeight() / 3 ); combined.setLocation( layne.getWidth() / 3, layne.getHeight() / 3 ); debugText.setText( processor.getDebugOutput().trim() ); layne.remove( pl ); layne.add( pl, 1 ); if( optionsDialog != null && optionsDialog.getLayerDisplayOption() == 1 && old != algorithm.getAlgorithmState() ) { pl.remove( topLeft ); pl.remove( topRight ); pl.remove( bottomLeft ); pl.remove( bottomRight ); pl.remove( combined ); switch( algorithm.getAlgorithmState() ) { case CONFLICT_DETECTION: pl.add( topLeft ); break; case LEFTMOST_UPPER: pl.add( topLeft ); break; case RIGHTMOST_UPPER: pl.add( topRight ); break; case LEFTMOST_LOWER: pl.add( bottomLeft ); break; case RIGHTMOST_LOWER: pl.add( bottomRight ); break; case COMBINE: pl.add( combined ); break; default: assert false; break; } pl.revalidate(); } treeView.revalidate(); frame.repaint(); } }); frame.setSize( frame.getWidth() + 1, frame.getHeight() ); frame.setSize( frame.getWidth() - 1, frame.getHeight() ); if( frame.getHeight() < (int)graph.getHeight( LayoutType.LEFTMOST_UPPER ) * 2 + 50 ) { double factor = (graph.getHeight( LayoutType.LEFTMOST_UPPER ) * 2) / (frame.getHeight()-50); frame.setSize( (int)((frame.getWidth() - 450) / factor) + 450, frame.getHeight() ); spane.setDividerLocation( frame.getWidth() - 430 ); } optionsDialog = new OptionsDialog(); optionsDialog.addActionListener( new ActionListener() { @Override public void actionPerformed(ActionEvent e) { controller.setStepOption( optionsDialog.getRunStepsOption() ); RenderHelper.font = new Font( "Monospaced", Font.PLAIN, optionsDialog.getFontSize() ); debugText.setFont( RenderHelper.font ); pseudoTree.setFont( RenderHelper.font ); pseudoTree.setRowHeight( (int)(15.0/12 * optionsDialog.getFontSize() ) ); pl.remove( topLeft ); pl.remove( topRight ); pl.remove( bottomLeft ); pl.remove( bottomRight ); pl.remove( combined ); layne.remove( combined ); if( optionsDialog.getLayerDisplayOption() == 0) { pl.setLayout( grout ); pl.add( topLeft ); pl.add( topRight ); pl.add( bottomLeft ); pl.add( bottomRight ); layne.add( combined, 0 ); } else { pl.setLayout( new BorderLayout() ); switch( algorithm.getAlgorithmState() ) { case CONFLICT_DETECTION: pl.add( topLeft ); break; case LEFTMOST_UPPER: pl.add( topLeft ); break; case RIGHTMOST_UPPER: pl.add( topRight ); break; case LEFTMOST_LOWER: pl.add( bottomLeft ); break; case RIGHTMOST_LOWER: pl.add( bottomRight ); break; case COMBINE: pl.add( combined ); break; default: assert false; break; } } pl.revalidate(); layne.revalidate(); for( ComponentListener l : frame.getComponentListeners() ) l.componentResized( new ComponentEvent( frame, 0 ) ); } }); processor.start(); // start running the algorithm } private NodeView createNodeView( LayeredGraphNode gNode, LayoutType lt ) { NodeView graphView = new NodeView( gNode, lt, frame ); ((LayeredNode)gNode).setView( graphView, 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; } }