Browse Source

Merge branch 'master' of https://koljastrohm-games.com:3000/GraphDrawer/NodePlacementAnimation

Kolja Strohm 6 years ago
parent
commit
6d154ec95a

+ 3 - 2
doc/chapter/1introduction.tex

@@ -9,5 +9,6 @@ After each step the current progress of the algorithm is displayed visually.
 In chapter~\ref{ch:architecture} we provide an overview over the \appname 's internal architecture while chapter~\ref{ch:ui} presents and explains the graphical user interface.
 To provide an overview of what is going on, chapter~\ref{ch:progress} lists features and their degree of completion.
 
-\appname is currently a work in progress so keep in mind that any of the here presented screenshot, diagram or other information may be slightly outdated\footnote{even this one}.
-Also note that some pdf viewers have problems with vector graphics exported from visual paradigm, so if you feel like there is a missing line in a class or component diagram, you are wrong.
+\appname\ is currently a work in progress so keep in mind that any of the here presented screenshot, diagram or other information may be slightly outdated\footnote{even this one}.
+Also note that some PDF viewers have problems with vector graphics exported from Visual Paradigm, so if you feel like there is a missing line in a class or component diagram, you are wrong.
+You may want to use Internet Explorer 11, where this bug does not exist.

+ 36 - 23
doc/chapter/2architecture.tex

@@ -6,16 +6,16 @@ The following assumptions are made for the implementation of the node placement
     \item There are no labels.
     \item There are no cross-hierarchy edges.
     \item No edges over multiple layers (the previous phases should have added dummy nodes).
-    \item Graphs are connected (maybe we will get rid of this assumption later, see~\ref{ch:progress}).
+    \item Graphs are connected (maybe we will get rid of this assumption later, see chapter~\ref{ch:progress}).
 \end{itemize}
 
 
 \section{Overview}\label{sec:components}
 The \code{main} package contains an executable class \code{Main}.
-This classes main method creates a graph or reads it from a file using the \code{graph.io} package and then creates a MainView.
+This classes main method reads a graph from a file using the \code{graph.io} package and then creates a MainView.
 The view then instantiates a \code{BKNodePlacement} algorithm and runs it.
 The \code{BKNodePlacement} repeatedly asks the \code{AnimationController} if a step should be done (this is further explained in section~\ref{sec:theActualAlgorithm}).
-For each step it uses works with \code{LayeredGraphNode}s and \code{LayeredGraphEdge}s.
+It uses \code{LayeredGraphNode}s and \code{LayeredGraphEdge}s.
 Meanwhile the view displays the same \code{LayeredGraphNode}s and \code{LayeredGraphEdge}s on the screen.
 
 Figure~\ref{fig:components} contains a component diagram that illustrates these dependencies of the packages.
@@ -29,7 +29,7 @@ Figure~\ref{fig:components} contains a component diagram that illustrates these
 
 
 \section{Input File Format}\label{sec:inputFileFormat}
-The input to \appname is a JSON file.
+The input to \appname\ is a JSON file.
 An example is displayed in figure~\ref{fig:json-example}.
 The structure is as follows:
 \begin{itemize}
@@ -56,7 +56,7 @@ The internal representation of graphs is further explained in the section~\ref{s
     The node can be higher if it contains other nodes that need more space.
     If the whole layout is too large, it is resized, such that all nodes are proportionately shrunk: In that case the minimum height can be exceeded after the shrinking.
     Default 40.\\\hline
-    dummy & boolean & yes & Iff this is explicitly set to yes, then the node is a dummy node. \\\hline
+    dummy & boolean & yes & Iff this is explicitly set to true, then the node is a dummy node. \\\hline
     layers & < < node > > & yes & The layers of nodes inside this node (Hierarchy). \\\hline
     edges & < edge > & yes & The edges between nodes whose parent node is this node. Also see section~\ref{sec:assumptions}. \\\hline
     \caption[Node Attributes]{Node Attributes. < \emph{element type} > is a list.}
@@ -102,27 +102,33 @@ The internal representation of graphs is further explained in the section~\ref{s
 
 \section{Internal graph representation, \code{graph}}\label{sec:graph}
 One feature that is important to us, is to be able to work with hierarchical graphs (cf.\ chapter~\ref{ch:progress}).
-Therefore a node not only has edges to other nodes, but also it can contain other nodes and edges.
+Therefore a node can contain other nodes and edges.
 So far this is similar to what we described in section~\ref{sec:inputFileFormat}.
 Additionally, there are multiple attributes that are used during the computation or as output variables.
 \begin{itemize}
+    \item The \member{parent} of a node is the node that contains it in the hierarchy.
+    \item \member{dummy} specifies whether this node is a dummy node.
+    \item \member{name} is the name of the node.
     \item The attributes \member{shift}, \member{sink},  \member{root} and  \member{align} correspond to the variables used by Brandes and Köpf~\cite{brandes_fast_2001}.
     They are summarized in table~\ref{table:bk-variables}.
-    \item The \member{parent} of a node is the node that contains it in the hierarchy.
-    \item The attributes \member{x} and \member{y} are the coordinates of the node relative to its \code{parent}.
+    \item The attribute \member{xUndef} determines whether the x coordinate of the node has already been assigned a value.
+    \item The attributes \member{x} and \member{y} are the coordinates of the node relative to its \member{parent}.
     \item The attributes \member{w} and \member{h} are the width and height of the node.
     \item The attributes \member{color} is the color in which the node is displayed.
-    \item The attribute \member{xUndef} determines whether the x coordinate of the node has already been assigned a value.
     \item The attribute \member{selected} is used to highlight the node that is currently active in each layout.
 \end{itemize}
-The last five bullet points are available for each of the four extremal layouts and for the combined layout.
+The last six bullet points are available separately for each of the four extremal layouts.
+The last four bullet points are also separately available for the combined layout.
 
-Similarly, edges have additional attributes:
+Similarly, edges have the following attributes in addition to those given through the JSON format:
 \begin{itemize}
-    \item \member{dummyNode} specifies whether they are dummy edges.
-    \item \member{conflicted} corresponds to the variable used by Brandes and Köpf~\cite{brandes_fast_2001} and indicates that this edge won't be drawn vertically.
+    \item \member{dummyEdge} specifies whether they are edges between two dummy nodes.
     \item \member{bindPoints} is a list of bend points for the edge, including the beginning and end point of the edge.
+    \item \member{reversed} specifies if this edge was reversed earlier (not used by \appname).
+    \item \member{graph} is the node that contains the edges (hierarchy).
+    \item \member{conflicted} corresponds to the variable used by Brandes and Köpf~\cite{brandes_fast_2001} and indicates that this edge won't be drawn vertically.
 \end{itemize}
+The last bullet point is available separately for each of the four extremal layouts and for the combined layout.
 
 A class diagram of the package \code{graph} is displayed in figure~\ref{fig:graph}.
 
@@ -137,13 +143,15 @@ A class diagram of the package \code{graph} is displayed in figure~\ref{fig:grap
     \begin{longtable}{|l|p{10cm}|}
         \hline
         Attribute & Explanation \\\hline\hline
-        root & The root node of the block of this node.
+        \member{root} & The root node of the block of this node.
         Unique for all nodes in the same block. \\\hline
-        sink & The topmost sink in the block graph that can be reached from the block that this node belongs to.
+        \member{sink} & The topmost sink in the block graph that can be reached from the block that this node belongs to.
         Only used for nodes that are the root of a block.
         Unique for all nodes in the same class. \\\hline
-        shift & The shift of the class that this node belongs to.
+        \member{shift} & The shift of the class that this node belongs to.
         Only used for nodes that are a sink of a class. \\\hline
+        \member{align} & The next node in the same block as this node.
+        The \member{align} of the last node in the block is the root node of the block again.\\\hline
     \end{longtable}
     \caption{Variables also used by Brandes and Köpf~\cite{brandes_fast_2001}}
     \label{table:bk-variables}
@@ -155,7 +163,7 @@ This section expects the reader to be familiar with the node placement algorithm
 We recommend section 3.2.1 of Carstens~\cite{carstens_node_2012} for a detailed explanation.
 
 A stage of the algorithm, interface \code{AlgorithmStage}, is an interval during which each step of the algorithm is performed in a similar way.
-Each time such a step is performed it returns whether the stage is already finished.
+Each time such a step is performed it returns whether the stage is already finished or a breakpoint has been reached.
 For example, a forward step in the stage of calculating one extremal layout, \code{ExtremalLayoutCalc}, consists of either a step of calculating the blocks, \code{BlockCalc}, or a step of compacting the layout, \code{Compaction}.
 All the stages are displayed in class diagram~\ref{fig:animation_and_bk}.
 
@@ -166,8 +174,8 @@ This works the following:
 \begin{enumerate}
     \item The \code{MainView} creates a node placement algorithm (only \code{BKNodePlacement} available).
     It sends an \code{AnimationController} as a parameter for the constructor.
-    \item The algorithm concurrently asks the \code{AnimationController} if it should do a forward or backward step.
-    \item The \code{AnimationController} waits until it knows which action to take (for example if the user pressed the right arrow key).
+    \item The algorithm concurrently asks the \code{AnimationController} if it should do a forward or backward step and if that is a \enquote{step into}, \enquote{step over} or \enquote{step out}.
+    \item The \code{AnimationController} waits until it knows which action to take (for example if the user pressed Alt + Right arrow key).
     Alternatively, if the animation is not paused, it waits until a specific delay has passed.
     Then it returns to the algorithm which step to take next.
     \item The algorithm potentially calls one the step methods of other stages while executing one step.
@@ -185,12 +193,17 @@ This works the following:
 This section only covers the software architecture regarding the views.
 For an explanation of what is actually displayed, see chapter~\ref{ch:ui}
 
-The distinguish two kinds of views:
 \begin{itemize}
-    \item The main window displays four regions for the different extremal layouts while also forwarding keyboard commands to the \code{AnimationController}.
-    For this we use a \code{JFrame} from the Swing library.
+    \item The main window displays a \code{lane} of the class \code{JLayeredPane} and a \code{menue} of the class \code{JPanel}.
+    The main window itself is a \code{JFrame} from the Swing library.
+    \item The \code{lane} display the current status of the graph.
+    \item The \code{menue} display \code{NiceButton}s and pseudocode.
     \item \code{EdgeView} and \code{NodeView} are \code{JPanel}s, which means they can be drawn onto the \code{JFrame}.
-    For this they have to know about which part of the graph and which layout they belong to.
+    For this they have to know about which part of the graph and which layout they belong to (some attributes).
+    \item A \code{NiceButton} is a \code{JButton} that has an image on it.
+    \item For rendering the pseudocode we use a \code{PseudoCodeRenderer} that is a \code{DefaultTreeCellRenderer}.
+    For example, it sets line numbers and highlights selected code lines.
+    \item A \code{RenderHelper} that contains some additional utility functions for the views.
 \end{itemize}
 A class diagram of the packages \code{view} and \code{main} is displayed in figure~\ref{fig:view}.
 

+ 8 - 7
doc/chapter/3ui.tex

@@ -1,7 +1,7 @@
 Note that since the application is still under construction, so not all screenshots may be up to date.
 
 \section{Graphical presentation of the running algorithm}\label{sec:graphicalPresentationOfTheRunningAlgorithm}
-A first sketch of how we want \appname to look is shown in figure~\ref{fig:sketch}.
+A first sketch of how we want \appname\ to look is shown in figure~\ref{fig:sketch}.
 The current development status is displayed in figure~\ref{fig:full-application-example}.
 Another example graph and an explanation of the shapes and colors is provided in figure~\ref{fig:example}.
 Figure~\ref{fig:originalpapergraph} compares our results to those of Brandes and Köpf~\cite{brandes_fast_2001}.
@@ -10,8 +10,8 @@ Figure~\ref{fig:originalpapergraph} compares our results to those of Brandes and
     \centering
     \includegraphics[width=\linewidth]{img/skizze}
     \caption[First sketch of the planned layout]{A first sketch of the planned layout, created with Microsoft Paint.
-    The buttons are (first row, from left to right): step over, step into, step out, run, pause, debug; and (second row, from left to right): step back, step back out, run backwards.
-    The actions corresponding to the buttons are the same as described for the keyboard input in table~\ref{table:keys}, at least for the features that are already implemented.
+    The buttons are (first row, from left to right): step over, step into, step out, run, pause, debug; and (second row, from left to right): step back over, step back into, step back out, run backwards, load graph, save graph, generate random graph.
+    The actions corresponding to the buttons are the same as described for the keyboard input in table~\ref{table:keys}, at least for the features that are already implemented (all of them).
     The left four rectangles show the progress of the four extremal layouts.
     The right rectangle shows pseudocode of the algorithm and the position of the current step.}
     \label{fig:sketch}
@@ -62,10 +62,10 @@ Figure~\ref{fig:originalpapergraph} compares our results to those of Brandes and
 \section{User interface}\label{sec:userInterface}
 Currently the two main ways to interact with the application are keyboard events and graphical button-clicking.
 The possible keyboard inputs are listed in table~\ref{table:keys}.
-These can also be used by clicking on one of the buttons displayed in figure~\ref{fig:sketch}.
+These can also be used by clicking on one of the buttons displayed in figures~\ref{fig:sketch} and~\ref{fig:full-application-example}.
 
 %\begin{table}[htp]
-    \begin{longtable}{|l|p{10cm}|}
+    \begin{longtable}{|l|p{12cm}|}
         \hline
         Key & Action \\\hline\hline
         Alt + Left arrow key & Perform one forward step of the algorithm, \enquote{step into}. \\\hline
@@ -80,8 +80,9 @@ These can also be used by clicking on one of the buttons displayed in figure~\re
         Alt + G & Generate a random graph (opens dialog window~\ref{fig:random-graph-dialog}). \\\hline
         Alt + S & Save the current graph to a file (opens a dialog window). \\\hline
         Alt + L & Load a graph from a file (opens a dialog window). \\\hline
-        Alt + D & Show a debug table (in a new window). \\\hline
-        \caption[Overview of the available keyboard commands]{Overview of the available keyboard commands. For the planned commands, see~\ref{ch:progress}.}
+        Alt + D & Show a debug table (opens window~\ref{fig:debug-table}). \\\hline
+        \caption[Overview of the available keyboard commands]{Overview of the available keyboard commands.
+        The lazy user might not want to learn these by rote but instead use the buttons displayed in figures~\ref{fig:sketch} and~\ref{fig:full-application-example}.}
         \label{table:keys}
     \end{longtable}
 %\end{table}

+ 2 - 2
doc/chapter/4progress.tex

@@ -24,7 +24,7 @@ The following features are either planned (\planned), under construction (\progr
         \item[\done] Drawing the edges just as plain straight lines.
         \item[\done] Drawing the conflicted edges in a different color.
         \item[\done] Drawing the four extremal layouts and the combined layout separately.
-        \item[\planned] Drawing the edges of the block graph (yet another, low priority).
+        \item[\planned] Drawing the edges of the block graph (yet another color, low priority).
         \item[\done] Showing pseudocode and the position where the algorithm currently is.
         \begin{itemize}
             \item[\done] Clicking on the pseudocode to set a breakpoint at (not \reserved{goto}) a specific location.
@@ -42,6 +42,6 @@ The following features are either planned (\planned), under construction (\progr
     \item[\done] Working with hierarchical graphs.
     \item[\done] Scaling the display with the (adjustable) window size.
     \item[\planned] Working with disconnected graphs (cf.\ section~\ref{sec:assumptions}), either by modifying the algorithm or by processing the connected components one by one (low priority).
-    \item[\planned] Creating ElkNode~\cite{noauthor_elk:_2018} objects from LayeredNode (\ref{sec:graph}) objects.
+    \item[\done] Creating ElkNode~\cite{noauthor_elk:_2018} objects from LayeredNode (\ref{sec:graph}) objects.
     \item[\planned] Creating LayeredNode (\ref{sec:graph}) objects from ElkNode~\cite{noauthor_elk:_2018} objects (low priority).
 \end{itemize}

+ 1 - 0
doc/chapter/6contributors.tex

@@ -25,6 +25,7 @@
         Localization Producer & Eren Bora Yilmaz \\
         \rowcolor{gray!25}
         Manual Code Formatting & Kolja Samuel Strohm \\
+        Black-Box Testing & Eren Bora Yilmaz \\
         \\\\\rowcolor{gray!25}
 		Special Thanks & Jens Burmeister \\\\
 	\end{longtable}

+ 6 - 0
doc/chapter/appendix.tex

@@ -3,4 +3,10 @@
     \includegraphics{img/random-graph-dialog}
     \caption[Random graph dialog]{Dialog for generating random graphs.}
     \label{fig:random-graph-dialog}
+\end{figure}
+\begin{figure}[htp]
+    \centering
+    \includegraphics[width=\linewidth]{img/debug-table}
+    \caption[Debug Table]{An example for a debug table. The graph used is the same as in figure~\ref{fig:example}}
+    \label{fig:debug-table}
 \end{figure}

BIN
doc/img/debug-table.png


+ 6 - 6
src/animation/Action.java

@@ -9,10 +9,10 @@ package animation;
  *
  */
 public enum Action {
-	FORWARD,
-	FORWARD_OVER,
-	FORWARD_OUT,
-	BACKWARD,
-	BACKWARD_OVER,
-	BACKWARD_OUT
+    FORWARD,
+    FORWARD_OVER,
+    FORWARD_OUT,
+    BACKWARD,
+    BACKWARD_OVER,
+    BACKWARD_OUT
 }

+ 18 - 18
src/animation/AlgorithmStage.java

@@ -17,22 +17,22 @@ public interface AlgorithmStage {
      * @author kolja
      *
      */
-	public static enum StageStatus
-	{
-		UNFINISHED,
-		BREAKPOINT,
-		FINISHED
-	}
-	
-	/**
-	 * perform one atomic step of the algorithm
-	 * @return whether the whole stage is finished.
+    public static enum StageStatus
+    {
+        UNFINISHED,
+        BREAKPOINT,
+        FINISHED
+    }
+
+    /**
+     * perform one atomic step of the algorithm
+     * @return whether the whole stage is finished.
      * For example if all steps are reverted, then {@code FINISHED} is returned.
-	 */
-	public StageStatus forwardStep();
-	
-	public StageStatus forwardStepOver();
-	
+     */
+    public StageStatus forwardStep();
+
+    public StageStatus forwardStepOver();
+
     public StageStatus forwardStepOut();
     
     /**
@@ -40,11 +40,11 @@ public interface AlgorithmStage {
      * @return whether the whole stage is finished in backwards direction. 
      * For example if all steps are reverted, then {@code FINISHED} is returned.
      */
-	public StageStatus backwardStep();
-	
+    public StageStatus backwardStep();
+
     public StageStatus backwardStepOver();
     
     public StageStatus backwardStepOut();
-	
+
     public PseudoCodeNode createPseudocodeTree( JTree tree );
 }

+ 41 - 39
src/animation/AnimatedAlgorithm.java

@@ -11,19 +11,19 @@ import graph.LayeredGraphNode;
 
 public abstract class AnimatedAlgorithm extends Thread implements AlgorithmStage {
 
-	protected AnimationController ac;
-	protected LayeredGraphNode graph;
-	private JFrame view;
-	
-	public AnimatedAlgorithm( AnimationController controller, LayeredGraphNode graph, JFrame view )
-	{
-		this.ac = controller;
-		this.graph = graph;
-		this.view = view;
-	}
-	
-	private void update()
-	{
+    protected AnimationController ac;
+    protected LayeredGraphNode graph;
+    private JFrame view;
+
+    public AnimatedAlgorithm( AnimationController controller, LayeredGraphNode graph, JFrame view )
+    {
+        this.ac = controller;
+        this.graph = graph;
+        this.view = view;
+    }
+
+    private void update()
+    {
         SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                 view.repaint();
@@ -33,20 +33,20 @@ public abstract class AnimatedAlgorithm extends Thread implements AlgorithmStage
                 }
             }
         });
-	}
-	
-	@Override
-	public void run()
-	{
-		while( true ) // if this loop would end we could not undo steps any more
-		{
-			try {
-				switch( ac.getNextAction() )
-				{
-				case FORWARD:
-					forwardStep();
-					update();
-					break;
+    }
+
+    @Override
+    public void run()
+    {
+        while( true ) // if this loop would end we could not undo steps any more
+        {
+            try {
+                switch( ac.getNextAction() )
+                {
+                case FORWARD:
+                    forwardStep();
+                    update();
+                    break;
                 case FORWARD_OUT:
                     forwardStepOut();
                     graph.unselectGraph();
@@ -57,10 +57,10 @@ public abstract class AnimatedAlgorithm extends Thread implements AlgorithmStage
                     graph.unselectGraph();
                     update();
                     break;
-				case BACKWARD:
-					backwardStep();
+                case BACKWARD:
+                    backwardStep();
                     update();
-					break;
+                    break;
                 case BACKWARD_OUT:
                     backwardStepOut();
                     graph.unselectGraph();
@@ -73,14 +73,16 @@ public abstract class AnimatedAlgorithm extends Thread implements AlgorithmStage
                     break;
                 default:
                     break;
-				}
-			} catch (InterruptedException e) {
-				e.printStackTrace();
-				return;
-			}
-			
-		}
-	}
-	
+                }
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+                return;
+            }
+
+        }
+    }
+    /**
+     * creates a node in the pseudo code tree
+     */
     public abstract PseudoCodeNode createPseudocodeTree( JTree tree );
 }

+ 60 - 60
src/animation/AnimationController.java

@@ -1,64 +1,64 @@
 package animation;
 
 public class AnimationController {
-	
-	private Action next;
-	private boolean continuous;
-	private long lastTime;
-	private long timeBetween;
-	
-	public AnimationController()
-	{
-		next = null;
-		continuous = false;
-		lastTime = 0;
-		timeBetween = 0;
-	}
-	
-	public Action getNextAction() throws InterruptedException
-	{
-		long old = lastTime;
-		Action ret = null;
-		synchronized( this ) {
-			while( next == null )
-				wait();
-			lastTime = System.currentTimeMillis();
-			ret = next;
-		}
-		if( !continuous )
-			next = null;
-		else
-		{
-			if( lastTime - old < timeBetween )
-			{
-				Thread.sleep( timeBetween - ( lastTime - old ) );
-				System.out.println( "sleep: " + ( timeBetween - ( lastTime - old ) ) );
-				lastTime = System.currentTimeMillis();
-			}
-		}
-		return ret;
-	}
-	
-	public void setContinuous( boolean c )
-	{
-		this.continuous = c;
-	}
-	
-	public void setTimeBetween( long between )
-	{
-		timeBetween = between;
-	}
-	
-	public void setNextAction( Action a )
-	{
-		next = a;
-		synchronized( this ) {
-			notify();
-		}
-	}
-	
-	public boolean isContinuous()
-	{
-		return continuous;
-	}
+
+    private Action next;
+    private boolean continuous;
+    private long lastTime;
+    private long timeBetween;
+
+    public AnimationController()
+    {
+        next = null;
+        continuous = false;
+        lastTime = 0;
+        timeBetween = 0;
+    }
+
+    public Action getNextAction() throws InterruptedException
+    {
+        long old = lastTime;
+        Action ret = null;
+        synchronized( this ) {
+            while( next == null )
+                wait();
+            lastTime = System.currentTimeMillis();
+            ret = next;
+        }
+        if( !continuous )
+            next = null;
+        else
+        {
+            if( lastTime - old < timeBetween )
+            {
+                Thread.sleep( timeBetween - ( lastTime - old ) );
+                System.out.println( "sleep: " + ( timeBetween - ( lastTime - old ) ) );
+                lastTime = System.currentTimeMillis();
+            }
+        }
+        return ret;
+    }
+
+    public void setContinuous( boolean c )
+    {
+        this.continuous = c;
+    }
+
+    public void setTimeBetween( long between )
+    {
+        timeBetween = between;
+    }
+
+    public void setNextAction( Action a )
+    {
+        next = a;
+        synchronized( this ) {
+            notify();
+        }
+    }
+
+    public boolean isContinuous()
+    {
+        return continuous;
+    }
 }

+ 1 - 1
src/animation/BackwardAction.java

@@ -10,5 +10,5 @@ public interface BackwardAction {
     /**
      * Undo another action.
      */
-	public void reverse();
+    public void reverse();
 }

+ 48 - 48
src/bk/BKNodePlacement.java

@@ -17,24 +17,24 @@ import graph.LayeredGraphNode;
  */
 public class BKNodePlacement extends AnimatedAlgorithm {
 
-	/*
-	 * Private data structures to store the process of the algorithm
-	 */
-	
-	private enum State
-	{
-		CONFLICTS,
-		LAYOUT1,
-		LAYOUT2,
-		LAYOUT3,
-		LAYOUT4,
-		COMBINE
-	}
-	
-	private ConflictDetection conftion;
-	private State state;
-	private ExtremalLayoutCalc layouts[];
-	private Combine combine;
+    /*
+     * Private data structures to store the process of the algorithm
+     */
+
+    private enum State
+    {
+        CONFLICTS,
+        LAYOUT1,
+        LAYOUT2,
+        LAYOUT3,
+        LAYOUT4,
+        COMBINE
+    }
+
+    private ConflictDetection conftion;
+    private State state;
+    private ExtremalLayoutCalc layouts[];
+    private Combine combine;
     private PseudoCodeNode conflictsNode; 
     private PseudoCodeNode layout1Node;
     private PseudoCodeNode layout2Node;
@@ -42,35 +42,35 @@ public class BKNodePlacement extends AnimatedAlgorithm {
     private PseudoCodeNode layout4Node;
     private PseudoCodeNode combineNode;
     private boolean inside;
-	
-	public BKNodePlacement(AnimationController controller, LayeredGraphNode graph, JFrame view) {
-		super(controller, graph, view);
-		state = State.CONFLICTS;
-		conftion = new ConflictDetection( graph );
-		layouts = new ExtremalLayoutCalc[ 4 ];
-		layouts[ 0 ] = new ExtremalLayoutCalc( ExtremalLayoutCalc.LayoutType.TOP_BOTTOM_LEFT, graph );
-		layouts[ 1 ] = new ExtremalLayoutCalc( ExtremalLayoutCalc.LayoutType.TOP_BOTTOM_RIGHT, graph );
-		layouts[ 2 ] = new ExtremalLayoutCalc( ExtremalLayoutCalc.LayoutType.BOTTOM_TOP_LEFT, graph );
-		layouts[ 3 ] = new ExtremalLayoutCalc( ExtremalLayoutCalc.LayoutType.BOTTOM_TOP_RIGHT, graph );
-		combine = new Combine( graph );
-		inside = false;
-	}
 
-	@Override
-	public StageStatus forwardStep() {
-		return forward( "forwardStep" );
-	}
+    public BKNodePlacement(AnimationController controller, LayeredGraphNode graph, JFrame view) {
+        super(controller, graph, view);
+        state = State.CONFLICTS;
+        conftion = new ConflictDetection( graph );
+        layouts = new ExtremalLayoutCalc[ 4 ];
+        layouts[ 0 ] = new ExtremalLayoutCalc( ExtremalLayoutCalc.LayoutType.TOP_BOTTOM_LEFT, graph );
+        layouts[ 1 ] = new ExtremalLayoutCalc( ExtremalLayoutCalc.LayoutType.TOP_BOTTOM_RIGHT, graph );
+        layouts[ 2 ] = new ExtremalLayoutCalc( ExtremalLayoutCalc.LayoutType.BOTTOM_TOP_LEFT, graph );
+        layouts[ 3 ] = new ExtremalLayoutCalc( ExtremalLayoutCalc.LayoutType.BOTTOM_TOP_RIGHT, graph );
+        combine = new Combine( graph );
+        inside = false;
+    }
+
+    @Override
+    public StageStatus forwardStep() {
+        return forward( "forwardStep" );
+    }
 
-	@Override
-	public StageStatus backwardStep() {
-	    return backward( "backwardStep" );
-	}
-	
-	@Override
-	public PseudoCodeNode createPseudocodeTree( JTree tree )
-	{
-	    PseudoCodeNode root = new PseudoCodeNode( "BK Node Placement Algorithm", tree );
-	    root.setSelected( true );
+    @Override
+    public StageStatus backwardStep() {
+        return backward( "backwardStep" );
+    }
+
+    @Override
+    public PseudoCodeNode createPseudocodeTree( JTree tree )
+    {
+        PseudoCodeNode root = new PseudoCodeNode( "BK Node Placement Algorithm", tree );
+        root.setSelected( true );
         conflictsNode = conftion.createPseudocodeTree( tree );
         layout1Node = layouts[ 0 ].createPseudocodeTree( tree );
         layout2Node = layouts[ 1 ].createPseudocodeTree( tree );
@@ -84,7 +84,7 @@ public class BKNodePlacement extends AnimatedAlgorithm {
         root.add( layout4Node );
         root.add( combineNode );
         return root;
-	}
+    }
 
     @Override
     public StageStatus forwardStepOver() {
@@ -147,8 +147,8 @@ public class BKNodePlacement extends AnimatedAlgorithm {
             switch( state )
             {
             case CONFLICTS:
-            	if( !conflictsNode.isSelected() )
-            		breakpoint |= !conflictsNode.setSelected( true );
+                if( !conflictsNode.isSelected() )
+                    breakpoint |= !conflictsNode.setSelected( true );
                 switch( (StageStatus)(ConflictDetection.class.getMethod( fName ).invoke( conftion ) ) )
                 {
                 case FINISHED:

+ 332 - 203
src/bk/BlockCalc.java

@@ -20,61 +20,70 @@ import graph.LayeredGraphNode;
  */
 public class BlockCalc implements AlgorithmStage {
 
-	private int layerIndex;
-	private int nodeIndex;
-	private int r;
-	private LayeredGraphNode graph;
-	private ArrayList< ArrayList< ExtremalLayoutCalc > > subgraphAlgs;
-	private ArrayList< BackwardAction > backwards; // TODO: evtl richtigen "Stack" benutzen
-	private LayoutType layout;
-	private PseudoCodeNode loopNode;
-	int step;
-	
-	public BlockCalc( LayeredGraphNode graph, LayoutType layout )
-	{
-	    this.layout = layout;
-		step = 0;
-		this.graph = graph;
-		layerIndex = 0;
-		nodeIndex = 0;
-		r = 0;
-		subgraphAlgs = new ArrayList<>();
-		for( ArrayList<LayeredGraphNode> l : graph.getContainedLayers() )
-		{
-			ArrayList< ExtremalLayoutCalc > algs = new ArrayList<>();
-			for( int i = 0; i < l.size(); i++ )
-				algs.add( null );
-			subgraphAlgs.add( algs );
-		}
-		backwards = new ArrayList<>();
-	}
-	
-	private int calcLayerIndex()
-	{
+    private int layerIndex;
+    private int nodeIndex;
+    private int r;
+    private LayeredGraphNode graph;
+    private ArrayList< ArrayList< PseudoCodeNode > > subgraphNodes;
+    private ArrayList< ArrayList< ExtremalLayoutCalc > > subgraphAlgs;
+    private ArrayList< BackwardAction > backwards; // TODO: evtl richtigen "Stack" benutzen
+    private LayoutType layout;
+    private PseudoCodeNode loopNode;
+    private boolean inside;
+    int step;
+
+    public BlockCalc( LayeredGraphNode graph, LayoutType layout )
+    {
+        this.layout = layout;
+        step = 0;
+        this.graph = graph;
+        layerIndex = 0;
+        nodeIndex = 0;
+        r = 0;
+        subgraphNodes = new ArrayList<>();
+        subgraphAlgs = new ArrayList<>();
+        for( ArrayList<LayeredGraphNode> l : graph.getContainedLayers() )
+        {
+            ArrayList< PseudoCodeNode > nodes = new ArrayList<>();
+            ArrayList< ExtremalLayoutCalc > algs = new ArrayList<>();
+            for( int i = 0; i < l.size(); i++ )
+            {
+                nodes.add( null );
+                algs.add( null );
+            }
+            subgraphAlgs.add( algs );
+            subgraphNodes.add( nodes );
+        }
+        inside = false;
+        backwards = new ArrayList<>();
+    }
+
+    private int calcLayerIndex()
+    {
         if( layout == LayoutType.TOP_BOTTOM_LEFT || layout == LayoutType.TOP_BOTTOM_RIGHT )
-	        return layerIndex;
+            return layerIndex;
         if( layout == LayoutType.BOTTOM_TOP_LEFT || layout == LayoutType.BOTTOM_TOP_RIGHT )
-	        return graph.getContainedLayers().size() - layerIndex - 1;
-	    return -1;
-	}
-	
-	private int calcBeforeLayerIndex()
-	{
+            return graph.getContainedLayers().size() - layerIndex - 1;
+        return -1;
+    }
+
+    private int calcBeforeLayerIndex()
+    {
         if( layout == LayoutType.TOP_BOTTOM_LEFT || layout == LayoutType.TOP_BOTTOM_RIGHT )
             return layerIndex - 1;
         if( layout == LayoutType.BOTTOM_TOP_LEFT || layout == LayoutType.BOTTOM_TOP_RIGHT )
             return graph.getContainedLayers().size() - layerIndex;
         return -1;
-	}
-	
-	private int calcNodeIndex( int index )
-	{
+    }
+
+    private int calcNodeIndex( int index )
+    {
         if( layout == LayoutType.TOP_BOTTOM_LEFT || layout == LayoutType.BOTTOM_TOP_LEFT )
             return index;
         if( layout == LayoutType.TOP_BOTTOM_RIGHT || layout == LayoutType.BOTTOM_TOP_RIGHT )
             return graph.getContainedLayers().get( calcLayerIndex() ).size() - index - 1;
         return index;
-	}
+    }
     
     private int calcBeforeLayerNodeIndex( int index )
     {
@@ -84,209 +93,329 @@ public class BlockCalc implements AlgorithmStage {
             return graph.getContainedLayers().get( calcBeforeLayerIndex() ).size() - index - 1;
         return index;
     }
-	
-	@Override
-	public StageStatus forwardStep() {
-		LayeredGraphNode current = graph.getContainedLayers().get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) );
-		current.setSelected( layout );
-		if( current.getContainedNodes().size() > 0 )
-		{
-			if( subgraphAlgs.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ) == null )
-			{
-			    ExtremalLayoutCalc extcalc = new ExtremalLayoutCalc( layout, current );
-			    loopNode.add( extcalc.createPseudocodeTree( loopNode.getTree() ) );
-				subgraphAlgs.get( calcLayerIndex() ).set( calcNodeIndex( nodeIndex ), extcalc );
-			}
-			switch( subgraphAlgs.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).forwardStep() )
-			{
+
+    @Override
+    public StageStatus forwardStep() {
+        LayeredGraphNode current = graph.getContainedLayers().get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) );
+        current.setSelected( layout );
+        if( current.getContainedNodes().size() > 0 )
+        {
+            inside = true;
+            boolean breakpoint = false;
+            if( !subgraphNodes.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).isSelected() )
+                breakpoint |= !subgraphNodes.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).setSelected( true );
+            switch( subgraphAlgs.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).forwardStep() )
+            {
             case BREAKPOINT:
                 return StageStatus.BREAKPOINT;
-			case UNFINISHED:
-				return StageStatus.UNFINISHED;
-            default:
+            case UNFINISHED:
+                if( breakpoint )
+                    return StageStatus.BREAKPOINT;
+                return StageStatus.UNFINISHED;
+            case FINISHED:
+                inside = false;
+                subgraphNodes.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).setSelected( false );
                 break;
-			}
-		}
-		ArrayList< LayeredGraphEdge > incommingEdges = null;
+            }
+        }
+        ArrayList< LayeredGraphEdge > incommingEdges = null;
         if( layout == LayoutType.TOP_BOTTOM_LEFT || layout == LayoutType.TOP_BOTTOM_RIGHT )
             incommingEdges = current.getSortedIncomingEdges();
         if( layout == LayoutType.BOTTOM_TOP_LEFT || layout == LayoutType.BOTTOM_TOP_RIGHT )
             incommingEdges = current.getSortedOutgoingEdges();
         if( layout == LayoutType.TOP_BOTTOM_RIGHT || layout == LayoutType.BOTTOM_TOP_RIGHT )
         Collections.reverse( incommingEdges );
-		if( incommingEdges.size() == 0 )
-		{
-			backwards.add( 0, () -> {
-				System.out.println( "Performing Empty Backwards Step..." );
-			});
-			return calcNextState();
-		}
-		int[] ms = {(incommingEdges.size() + 1) / 2, (int)( (incommingEdges.size() + 1) / 2.0 + 0.5 )};
-		boolean backwardsAdded = false;
-		for( int m : ms )
-		{
-		    if( current.getAlignedTo( layout ) == current )
-		    {
+        if( incommingEdges.size() == 0 )
+        {
+            backwards.add( 0, () -> {
+                System.out.println( "Performing Empty Backwards Step..." );
+            });
+            return calcNextState();
+        }
+        int[] ms = {(incommingEdges.size() + 1) / 2, (int)( (incommingEdges.size() + 1) / 2.0 + 0.5 )};
+        boolean backwardsAdded = false;
+        for( int m : ms )
+        {
+            if( current.getAlign( layout ) == current )
+            {
                 LayeredGraphNode u = null;
                 if( layout == LayoutType.TOP_BOTTOM_LEFT || layout == LayoutType.TOP_BOTTOM_RIGHT )
                     u = incommingEdges.get( m - 1 ).getSources().get( 0 );
                 if( layout == LayoutType.BOTTOM_TOP_LEFT || layout == LayoutType.BOTTOM_TOP_RIGHT )
                     u = incommingEdges.get( m - 1 ).getTargets().get( 0 );
-                ArrayList<LayeredGraphEdge> conflicts = incommingEdges.get( m - 1 ).calcConflictedEdges();
+                ArrayList<LayeredGraphEdge> conflicts = incommingEdges.get( m - 1 ).calcEdgeCrossings();
                 
-		        if( !incommingEdges.get( m - 1 ).isConflicted( layout ) && r < calcBeforeLayerNodeIndex( graph.getContainedLayers().get( calcBeforeLayerIndex() ).indexOf( u ) ) + 1 )
-		        {
-		        	System.out.println( "" );
-		        	ArrayList< Boolean > oldConflicts = new ArrayList<>();
-		        	for( LayeredGraphEdge e : conflicts )
-		        	{
-		        		oldConflicts.add( e.isConflicted( layout ) );
-		        		e.setConflicted( true, layout );
-		        	}
-		            LayeredGraphNode oldAlignU = u.getAlignedTo( layout );
-		            Color oldColorCurrent = current.getColor( layout );
-		            LayeredGraphNode oldRootCurrent = current.getRoot( layout );
-		            LayeredGraphNode oldAlignCurrent = current.getAlignedTo( layout );
-		            int oldR = r;
-		            u.setAlignTo( current, layout );
-		            current.setColor( u.getRoot( layout ).getColor( layout ), layout );
-		            current.setRoot( u.getRoot( layout ), layout );
-		            current.setAlignTo( current.getRoot( layout ), layout );
-		            r = calcBeforeLayerNodeIndex( graph.getContainedLayers().get( calcBeforeLayerIndex() ).indexOf( u ) ) + 1;
-		            int oldStep = step++;
-		            final LayeredGraphNode uf = u;
-		            backwards.add( 0, () -> {
-		                System.out.println( "Stepping Backwards... (Step " + oldStep + ")" );
-			        	for( int i = 0; i < conflicts.size(); i++ )
-			        		conflicts.get( i ).setConflicted( oldConflicts.get( i ), layout );
-			        	uf.setAlignTo( oldAlignU, layout );
-		                current.setColor( oldColorCurrent, layout );
-		                current.setRoot( oldRootCurrent, layout );
-		                current.setAlignTo( oldAlignCurrent, layout );
-		                r = oldR;
-		            });
-		            backwardsAdded = true;
-		        }
-		    }
-		}
-		if( !backwardsAdded )
-		{
-    		backwards.add( 0, () -> {
+                if( !incommingEdges.get( m - 1 ).isConflicted( layout ) && r < calcBeforeLayerNodeIndex( graph.getContainedLayers().get( calcBeforeLayerIndex() ).indexOf( u ) ) + 1 )
+                {
+                    System.out.println( "" );
+                    ArrayList< Boolean > oldConflicts = new ArrayList<>();
+                    for( LayeredGraphEdge e : conflicts )
+                    {
+                        oldConflicts.add( e.isConflicted( layout ) );
+                        e.setConflicted( true, layout );
+                    }
+                    LayeredGraphNode oldAlignU = u.getAlign( layout );
+                    Color oldColorCurrent = current.getColor( layout );
+                    LayeredGraphNode oldRootCurrent = current.getRoot( layout );
+                    LayeredGraphNode oldAlignCurrent = current.getAlign( layout );
+                    int oldR = r;
+                    u.setAlign( current, layout );
+                    current.setColor( u.getRoot( layout ).getColor( layout ), layout );
+                    current.setRoot( u.getRoot( layout ), layout );
+                    current.setAlign( current.getRoot( layout ), layout );
+                    r = calcBeforeLayerNodeIndex( graph.getContainedLayers().get( calcBeforeLayerIndex() ).indexOf( u ) ) + 1;
+                    int oldStep = step++;
+                    final LayeredGraphNode uf = u;
+                    backwards.add( 0, () -> {
+                        System.out.println( "Stepping Backwards... (Step " + oldStep + ")" );
+                        for( int i = 0; i < conflicts.size(); i++ )
+                            conflicts.get( i ).setConflicted( oldConflicts.get( i ), layout );
+                        uf.setAlign( oldAlignU, layout );
+                        current.setColor( oldColorCurrent, layout );
+                        current.setRoot( oldRootCurrent, layout );
+                        current.setAlign( oldAlignCurrent, layout );
+                        r = oldR;
+                    });
+                    backwardsAdded = true;
+                }
+            }
+        }
+        if( !backwardsAdded )
+        {
+            backwards.add( 0, () -> {
                 System.out.println( "Performing Empty Backwards Step..." );
-    		});
-		}
-		//current.update();
-		return calcNextState();
-	}
-	
-	private StageStatus calcNextState()
-	{
+            });
+        }
+        //current.update();
+        return calcNextState();
+    }
+
+    private StageStatus calcNextState()
+    {
         boolean breakpoint = !loopNode.setSelected( true );
-		if( layerIndex >= graph.getContainedLayers().size() - 1 )
-		{
-			if( nodeIndex >= graph.getContainedLayers().get( calcLayerIndex() ).size() -1 )
-			{
+        if( layerIndex >= graph.getContainedLayers().size() - 1 )
+        {
+            if( nodeIndex >= graph.getContainedLayers().get( calcLayerIndex() ).size() -1 )
+            {
                 loopNode.setSelected( false );
-				return StageStatus.FINISHED;
-			}
-		}
-		nodeIndex++;
-		if( nodeIndex >= graph.getContainedLayers().get( calcLayerIndex() ).size() )
-		{
-			layerIndex++;
-			nodeIndex = 0;
-			int oldR = r;
-			r = 0;
-			backwards.add(0, ()->{
-			   this.r = oldR;
-			});
-		}
-		if( breakpoint )
-		    return StageStatus.BREAKPOINT;
-		return StageStatus.UNFINISHED;
-	}
+                return StageStatus.FINISHED;
+            }
+        }
+        nodeIndex++;
+        if( nodeIndex >= graph.getContainedLayers().get( calcLayerIndex() ).size() )
+        {
+            layerIndex++;
+            nodeIndex = 0;
+            int oldR = r;
+            r = 0;
+            backwards.add(0, ()->{
+               this.r = oldR;
+            });
+        }
+        if( breakpoint )
+            return StageStatus.BREAKPOINT;
+        return StageStatus.UNFINISHED;
+    }
 
-	@Override
-	public StageStatus backwardStep() {
-		if( subgraphAlgs.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ) != null )
-		{
-			if( subgraphAlgs.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).backwardStep() == StageStatus.UNFINISHED )
-			{
-				LayeredGraphNode current = graph.getContainedLayers().get( calcLayerIndex() ).get( nodeIndex );
-				current.setSelected( layout );
-				//current.update();
-				return StageStatus.UNFINISHED;
-			}
-		}
-		StageStatus status = calcBeforeState();
-		if( status == StageStatus.FINISHED )
-			return status;
-		LayeredGraphNode current = graph.getContainedLayers().get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) );
-		current.setSelected( layout );
-		//current.update();
-		if( !backwards.isEmpty() )
-		{
-			backwards.get( 0 ).reverse();
-			backwards.remove( 0 );
-		}
-		return status;
-	}
-	
-	private StageStatus calcBeforeState()
-	{
-	    boolean breakpoint = !loopNode.setSelected( true );
-		if( layerIndex == 0 )
-		{
-			if( nodeIndex == 0 )
-			{
-		        loopNode.setSelected( false );
-				return StageStatus.FINISHED;
-			}	
-		}
-		nodeIndex--;
-		if( nodeIndex < 0 )
-		{
-			layerIndex--;
-	        backwards.get( 0 ).reverse();
-	        backwards.remove( 0 );
-			nodeIndex = graph.getContainedLayers().get( calcLayerIndex() ).size() - 1;
-		}
+    @Override
+    public StageStatus backwardStep() {
+        if( subgraphAlgs.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ) != null )
+        {
+            inside = true;
+            boolean breakpoint = false;
+            if( !subgraphNodes.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).isSelected() )
+                breakpoint |= !subgraphNodes.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).setSelected( true );
+            switch( subgraphAlgs.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).backwardStep() )
+            {
+            case BREAKPOINT:
+                return StageStatus.BREAKPOINT;
+            case UNFINISHED:
+                LayeredGraphNode current = graph.getContainedLayers().get( calcLayerIndex() ).get( nodeIndex );
+                current.setSelected( layout );
+                if( breakpoint )
+                    return StageStatus.BREAKPOINT;
+                return StageStatus.UNFINISHED;
+            case FINISHED:
+                inside = false;
+                subgraphNodes.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).setSelected( false );
+                break;
+            }
+        }
+        StageStatus status = calcBeforeState();
+        if( status == StageStatus.FINISHED )
+            return status;
+        LayeredGraphNode current = graph.getContainedLayers().get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) );
+        current.setSelected( layout );
+        //current.update();
+        if( !backwards.isEmpty() )
+        {
+            backwards.get( 0 ).reverse();
+            backwards.remove( 0 );
+        }
+        return status;
+    }
+
+    private StageStatus calcBeforeState()
+    {
+        boolean breakpoint = !loopNode.setSelected( true );
+        if( layerIndex == 0 )
+        {
+            if( nodeIndex == 0 )
+            {
+                loopNode.setSelected( false );
+                return StageStatus.FINISHED;
+            }
+        }
+        nodeIndex--;
+        if( nodeIndex < 0 )
+        {
+            layerIndex--;
+            backwards.get( 0 ).reverse();
+            backwards.remove( 0 );
+            nodeIndex = graph.getContainedLayers().get( calcLayerIndex() ).size() - 1;
+        }
         if( breakpoint )
             return StageStatus.BREAKPOINT;
-		return StageStatus.UNFINISHED;
-	}
+        return StageStatus.UNFINISHED;
+    }
 
     @Override
     public PseudoCodeNode createPseudocodeTree( JTree tree ) {
         PseudoCodeNode root = new PseudoCodeNode( "Vertical alignment", tree );
         loopNode = new PseudoCodeNode( "Loop through all nodes...", tree );
+        do {
+            LayeredGraphNode current = graph.getContainedLayers().get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) );
+            if( current.getContainedNodes().size() > 0 )
+            {
+                ExtremalLayoutCalc extcalc = new ExtremalLayoutCalc( layout, current );
+                PseudoCodeNode subNode = extcalc.createPseudocodeTree( loopNode.getTree() );
+                loopNode.add( subNode );
+                subgraphAlgs.get( calcLayerIndex() ).set( calcNodeIndex( nodeIndex ), extcalc );
+                subgraphNodes.get( calcLayerIndex() ).set( calcNodeIndex( nodeIndex ), subNode );
+            }
+        } while( calcNextState() != StageStatus.FINISHED );
+        layerIndex = 0;
+        nodeIndex = 0;
+        backwards.clear();
         root.add( loopNode );
         return root;
     }
 
     @Override
     public StageStatus forwardStepOver() {
-        return forwardStep();
+        if( !inside )
+            return forwardStep();
+        else
+        {
+            boolean breakpoint = false;
+            if( !subgraphNodes.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).isSelected() )
+                breakpoint |= !subgraphNodes.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).setSelected( true );
+            switch( subgraphAlgs.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).forwardStepOver() )
+            {
+            case BREAKPOINT:
+                return StageStatus.BREAKPOINT;
+            case UNFINISHED:
+                if( breakpoint )
+                    return StageStatus.BREAKPOINT;
+                return StageStatus.UNFINISHED;
+            case FINISHED:
+                inside = false;
+                subgraphNodes.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).setSelected( false );
+                break;
+            }
+            return StageStatus.UNFINISHED;
+        }
     }
 
     @Override
     public StageStatus forwardStepOut() {
-        StageStatus status = StageStatus.UNFINISHED;
-        while( status == StageStatus.UNFINISHED )
-            status = forwardStep();
-        return status;
+        if( !inside )
+        {
+            StageStatus status = StageStatus.UNFINISHED;
+            while( status == StageStatus.UNFINISHED )
+                status = forwardStep();
+            return status;
+        }
+        else
+        {
+            boolean breakpoint = false;
+            if( !subgraphNodes.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).isSelected() )
+                breakpoint |= !subgraphNodes.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).setSelected( true );
+            switch( subgraphAlgs.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).forwardStepOut() )
+            {
+            case BREAKPOINT:
+                return StageStatus.BREAKPOINT;
+            case UNFINISHED:
+                if( breakpoint )
+                    return StageStatus.BREAKPOINT;
+                return StageStatus.UNFINISHED;
+            case FINISHED:
+                inside = false;
+                subgraphNodes.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).setSelected( false );
+                break;
+            }
+            return StageStatus.UNFINISHED;
+        }
     }
 
     @Override
     public StageStatus backwardStepOver() {
-        return backwardStep();
+        if( !inside )
+            return backwardStep();
+        else
+        {
+            boolean breakpoint = false;
+            if( !subgraphNodes.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).isSelected() )
+                breakpoint |= !subgraphNodes.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).setSelected( true );
+            switch( subgraphAlgs.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).backwardStepOver() )
+            {
+            case BREAKPOINT:
+                return StageStatus.BREAKPOINT;
+            case UNFINISHED:
+                LayeredGraphNode current = graph.getContainedLayers().get( calcLayerIndex() ).get( nodeIndex );
+                current.setSelected( layout );
+                if( breakpoint )
+                    return StageStatus.BREAKPOINT;
+                return StageStatus.UNFINISHED;
+            case FINISHED:
+                inside = false;
+                subgraphNodes.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).setSelected( false );
+                break;
+            }
+            return StageStatus.UNFINISHED;
+        }
     }
 
     @Override
     public StageStatus backwardStepOut() {
-        StageStatus status = StageStatus.UNFINISHED;
-        while( status == StageStatus.UNFINISHED )
-            status = backwardStep();
-        return status;
+        if( !inside )
+        {
+            StageStatus status = StageStatus.UNFINISHED;
+            while( status == StageStatus.UNFINISHED )
+                status = backwardStep();
+            return status;
+        }
+        else
+        {
+            boolean breakpoint = false;
+            if( !subgraphNodes.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).isSelected() )
+                breakpoint |= !subgraphNodes.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).setSelected( true );
+            switch( subgraphAlgs.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).backwardStepOut() )
+            {
+            case BREAKPOINT:
+                return StageStatus.BREAKPOINT;
+            case UNFINISHED:
+                LayeredGraphNode current = graph.getContainedLayers().get( calcLayerIndex() ).get( nodeIndex );
+                current.setSelected( layout );
+                if( breakpoint )
+                    return StageStatus.BREAKPOINT;
+                return StageStatus.UNFINISHED;
+            case FINISHED:
+                inside = false;
+                subgraphNodes.get( calcLayerIndex() ).get( calcNodeIndex( nodeIndex ) ).setSelected( false );
+                break;
+            }
+            return StageStatus.UNFINISHED;
+        }
     }
 }

+ 130 - 130
src/bk/Combine.java

@@ -19,152 +19,152 @@ import graph.LayeredGraphNode;
  */
 public class Combine implements AlgorithmStage {
 
-	LayeredGraphNode graph;
-	
-	private enum State
-	{
-		ALIGN,
-		SET_COORDINATES
-	}
-	
-	private State state;
-	private int btlOffset;
-	private int btrOffset;
-	private int tblOffset;
-	private int tbrOffset;
-	private int vIndex;
-	private ArrayList< BackwardAction > actions;
+    LayeredGraphNode graph;
+
+    private enum State
+    {
+        ALIGN,
+        SET_COORDINATES
+    }
+
+    private State state;
+    private int btlOffset;
+    private int btrOffset;
+    private int tblOffset;
+    private int tbrOffset;
+    private int vIndex;
+    private ArrayList< BackwardAction > actions;
     private PseudoCodeNode alignNode;
     private PseudoCodeNode setNode;
     private PseudoCodeNode loopNode;
     private boolean inside;
     private boolean breakPoint;
-	
-	public Combine( LayeredGraphNode graph )
-	{
-		this.graph = graph;
-		state = State.ALIGN;
-		vIndex = 0;
-		actions = new ArrayList<>();
-		inside = false;
-	}
-	
-	@Override
-	public StageStatus forwardStep() {
-		breakPoint = false;
-		if( state == State.ALIGN )
-		{
-		    inside = false;
-		    if( !alignNode.isSelected() )
-		    	breakPoint |= !alignNode.setSelected( true );
-			int tblw = (int)graph.getWidth( LayoutType.TOP_BOTTOM_LEFT );
-			int tbrw = (int)graph.getWidth( LayoutType.TOP_BOTTOM_RIGHT );
-			int btlw = (int)graph.getWidth( LayoutType.BOTTOM_TOP_LEFT );
-			int btrw = (int)graph.getWidth( LayoutType.BOTTOM_TOP_RIGHT );
-			LayoutType minLayout = LayoutType.TOP_BOTTOM_LEFT;
-			int minWidth = tblw;
-			if( tbrw < minWidth )
-			{
-				minWidth = tbrw;
-				minLayout = LayoutType.TOP_BOTTOM_RIGHT;
-			}
-			if( btlw < minWidth )
-			{
-				minWidth = btlw;
-				minLayout = LayoutType.BOTTOM_TOP_LEFT;
-			}
-			if( btrw < minWidth )
-			{
-				minWidth = btrw;
-				minLayout = LayoutType.BOTTOM_TOP_RIGHT;
-			}
-			int minX = calcMinX( minLayout );
-			btlOffset = minX - calcMinX( LayoutType.BOTTOM_TOP_LEFT );
-			tblOffset = minX - calcMinX( LayoutType.TOP_BOTTOM_LEFT );
-			btrOffset = minWidth - btrw;
-			tbrOffset = minWidth - tbrw;
-			graph.setColor( Color.BLACK, null );
-			//MainView.frame.setSize( MainView.frame.getWidth() + 1, MainView.frame.getHeight() );
-			//MainView.frame.setSize( MainView.frame.getWidth() - 1, MainView.frame.getHeight() );
-			actions.add( 0, () -> {
+
+    public Combine( LayeredGraphNode graph )
+    {
+        this.graph = graph;
+        state = State.ALIGN;
+        vIndex = 0;
+        actions = new ArrayList<>();
+        inside = false;
+    }
+
+    @Override
+    public StageStatus forwardStep() {
+        breakPoint = false;
+        if( state == State.ALIGN )
+        {
+            inside = false;
+            if( !alignNode.isSelected() )
+                breakPoint |= !alignNode.setSelected( true );
+            int tblw = (int)graph.getWidth( LayoutType.TOP_BOTTOM_LEFT );
+            int tbrw = (int)graph.getWidth( LayoutType.TOP_BOTTOM_RIGHT );
+            int btlw = (int)graph.getWidth( LayoutType.BOTTOM_TOP_LEFT );
+            int btrw = (int)graph.getWidth( LayoutType.BOTTOM_TOP_RIGHT );
+            LayoutType minLayout = LayoutType.TOP_BOTTOM_LEFT;
+            int minWidth = tblw;
+            if( tbrw < minWidth )
+            {
+                minWidth = tbrw;
+                minLayout = LayoutType.TOP_BOTTOM_RIGHT;
+            }
+            if( btlw < minWidth )
+            {
+                minWidth = btlw;
+                minLayout = LayoutType.BOTTOM_TOP_LEFT;
+            }
+            if( btrw < minWidth )
+            {
+                minWidth = btrw;
+                minLayout = LayoutType.BOTTOM_TOP_RIGHT;
+            }
+            int minX = calcMinX( minLayout );
+            btlOffset = minX - calcMinX( LayoutType.BOTTOM_TOP_LEFT );
+            tblOffset = minX - calcMinX( LayoutType.TOP_BOTTOM_LEFT );
+            btrOffset = minWidth - btrw;
+            tbrOffset = minWidth - tbrw;
+            graph.setColor( Color.BLACK, null );
+            //MainView.frame.setSize( MainView.frame.getWidth() + 1, MainView.frame.getHeight() );
+            //MainView.frame.setSize( MainView.frame.getWidth() - 1, MainView.frame.getHeight() );
+            actions.add( 0, () -> {
                 inside = false;
                 setNode.setSelected( false );
                 breakPoint = false;
-    		    if( !alignNode.isSelected() )
-    		    	breakPoint |= !alignNode.setSelected( true );
-				state = State.ALIGN;
-				graph.setColor( null, null );
-				//MainView.frame.setSize( MainView.frame.getWidth() + 1, MainView.frame.getHeight() );
-				//MainView.frame.setSize( MainView.frame.getWidth() - 1, MainView.frame.getHeight() );
-			});
-			state = State.SET_COORDINATES;
+                if( !alignNode.isSelected() )
+                    breakPoint |= !alignNode.setSelected( true );
+                state = State.ALIGN;
+                graph.setColor( null, null );
+                //MainView.frame.setSize( MainView.frame.getWidth() + 1, MainView.frame.getHeight() );
+                //MainView.frame.setSize( MainView.frame.getWidth() - 1, MainView.frame.getHeight() );
+            });
+            state = State.SET_COORDINATES;
             alignNode.setSelected( false );
-		    if( !setNode.isSelected() )
-		    	breakPoint |= !setNode.setSelected( true );
+            if( !setNode.isSelected() )
+                breakPoint |= !setNode.setSelected( true );
             breakPoint |= !loopNode.setSelected( true );
-		}
-		else
-		{
+        }
+        else
+        {
             breakPoint = !loopNode.setSelected( true );
-			if( vIndex >= graph.getContainedNodes().size() )
-			{
-	            inside = false; 
-			    setNode.setSelected( false );
-			    loopNode.setSelected( false );
-				return StageStatus.FINISHED;
-			}
-			else
-	            inside = true;
-			LayeredGraphNode current = graph.getContainedNodes().get( vIndex );
-			current.setSelected( null );
-			ArrayList< Integer > positions = new ArrayList<>();
-			positions.add( (int)current.getX( LayoutType.TOP_BOTTOM_LEFT ) + tblOffset );
-			positions.add( (int)current.getX( LayoutType.TOP_BOTTOM_RIGHT ) + tbrOffset );
-			positions.add( (int)current.getX( LayoutType.BOTTOM_TOP_LEFT ) + btlOffset );
-			positions.add( (int)current.getX( LayoutType.BOTTOM_TOP_RIGHT ) + btrOffset );
-			Collections.sort( positions );
-			int oldX = (int)current.getX( LayoutType.COMBINED );
-			current.setX( (positions.get( 1 ) + positions.get( 2 )) / 2, true, LayoutType.COMBINED );
-			actions.add( 0, () -> {
+            if( vIndex >= graph.getContainedNodes().size() )
+            {
+                inside = false;
+                setNode.setSelected( false );
+                loopNode.setSelected( false );
+                return StageStatus.FINISHED;
+            }
+            else
+                inside = true;
+            LayeredGraphNode current = graph.getContainedNodes().get( vIndex );
+            current.setSelected( null );
+            ArrayList< Integer > positions = new ArrayList<>();
+            positions.add( (int)current.getX( LayoutType.TOP_BOTTOM_LEFT ) + tblOffset );
+            positions.add( (int)current.getX( LayoutType.TOP_BOTTOM_RIGHT ) + tbrOffset );
+            positions.add( (int)current.getX( LayoutType.BOTTOM_TOP_LEFT ) + btlOffset );
+            positions.add( (int)current.getX( LayoutType.BOTTOM_TOP_RIGHT ) + btrOffset );
+            Collections.sort( positions );
+            int oldX = (int)current.getX( LayoutType.COMBINED );
+            current.setX( (positions.get( 1 ) + positions.get( 2 )) / 2, true, LayoutType.COMBINED );
+            actions.add( 0, () -> {
                 inside = true;
                 breakPoint = false;
-    		    if( !setNode.isSelected() )
-    		    	breakPoint |= !setNode.setSelected( true );
-    		    breakPoint |= !loopNode.setSelected( true );
-				vIndex--;
-				current.setX( oldX, true, LayoutType.COMBINED );
-				current.setSelected( null );
-			});
-			vIndex++;
-		}
-		if( breakPoint )
-		    return StageStatus.BREAKPOINT;
-		return StageStatus.UNFINISHED;
-	}
-	
-	private int calcMinX(  LayoutType layout )
-	{
-		int minX = 0;
-		if( graph.getContainedNodes().size() > 0 )
-			minX = (int)graph.getContainedNodes().get( 0 ).getX( layout );
-		for( LayeredGraphNode n : graph.getContainedNodes() )
-			minX = Math.min( minX, (int)n.getX( layout ) );
-		return minX;
-	}
-
-	@Override
-	public StageStatus backwardStep() {
-		if( actions.size() == 0 )
-		{
+                if( !setNode.isSelected() )
+                    breakPoint |= !setNode.setSelected( true );
+                breakPoint |= !loopNode.setSelected( true );
+                vIndex--;
+                current.setX( oldX, true, LayoutType.COMBINED );
+                current.setSelected( null );
+            });
+            vIndex++;
+        }
+        if( breakPoint )
+            return StageStatus.BREAKPOINT;
+        return StageStatus.UNFINISHED;
+    }
+
+    private int calcMinX(  LayoutType layout )
+    {
+        int minX = 0;
+        if( graph.getContainedNodes().size() > 0 )
+            minX = (int)graph.getContainedNodes().get( 0 ).getX( layout );
+        for( LayeredGraphNode n : graph.getContainedNodes() )
+            minX = Math.min( minX, (int)n.getX( layout ) );
+        return minX;
+    }
+
+    @Override
+    public StageStatus backwardStep() {
+        if( actions.size() == 0 )
+        {
             inside = false;
-			return StageStatus.FINISHED;
-		}
-		actions.get( 0 ).reverse();
-		actions.remove( 0 );
+            return StageStatus.FINISHED;
+        }
+        actions.get( 0 ).reverse();
+        actions.remove( 0 );
         if( breakPoint )
             return StageStatus.BREAKPOINT;
-		return StageStatus.UNFINISHED;
-	}
+        return StageStatus.UNFINISHED;
+    }
 
     @Override
     public PseudoCodeNode createPseudocodeTree( JTree tree ) {

+ 310 - 310
src/bk/Compaction.java

@@ -17,242 +17,242 @@ import graph.LayeredGraphNode;
  */
 public class Compaction implements AlgorithmStage{
 
-	private enum CompactionState
-	{
-		PLACE_BLOCKS,
-		APPLY_SHIFT
-	}
-	
-	private class StackFrame
-	{
-		public LayeredGraphNode v;
-		public LayeredGraphNode u;
-		public LayeredGraphNode w;
-	}
-	
-	private CompactionState state;
-	private LayeredGraphNode graph;
-	private int vIndex;
-	
-	private ArrayList< StackFrame > stack; // TODO: evtl richtigen "Stack" benutzen
-	private ArrayList< BackwardAction > actions; // TODO: evtl richtigen "Stack" benutzen
-	private LayoutType layout;
-	private PseudoCodeNode placeNode;
+    private enum CompactionState
+    {
+        PLACE_BLOCKS,
+        APPLY_SHIFT
+    }
+
+    private class StackFrame
+    {
+        public LayeredGraphNode v;
+        public LayeredGraphNode u;
+        public LayeredGraphNode w;
+    }
+
+    private CompactionState state;
+    private LayeredGraphNode graph;
+    private int vIndex;
+
+    private ArrayList< StackFrame > stack; // TODO: evtl richtigen "Stack" benutzen
+    private ArrayList< BackwardAction > actions; // TODO: evtl richtigen "Stack" benutzen
+    private LayoutType layout;
+    private PseudoCodeNode placeNode;
     private PseudoCodeNode placeLoopNode;
     private PseudoCodeNode applyNode;
     private PseudoCodeNode applyLoopNode;
     private boolean breakPoint;
     private boolean inside;
-	
-	
-	public Compaction( LayeredGraphNode graph, LayoutType layout )
-	{
-	    this.layout = layout;
-		this.graph = graph;
-		state = CompactionState.PLACE_BLOCKS;
-		stack = new ArrayList<>(); // der call-stack des rekursiven algorithmus
-		vIndex = 0;
-		actions = new ArrayList<>();
-		inside = false;
-	}
-	
-	/**
-	 * calculates the minimum spacing needed between two left borders of nodes.
-	 * @return the spacing
-	 */
-	public double calcSpacing()
-	{
-		double max = 0;
-		for( LayeredGraphNode n : graph.getContainedNodes() )
-			max = Math.max( max, n.getWidth( layout ) );
-		//return max + 25;
-		return max + 5;
-	}
-	
-	private LayeredGraphNode getNodeFromIndex( int index )
-	{
-	    for( ArrayList< LayeredGraphNode > l : graph.getContainedLayers() )
-	    {
-	        if( index >= l.size() )
-	            index -= l.size();
-	        else
-	            return l.get( index );
-	    }
-	    return null;
-	}
-	
-	@Override
-	public StageStatus forwardStep() {
-		breakPoint = false;
-		int acSize = actions.size();
-		if( state == CompactionState.PLACE_BLOCKS ) // blöcke platzieren
-		{
-		    inside = true;
-		    if( !placeNode.isSelected() )
-		    	breakPoint = !placeNode.setSelected( true );
-		    breakPoint |= !placeLoopNode.setSelected( true );
-			if( stack.size() == 0 ) // äußere schleife, placeblocks bisher nicht aufgerufen
-			{
-				ArrayList< LayeredGraphNode > nodes = graph.getContainedNodes();
-				boolean found = false; // knoten mit v = root[v] gefunden?
-				int oldVIndex = vIndex; // nötig für "undo"
-				
-				// suche knoten mit v = root[v] und undefiniertem x-Wert
-				for( ; vIndex < nodes.size(); vIndex++ )
-				{
-					if( getNodeFromIndex( vIndex ).isXUndefined( layout ) && getNodeFromIndex( vIndex ) == getNodeFromIndex( vIndex ).getRoot( layout ) )
-					{
-	                    found = true;
-						break;
-					}
-				}
-				
-				// kein knoten gefunden
-				if( !found )
-				{
-				    // wechsele in die phase des Blöckeshiftens
-		            placeNode.setSelected( false );
-		            placeLoopNode.setSelected( false );
-				    if( !applyNode.isSelected() )
-				    	breakPoint |= !applyNode.setSelected( true );
-		            breakPoint |= !applyLoopNode.setSelected( true );
-					state = CompactionState.APPLY_SHIFT;
-					inside = false;
-					vIndex = 0;
-					actions.add( 0, ()-> {
-	                    applyNode.setSelected( false );
-	                    applyLoopNode.setSelected( false );
-	                    breakPoint = false;
-					    if( !placeNode.isSelected() )
-					    	breakPoint |= !placeNode.setSelected( true );
-	                    breakPoint |= !placeLoopNode.setSelected( true );
-						vIndex = oldVIndex;
-						inside = false;
-						state = CompactionState.PLACE_BLOCKS;
-					} );
-				}
-				else // Knoten gefunden
-				{
-					StackFrame f = new StackFrame(); // enthält lokale variablen
-					f.v = getNodeFromIndex( vIndex );
-					double oldX = f.v.getX( layout ); // nötig für "undo"
-					f.v.setX( 0, true, layout );
-					f.w = f.v;
+
+
+    public Compaction( LayeredGraphNode graph, LayoutType layout )
+    {
+        this.layout = layout;
+        this.graph = graph;
+        state = CompactionState.PLACE_BLOCKS;
+        stack = new ArrayList<>(); // der call-stack des rekursiven algorithmus
+        vIndex = 0;
+        actions = new ArrayList<>();
+        inside = false;
+    }
+
+    /**
+     * calculates the minimum spacing needed between two left borders of nodes.
+     * @return the spacing
+     */
+    public double calcSpacing()
+    {
+        double max = 0;
+        for( LayeredGraphNode n : graph.getContainedNodes() )
+            max = Math.max( max, n.getWidth( layout ) );
+        //return max + 25;
+        return max + 5;
+    }
+
+    private LayeredGraphNode getNodeFromIndex( int index )
+    {
+        for( ArrayList< LayeredGraphNode > l : graph.getContainedLayers() )
+        {
+            if( index >= l.size() )
+                index -= l.size();
+            else
+                return l.get( index );
+        }
+        return null;
+    }
+
+    @Override
+    public StageStatus forwardStep() {
+        breakPoint = false;
+        int acSize = actions.size();
+        if( state == CompactionState.PLACE_BLOCKS ) // blöcke platzieren
+        {
+            inside = true;
+            if( !placeNode.isSelected() )
+                breakPoint = !placeNode.setSelected( true );
+            breakPoint |= !placeLoopNode.setSelected( true );
+            if( stack.size() == 0 ) // äußere schleife, placeblocks bisher nicht aufgerufen
+            {
+                ArrayList< LayeredGraphNode > nodes = graph.getContainedNodes();
+                boolean found = false; // knoten mit v = root[v] gefunden?
+                int oldVIndex = vIndex; // nötig für "undo"
+
+                // suche knoten mit v = root[v] und undefiniertem x-Wert
+                for( ; vIndex < nodes.size(); vIndex++ )
+                {
+                    if( getNodeFromIndex( vIndex ).isXUndefined( layout ) && getNodeFromIndex( vIndex ) == getNodeFromIndex( vIndex ).getRoot( layout ) )
+                    {
+                        found = true;
+                        break;
+                    }
+                }
+
+                // kein knoten gefunden
+                if( !found )
+                {
+                    // wechsele in die phase des Blöckeshiftens
+                    placeNode.setSelected( false );
+                    placeLoopNode.setSelected( false );
+                    if( !applyNode.isSelected() )
+                        breakPoint |= !applyNode.setSelected( true );
+                    breakPoint |= !applyLoopNode.setSelected( true );
+                    state = CompactionState.APPLY_SHIFT;
+                    inside = false;
+                    vIndex = 0;
+                    actions.add( 0, ()-> {
+                        applyNode.setSelected( false );
+                        applyLoopNode.setSelected( false );
+                        breakPoint = false;
+                        if( !placeNode.isSelected() )
+                            breakPoint |= !placeNode.setSelected( true );
+                        breakPoint |= !placeLoopNode.setSelected( true );
+                        vIndex = oldVIndex;
+                        inside = false;
+                        state = CompactionState.PLACE_BLOCKS;
+                    } );
+                }
+                else // Knoten gefunden
+                {
+                    StackFrame f = new StackFrame(); // enthält lokale variablen
+                    f.v = getNodeFromIndex( vIndex );
+                    double oldX = f.v.getX( layout ); // nötig für "undo"
+                    f.v.setX( 0, true, layout );
+                    f.w = f.v;
                     f.w.setSelected( layout ); // zeige knoten als aktiven knoten an
                     System.out.println( "call place_block( " + f.v + " )" );
-					stack.add( 0, f );
-					
-					// die "undo"-action
-					actions.add( 0, ()-> {
-	                    breakPoint = false;
-					    if( !placeNode.isSelected() )
-					    	breakPoint |= !placeNode.setSelected( true );
+                    stack.add( 0, f );
+
+                    // die "undo"-action
+                    actions.add( 0, ()-> {
+                        breakPoint = false;
+                        if( !placeNode.isSelected() )
+                            breakPoint |= !placeNode.setSelected( true );
                         breakPoint |= !placeLoopNode.setSelected( true );
-					    inside = true;
-						stack.get( 0 ).v.setX( oldX, false, layout );
-						stack.get( 0 ).v.setSelected( layout );
-						stack.remove( 0 );
-						vIndex = oldVIndex;
-						state = CompactionState.PLACE_BLOCKS;
-					});
-				}
-			}
-			else // zurzeit innerhalb einer placeblock methode
-			{
-				StackFrame sf = stack.get( 0 );
-				if( sf.u == null ) // zu beginn der placeblock methode
-				{
+                        inside = true;
+                        stack.get( 0 ).v.setX( oldX, false, layout );
+                        stack.get( 0 ).v.setSelected( layout );
+                        stack.remove( 0 );
+                        vIndex = oldVIndex;
+                        state = CompactionState.PLACE_BLOCKS;
+                    });
+                }
+            }
+            else // zurzeit innerhalb einer placeblock methode
+            {
+                StackFrame sf = stack.get( 0 );
+                if( sf.u == null ) // zu beginn der placeblock methode
+                {
                     int posW = graph.getContainedLayers().get( sf.w.getLayer() ).indexOf( sf.w );
-					if( (posW >= 1 && (layout == LayoutType.BOTTOM_TOP_LEFT || layout == LayoutType.TOP_BOTTOM_LEFT)) || (posW < graph.getContainedLayers().get( sf.w.getLayer() ).size() - 1 && (layout == LayoutType.BOTTOM_TOP_RIGHT || layout == LayoutType.TOP_BOTTOM_RIGHT)) ) // if pos[w] > 1"
-					{
-					    int offset = -1;
-					    if( layout == LayoutType.BOTTOM_TOP_RIGHT || layout == LayoutType.TOP_BOTTOM_RIGHT )
-					        offset = 1;
+                    if( (posW >= 1 && (layout == LayoutType.BOTTOM_TOP_LEFT || layout == LayoutType.TOP_BOTTOM_LEFT)) || (posW < graph.getContainedLayers().get( sf.w.getLayer() ).size() - 1 && (layout == LayoutType.BOTTOM_TOP_RIGHT || layout == LayoutType.TOP_BOTTOM_RIGHT)) ) // if pos[w] > 1"
+                    {
+                        int offset = -1;
+                        if( layout == LayoutType.BOTTOM_TOP_RIGHT || layout == LayoutType.TOP_BOTTOM_RIGHT )
+                            offset = 1;
                         sf.u = graph.getContainedLayers().get( sf.w.getLayer() ).get( posW + offset ).getRoot( layout );
-						
-						if( sf.u.isXUndefined( layout ) ) // nötig placeblock aufzurufen?
-						{// ja
-							StackFrame nsf = new StackFrame(); // enthält lokale variablen
-							nsf.v = sf.u;
-							double oldX = nsf.v.getX( layout ); // nötig für "undo"
-							nsf.v.setX( 0, true, layout );
-							nsf.w = nsf.v;
+
+                        if( sf.u.isXUndefined( layout ) ) // nötig placeblock aufzurufen?
+                        {// ja
+                            StackFrame nsf = new StackFrame(); // enthält lokale variablen
+                            nsf.v = sf.u;
+                            double oldX = nsf.v.getX( layout ); // nötig für "undo"
+                            nsf.v.setX( 0, true, layout );
+                            nsf.w = nsf.v;
                             nsf.w.setSelected( layout ); // zeige knoten als aktiven knoten an
-		                    System.out.println( "call place_block( " + nsf.v + " )" );
-							stack.add( 0, nsf );
-		                    
-		                    // die "undo"-action
-							actions.add( 0, ()-> {
-			                    breakPoint = false;
-							    if( !placeNode.isSelected() )
-							    	breakPoint |= !placeNode.setSelected( true );
-		                        breakPoint |= !placeLoopNode.setSelected( true );
-							    inside = true;
-								stack.get( 0 ).v.setX( oldX, false, layout );
-								stack.get( 0 ).v.setSelected( layout );
-								stack.remove( 0 );
-								stack.get( 0 ).u = null;
-							});
-						}
-						else // nein
-						{
-						    // tue nix
-							sf.w.setSelected( layout );
-							actions.add( 0, ()-> {
-			                    breakPoint = false;
-							    if( !placeNode.isSelected() )
-							    	breakPoint |= !placeNode.setSelected( true );
-		                        breakPoint |= !placeLoopNode.setSelected( true );
+                            System.out.println( "call place_block( " + nsf.v + " )" );
+                            stack.add( 0, nsf );
+
+                            // die "undo"-action
+                            actions.add( 0, ()-> {
+                                breakPoint = false;
+                                if( !placeNode.isSelected() )
+                                    breakPoint |= !placeNode.setSelected( true );
+                                breakPoint |= !placeLoopNode.setSelected( true );
+                                inside = true;
+                                stack.get( 0 ).v.setX( oldX, false, layout );
+                                stack.get( 0 ).v.setSelected( layout );
+                                stack.remove( 0 );
+                                stack.get( 0 ).u = null;
+                            });
+                        }
+                        else // nein
+                        {
+                            // tue nix
+                            sf.w.setSelected( layout );
+                            actions.add( 0, ()-> {
+                                breakPoint = false;
+                                if( !placeNode.isSelected() )
+                                    breakPoint |= !placeNode.setSelected( true );
+                                breakPoint |= !placeLoopNode.setSelected( true );
                                 inside = true;
-								stack.get( 0 ).u = null;
-							});
-						}
-					}
-					else 
-					{ // w = align[w]
-						LayeredGraphNode oldW = sf.w;
-						sf.w = sf.w.getAlignedTo( layout );
-						sf.w.setSelected( layout );
-						if( sf.w == sf.v ) // schleifenabbruchbedingung
-						{ //abbrechen, placeblock beendet
+                                stack.get( 0 ).u = null;
+                            });
+                        }
+                    }
+                    else
+                    { // w = align[w]
+                        LayeredGraphNode oldW = sf.w;
+                        sf.w = sf.w.getAlign( layout );
+                        sf.w.setSelected( layout );
+                        if( sf.w == sf.v ) // schleifenabbruchbedingung
+                        { //abbrechen, placeblock beendet
                             System.out.println( "return place_block( " + sf.v + " )" );
-							stack.remove( 0 );
-							actions.add( 0, ()-> {
-			                    breakPoint = false;
-							    if( !placeNode.isSelected() )
-							    	breakPoint |= !placeNode.setSelected( true );
-		                        breakPoint |= !placeLoopNode.setSelected( true );
+                            stack.remove( 0 );
+                            actions.add( 0, ()-> {
+                                breakPoint = false;
+                                if( !placeNode.isSelected() )
+                                    breakPoint |= !placeNode.setSelected( true );
+                                breakPoint |= !placeLoopNode.setSelected( true );
                                 inside = true;
-								stack.add( 0, sf );
-								sf.w = oldW;
+                                stack.add( 0, sf );
+                                sf.w = oldW;
                                 sf.w.setSelected( layout );
-							});
-						}
-						else
-						{ //nur "undo aktion" hinzufügen
-							actions.add( 0, ()-> {
-			                    breakPoint = false;
-							    if( !placeNode.isSelected() )
-							    	breakPoint |= !placeNode.setSelected( true );
-		                        breakPoint |= !placeLoopNode.setSelected( true );
+                            });
+                        }
+                        else
+                        { //nur "undo aktion" hinzufügen
+                            actions.add( 0, ()-> {
+                                breakPoint = false;
+                                if( !placeNode.isSelected() )
+                                    breakPoint |= !placeNode.setSelected( true );
+                                breakPoint |= !placeLoopNode.setSelected( true );
                                 inside = true;
-								sf.w = oldW;
-								sf.w.setSelected( layout );
-							});
-						}
-					}	
-				}
-				else // ein "placeBlock(u)" aufruf hat gerade returned
-				{
-				    // alte Werte merken für undo
-					LayeredGraphNode oldSink = sf.v.getSink( layout );	
-					LayeredGraphNode sinkOfU = sf.u.getSink( layout );
-					double oldShift = sinkOfU.getShift( layout );
-					double oldX = sf.v.getX( layout );
-					boolean oldDef = !sf.v.isXUndefined( layout );
-					
-					// v für visualisierung markieren
-					sf.w.setSelected( layout );
+                                sf.w = oldW;
+                                sf.w.setSelected( layout );
+                            });
+                        }
+                    }
+                }
+                else // ein "placeBlock(u)" aufruf hat gerade returned
+                {
+                    // alte Werte merken für undo
+                    LayeredGraphNode oldSink = sf.v.getSink( layout );
+                    LayeredGraphNode sinkOfU = sf.u.getSink( layout );
+                    double oldShift = sinkOfU.getShift( layout );
+                    double oldX = sf.v.getX( layout );
+                    boolean oldDef = !sf.v.isXUndefined( layout );
+
+                    // v für visualisierung markieren
+                    sf.w.setSelected( layout );
                     
                     if( sf.v.getSink( layout ) == sf.v ) // sink[v] = v?
                         sf.v.setSink( sf.u.getSink( layout ), layout ); // sink[v] := sink[u]
@@ -260,121 +260,121 @@ public class Compaction implements AlgorithmStage{
                     if( layout == LayoutType.BOTTOM_TOP_RIGHT || layout == LayoutType.TOP_BOTTOM_RIGHT )
                         multiplyer = -1;
                     
-					if( sf.v.getSink( layout ) != sf.u.getSink( layout ) ) // sink[v] != sink [u]?
-						sf.u.getSink( layout ).setShift( // shift[sink[u]] =
-						  Math.min( sf.u.getSink( layout ).getShift( layout ),  // min(shift[sink[u]]
-						          multiplyer * (Math.abs(sf.v.getX( layout )) - Math.abs(sf.u.getX( layout )) - calcSpacing()) ), layout ); // y_v - y_u - s
-					else
-					    // y_v = max {y_v, y_u + s}
-						sf.v.setX( multiplyer * Math.max( Math.abs( sf.v.getX( layout ) ), Math.abs( sf.u.getX( layout ) ) + calcSpacing() ), true, layout );
-					
+                    if( sf.v.getSink( layout ) != sf.u.getSink( layout ) ) // sink[v] != sink [u]?
+                        sf.u.getSink( layout ).setShift( // shift[sink[u]] =
+                          Math.min( sf.u.getSink( layout ).getShift( layout ),  // min(shift[sink[u]]
+                                  multiplyer * (Math.abs(sf.v.getX( layout )) - Math.abs(sf.u.getX( layout )) - calcSpacing()) ), layout ); // y_v - y_u - s
+                    else
+                        // y_v = max {y_v, y_u + s}
+                        sf.v.setX( multiplyer * Math.max( Math.abs( sf.v.getX( layout ) ), Math.abs( sf.u.getX( layout ) ) + calcSpacing() ), true, layout );
+
 
                     // alte Werte merken für undo
-					LayeredGraphNode oldW = sf.w;
+                    LayeredGraphNode oldW = sf.w;
                     LayeredGraphNode oldU = sf.u;
                     
-					sf.w = sf.w.getAlignedTo( layout ); // w = align[w]
-					sf.u = null; // u wird nächsten schleifendurchlauf neu gesetzt
-					
-					if( sf.w == sf.v ) // schleifenabbruchbedingung
-					{ //abbrechen, placeblock beendet  
-					    System.out.println( "return place_block( " + sf.v + " )" );
-						stack.remove( 0 );
-						actions.add( 0, ()-> {
-		                    breakPoint = false;
-						    if( !placeNode.isSelected() )
-						    	breakPoint |= !placeNode.setSelected( true );
-	                        breakPoint |= !placeLoopNode.setSelected( true );
+                    sf.w = sf.w.getAlign( layout ); // w = align[w]
+                    sf.u = null; // u wird nächsten schleifendurchlauf neu gesetzt
+
+                    if( sf.w == sf.v ) // schleifenabbruchbedingung
+                    { //abbrechen, placeblock beendet
+                        System.out.println( "return place_block( " + sf.v + " )" );
+                        stack.remove( 0 );
+                        actions.add( 0, ()-> {
+                            breakPoint = false;
+                            if( !placeNode.isSelected() )
+                                breakPoint |= !placeNode.setSelected( true );
+                            breakPoint |= !placeLoopNode.setSelected( true );
                             inside = true;
-							stack.add( 0, sf );
-							stack.get( 0 ).v.setSink(  oldSink, layout );
-							sinkOfU.setShift( oldShift, layout );
-							sf.u = oldU;
-							sf.v.setX( oldX, oldDef, layout );
-							sf.w = oldW;
+                            stack.add( 0, sf );
+                            stack.get( 0 ).v.setSink(  oldSink, layout );
+                            sinkOfU.setShift( oldShift, layout );
+                            sf.u = oldU;
+                            sf.v.setX( oldX, oldDef, layout );
+                            sf.w = oldW;
                             sf.w.setSelected( layout );
-						});
-					}
-					else
-					{ //nur "undo aktion" hinzufügen
-						actions.add( 0, ()-> {
-		                    breakPoint = false;
-						    if( !placeNode.isSelected() )
-						    	breakPoint |= !placeNode.setSelected( true );
-	                        breakPoint |= !placeLoopNode.setSelected( true );
+                        });
+                    }
+                    else
+                    { //nur "undo aktion" hinzufügen
+                        actions.add( 0, ()-> {
+                            breakPoint = false;
+                            if( !placeNode.isSelected() )
+                                breakPoint |= !placeNode.setSelected( true );
+                            breakPoint |= !placeLoopNode.setSelected( true );
                             inside = true;
-							stack.get( 0 ).v.setSink(  oldSink, layout );
-							sinkOfU.setShift( oldShift, layout );
-							sf.u = oldU;
-							sf.v.setX( oldX, oldDef, layout );
-							sf.w = oldW;
+                            stack.get( 0 ).v.setSink(  oldSink, layout );
+                            sinkOfU.setShift( oldShift, layout );
+                            sf.u = oldU;
+                            sf.v.setX( oldX, oldDef, layout );
+                            sf.w = oldW;
                             sf.w.setSelected( layout );
-						});
-					}
-				}
-			}
-		}
-		else if( state == CompactionState.APPLY_SHIFT )// "Compute absolute coordinates"
-		{
+                        });
+                    }
+                }
+            }
+        }
+        else if( state == CompactionState.APPLY_SHIFT )// "Compute absolute coordinates"
+        {
             inside = true;
-		    if( !applyNode.isSelected() )
-		    	breakPoint |= !applyNode.setSelected( true );
+            if( !applyNode.isSelected() )
+                breakPoint |= !applyNode.setSelected( true );
             breakPoint |= !applyLoopNode.setSelected( true );
-		    if( vIndex >= graph.getContainedNodes().size() )
-		    {
+            if( vIndex >= graph.getContainedNodes().size() )
+            {
                 inside = false;
                 applyNode.setSelected( false );
                 applyLoopNode.setSelected( false );
                 return StageStatus.FINISHED;
-		    }
-			LayeredGraphNode v = graph.getContainedNodes().get( vIndex );
-			double oldX = v.getX( layout );
-			boolean oldDef = !v.isXUndefined( layout );
-			
-			v.setSelected( layout );
-			v.setX( v.getRoot( layout ).getX( layout ), true, layout ); // y_v = y_root[v]
-			if( v == v.getRoot( layout ) && v.getSink( layout ).getShift( layout ) < Double.POSITIVE_INFINITY )
-				v.setX( v.getX( layout ) + v.getSink( layout ).getShift( layout ), true, layout );
-			actions.add( 0, ()-> {
+            }
+            LayeredGraphNode v = graph.getContainedNodes().get( vIndex );
+            double oldX = v.getX( layout );
+            boolean oldDef = !v.isXUndefined( layout );
+
+            v.setSelected( layout );
+            v.setX( v.getRoot( layout ).getX( layout ), true, layout ); // y_v = y_root[v]
+            if( v == v.getRoot( layout ) && v.getSink( layout ).getShift( layout ) < Double.POSITIVE_INFINITY )
+                v.setX( v.getX( layout ) + v.getSink( layout ).getShift( layout ), true, layout );
+            actions.add( 0, ()-> {
                 inside = true;
                 breakPoint = false;
-			    if( !applyNode.isSelected() )
-			    	breakPoint |= !applyNode.setSelected( true );
+                if( !applyNode.isSelected() )
+                    breakPoint |= !applyNode.setSelected( true );
                 breakPoint |= !applyLoopNode.setSelected( true );
-				v.setX( oldX, oldDef, layout );
-				v.setSelected( layout );
-				vIndex--;
-			} );
-			vIndex++;
-			if( vIndex >= graph.getContainedNodes().size() )
-			{
+                v.setX( oldX, oldDef, layout );
+                v.setSelected( layout );
+                vIndex--;
+            } );
+            vIndex++;
+            if( vIndex >= graph.getContainedNodes().size() )
+            {
                 applyNode.setSelected( false );
                 applyLoopNode.setSelected( false );
-				return StageStatus.FINISHED;
-			}
-		}
-		if( actions.size() != acSize + 1 )
-			System.out.println( "ERROR" );
-		if( breakPoint )
-		    return StageStatus.BREAKPOINT;
-		return StageStatus.UNFINISHED;
-	}
+                return StageStatus.FINISHED;
+            }
+        }
+        if( actions.size() != acSize + 1 )
+            System.out.println( "ERROR" );
+        if( breakPoint )
+            return StageStatus.BREAKPOINT;
+        return StageStatus.UNFINISHED;
+    }
 
-	@Override
-	public StageStatus backwardStep() {
-		if( actions.size() == 0 )
-		{
+    @Override
+    public StageStatus backwardStep() {
+        if( actions.size() == 0 )
+        {
             inside = false;
             placeNode.setSelected( false );
             placeLoopNode.setSelected( false );
-			return StageStatus.FINISHED;
-		}
-		actions.get( 0 ).reverse();
-		actions.remove( 0 );
+            return StageStatus.FINISHED;
+        }
+        actions.get( 0 ).reverse();
+        actions.remove( 0 );
         if( breakPoint )
             return StageStatus.BREAKPOINT;
-		return StageStatus.UNFINISHED;
-	}
+        return StageStatus.UNFINISHED;
+    }
 
     @Override
     public PseudoCodeNode createPseudocodeTree( JTree tree ) {

+ 44 - 44
src/bk/ConflictDetection.java

@@ -29,61 +29,61 @@ public class ConflictDetection implements AlgorithmStage {
     
     @Override
     public StageStatus forwardStep() {
-    	int oldI = i;
-    	int oldL1 = l1;
-    	((PseudoCodeNode)markNode.getParent()).setSelected( true );
-    	boolean breakPoint = !markNode.setSelected( true );
-    	if( i + 1 >= graph.getContainedLayers().size() - 1 )
-    	{
+        int oldI = i;
+        int oldL1 = l1;
+        ((PseudoCodeNode)markNode.getParent()).setSelected( true );
+        boolean breakPoint = !markNode.setSelected( true );
+        if( i + 1 >= graph.getContainedLayers().size() - 1 )
+        {
             ((PseudoCodeNode)markNode.getParent()).setSelected( false );
             markNode.setSelected( false );
-    		return StageStatus.FINISHED;
-    	}
-    	LayeredGraphNode curr = graph.getContainedLayers().get( i + 1 ).get( l1 );
-    	curr.setSelected( null );
-    	ArrayList< LayeredGraphEdge > edges = curr.getIncomingEdges();
-    	LayeredGraphEdge dummyEdge = null;
-    	for( LayeredGraphEdge e : edges )
-    	{
-    		if( e.isDummyEdge() )
-    		{
-    			dummyEdge = e;
-    			break;
-    		}
-    	}
-    	ArrayList< LayeredGraphEdge > conflicts = new ArrayList<>();
+            return StageStatus.FINISHED;
+        }
+        LayeredGraphNode curr = graph.getContainedLayers().get( i + 1 ).get( l1 );
+        curr.setSelected( null );
+        ArrayList< LayeredGraphEdge > edges = curr.getIncomingEdges();
+        LayeredGraphEdge dummyEdge = null;
+        for( LayeredGraphEdge e : edges )
+        {
+            if( e.isDummyEdge() )
+            {
+                dummyEdge = e;
+                break;
+            }
+        }
+        ArrayList< LayeredGraphEdge > conflicts = new ArrayList<>();
         if( dummyEdge != null )
         {
-    		for( LayeredGraphEdge e : edges )
-    		{
-    			if( e.isDummyEdge() )
-    			{
-    				ArrayList< LayeredGraphEdge > conf = e.calcConflictedEdges();
-    				for( LayeredGraphEdge ce : conf )
-    				{
-    					if( !ce.isDummyEdge() )
-    						conflicts.add( ce );
-    				}
-    			}
-    		}
+            for( LayeredGraphEdge e : edges )
+            {
+                if( e.isDummyEdge() )
+                {
+                    ArrayList< LayeredGraphEdge > conf = e.calcEdgeCrossings();
+                    for( LayeredGraphEdge ce : conf )
+                    {
+                        if( !ce.isDummyEdge() )
+                            conflicts.add( ce );
+                    }
+                }
+            }
         }
         for( LayeredGraphEdge c : conflicts )
-        	c.setConflicted( true, null );
-    	StageStatus status =  calcNextStatus();
-    	actions.add( 0, ()->{
-    		i = oldI;
-    		l1 = oldL1;
+            c.setConflicted( true, null );
+        StageStatus status =  calcNextStatus();
+        actions.add( 0, ()->{
+            i = oldI;
+            l1 = oldL1;
             if( i + 1 < graph.getContainedLayers().size() - 1 && l1 > 0 )
             {
                 LayeredGraphNode layde = graph.getContainedLayers().get( i + 1 ).get( l1 - 1 );
                 layde.setSelected( null );
             }
             for( LayeredGraphEdge c : conflicts )
-            	c.setConflicted( false, null );
-    	});
-    	if( status != StageStatus.FINISHED && breakPoint )
-    	    return StageStatus.BREAKPOINT;
-    	return status;
+                c.setConflicted( false, null );
+        });
+        if( status != StageStatus.FINISHED && breakPoint )
+            return StageStatus.BREAKPOINT;
+        return status;
     }
     
     private StageStatus calcNextStatus()
@@ -113,7 +113,7 @@ public class ConflictDetection implements AlgorithmStage {
         {
             ((PseudoCodeNode)markNode.getParent()).setSelected( false );
             markNode.setSelected( false );
-        	return StageStatus.FINISHED;
+            return StageStatus.FINISHED;
         }
         actions.get( 0 ).reverse();
         actions.remove( 0 );

+ 50 - 50
src/bk/ExtremalLayoutCalc.java

@@ -15,48 +15,48 @@ import graph.LayeredGraphNode;
  */
 public class ExtremalLayoutCalc implements AlgorithmStage {
 
-	public enum LayoutType{
-		TOP_BOTTOM_LEFT,
-		TOP_BOTTOM_RIGHT,
-		BOTTOM_TOP_LEFT,
-		BOTTOM_TOP_RIGHT,
-		COMBINED
-	}
-	
-	private enum LayoutState
-	{
-		BLOCK_CALCULATION,
-		COMPACTION
-	}
-	
-	private PseudoCodeNode pseudoCode;
-	private BlockCalc bc;
-	private Compaction cp;
-	private LayoutState status;
-	private PseudoCodeNode bcNode;
-	private PseudoCodeNode cpNode;
-	private LayoutType type;
-	private boolean inside;
-	
-	
-	public ExtremalLayoutCalc( LayoutType typ, LayeredGraphNode graph )
-	{
-	    type = typ;
-		status = LayoutState.BLOCK_CALCULATION;
-		bc = new BlockCalc( graph, typ );
-		cp = new Compaction( graph, typ );
-		inside = false;
-	}
-	
-	@Override
-	public StageStatus forwardStep() {
-		return forward( "forwardStep" );
-	}
-
-	@Override
-	public StageStatus backwardStep() {
-		return backward( "backwardStep" );
-	}
+    public enum LayoutType{
+        TOP_BOTTOM_LEFT,
+        TOP_BOTTOM_RIGHT,
+        BOTTOM_TOP_LEFT,
+        BOTTOM_TOP_RIGHT,
+        COMBINED
+    }
+
+    private enum LayoutState
+    {
+        BLOCK_CALCULATION,
+        COMPACTION
+    }
+
+    private PseudoCodeNode pseudoCode;
+    private BlockCalc bc;
+    private Compaction cp;
+    private LayoutState status;
+    private PseudoCodeNode bcNode;
+    private PseudoCodeNode cpNode;
+    private LayoutType type;
+    private boolean inside;
+
+
+    public ExtremalLayoutCalc( LayoutType typ, LayeredGraphNode graph )
+    {
+        type = typ;
+        status = LayoutState.BLOCK_CALCULATION;
+        bc = new BlockCalc( graph, typ );
+        cp = new Compaction( graph, typ );
+        inside = false;
+    }
+
+    @Override
+    public StageStatus forwardStep() {
+        return forward( "forwardStep" );
+    }
+
+    @Override
+    public StageStatus backwardStep() {
+        return backward( "backwardStep" );
+    }
 
     @Override
     public PseudoCodeNode createPseudocodeTree( JTree tree ) {
@@ -135,8 +135,8 @@ public class ExtremalLayoutCalc implements AlgorithmStage {
         try {
             if( status == LayoutState.BLOCK_CALCULATION )
             {
-            	if( !bcNode.isSelected() )
-            		breakpoint |= !bcNode.setSelected( true );
+                if( !bcNode.isSelected() )
+                    breakpoint |= !bcNode.setSelected( true );
                 switch( (StageStatus)(BlockCalc.class.getMethod( fName ).invoke( bc ) ) )
                 {
                 case FINISHED:
@@ -154,8 +154,8 @@ public class ExtremalLayoutCalc implements AlgorithmStage {
             }
             else if( status == LayoutState.COMPACTION )
             {
-            	if( !cpNode.isSelected() )
-            	    breakpoint |= !cpNode.setSelected( true );
+                if( !cpNode.isSelected() )
+                    breakpoint |= !cpNode.setSelected( true );
                 switch( (StageStatus)(Compaction.class.getMethod( fName ).invoke( cp ) ) )
                 {
                 case FINISHED:
@@ -191,8 +191,8 @@ public class ExtremalLayoutCalc implements AlgorithmStage {
         try {
             if( status == LayoutState.BLOCK_CALCULATION )
             {
-            	if( !bcNode.isSelected() )
-            		breakpoint |= !bcNode.setSelected( true );
+                if( !bcNode.isSelected() )
+                    breakpoint |= !bcNode.setSelected( true );
                 switch( (StageStatus)(BlockCalc.class.getMethod( fName ).invoke( bc ) ) )
                 {
                 case FINISHED:
@@ -208,8 +208,8 @@ public class ExtremalLayoutCalc implements AlgorithmStage {
             }
             else if( status == LayoutState.COMPACTION )
             {
-            	if( !cpNode.isSelected() )
-            		breakpoint |= !cpNode.setSelected( true );
+                if( !cpNode.isSelected() )
+                    breakpoint |= !cpNode.setSelected( true );
                 switch( (StageStatus)(Compaction.class.getMethod( fName ).invoke( cp ) ) )
                 {
                 case FINISHED:

+ 1 - 1
src/graph/InitializeNodePositions.java

@@ -18,7 +18,7 @@ public class InitializeNodePositions {
      * @param graph the graph where the node positions are to be set.
      */
     public static void placeNodes( LayeredGraphNode graph ) {
-    	for( LayeredGraphNode n : graph.getContainedNodes() )
+        for( LayeredGraphNode n : graph.getContainedNodes() )
         {
             n.setColor( new Color((int)(Math.random() * 0x1000000)), null );
             placeNodes( n );

+ 28 - 28
src/graph/LayeredEdge.java

@@ -16,14 +16,14 @@ import bk.ExtremalLayoutCalc.LayoutType;
  */
 public class LayeredEdge implements LayeredGraphEdge {
 
-    ElkEdge original;
-    ArrayList< LayeredGraphNode > sources;
-    ArrayList< LayeredGraphNode > targets;
-    LayeredGraphNode graph;
-    boolean reversed;
-    boolean dummy;
-    ArrayList< Point >[] bindPoints;
-    boolean[] conflicted;
+    private ElkEdge original;
+    private ArrayList< LayeredGraphNode > sources;
+    private ArrayList< LayeredGraphNode > targets;
+    private LayeredGraphNode graph;
+    private boolean reversed;
+    private boolean dummy;
+    private ArrayList< Point >[] bindPoints;
+    private boolean[] conflicted;
     
     @SuppressWarnings("unchecked")
     public LayeredEdge( ElkEdge original, ArrayList< LayeredGraphNode > sources, ArrayList< LayeredGraphNode > targets, LayeredGraphNode graph )
@@ -62,27 +62,27 @@ public class LayeredEdge implements LayeredGraphEdge {
     }
     
     @Override
-    public ArrayList<LayeredGraphEdge> calcConflictedEdges()
+    public ArrayList<LayeredGraphEdge> calcEdgeCrossings()
     {
-    	ArrayList<LayeredGraphEdge> list = new ArrayList<>();
-    	ArrayList<LayeredGraphNode> l = graph.getContainedLayers().get( sources.get( 0 ).getLayer() );
-    	ArrayList<LayeredGraphNode> l2 = graph.getContainedLayers().get( targets.get( 0 ).getLayer() );
-    	int startIndex = l.indexOf( sources.get( 0 ) );
-    	int endIndex = l2.indexOf( targets.get( 0 ) );
-    	for( int i = 0; i < l.size(); i++ )
-    	{
-    		if( i == startIndex )
-    			continue;
-    		for( LayeredGraphEdge e : l.get( i ).getOutgoingEdges() )
-    		{
-    			int i2 = l2.indexOf( e.getTargets().get( 0 ) );
-    			if( i2 == endIndex )
-    				continue;
-    			if( i < startIndex && i2 > endIndex || i > startIndex && i2 < endIndex )
-    				list.add( e );
-    		}
-    	}
-    	return list;
+        ArrayList<LayeredGraphEdge> list = new ArrayList<>();
+        ArrayList<LayeredGraphNode> l = graph.getContainedLayers().get( sources.get( 0 ).getLayer() );
+        ArrayList<LayeredGraphNode> l2 = graph.getContainedLayers().get( targets.get( 0 ).getLayer() );
+        int startIndex = l.indexOf( sources.get( 0 ) );
+        int endIndex = l2.indexOf( targets.get( 0 ) );
+        for( int i = 0; i < l.size(); i++ )
+        {
+            if( i == startIndex )
+                continue;
+            for( LayeredGraphEdge e : l.get( i ).getOutgoingEdges() )
+            {
+                int i2 = l2.indexOf( e.getTargets().get( 0 ) );
+                if( i2 == endIndex )
+                    continue;
+                if( i < startIndex && i2 > endIndex || i > startIndex && i2 < endIndex )
+                    list.add( e );
+            }
+        }
+        return list;
     };
     
     @Override

+ 57 - 20
src/graph/LayeredGraphEdge.java

@@ -17,72 +17,109 @@ public interface LayeredGraphEdge {
     /**
      * @return Gibt die originale Kante des Elk Graphen zur�ck
      */
-    ElkEdge getOriginalEdge();
-    
+    public ElkEdge getOriginalEdge();
     
+    /**
+     * Checks whether the edge has been marked as conflicted in the given layout.
+     * @param layout the layout to check
+     * @return whether the edge has been marked as conflicted in the given layout
+     */
     public boolean isConflicted( LayoutType layout );
-    public ArrayList<LayeredGraphEdge> calcConflictedEdges();
+    
+    /**
+     * Computes a list of edges that cross this edge.
+     * @return the list.
+     */
+    public ArrayList<LayeredGraphEdge> calcEdgeCrossings();
+    
+    /**
+     * Mark this edge as conflicted in the given layout.
+     * @param conflicted Whether to mark the edge as conflicted or to remove this mark.
+     * @param layout the layout
+     */
     public void setConflicted( boolean conflicted, LayoutType layout );
     /**
      * Entfernt diese Kante vom Graphen
      */
-    void remove();
+    public void remove();
     /**
      * Gibt eine Liste mit Knoten zur�ck, von welchen die Kante beginnt
      * @return Liste mit Startknoten
      */
-    ArrayList< LayeredGraphNode > getSources();
+    public ArrayList< LayeredGraphNode > getSources();
     /**
      * Gibt eine Liste mit Knoten zur�ck, bei welchen die Kante endet
      * @return Liste mit Endknoten
      */
-    ArrayList< LayeredGraphNode > getTargets();
+    public ArrayList< LayeredGraphNode > getTargets();
     /**
      * Pr�ft, ob die Kante �ber mehrere Layer hinweg geht
      * @return true, falls die Kante �ber mehrere Layer hinweg geht
      */
-    boolean isCrossLayerEdge();
+    public boolean isCrossLayerEdge();
     /**
      * F�r jeden Layer �ber den die Kante geht wird ein Dummy Node erzeugt.
      * Diese werden durch Dummy Kanten verbunden, welche diese Kante ersetzen.
      * Die Kante wird automatisch aus dem Graphen entfernt
      */
-    void replaceByDummyNodes();
+    public void replaceByDummyNodes();
     /**
      * Dreht die Kante um, indem die Startknoten mit den Endknoten getauscht werden
      */
-    void reverse();
-    
-    void setStartPoint( int x, int y, LayoutType layout );
-    void setEndPoint( int x, int y, LayoutType layout );
-    void addBindPoint( int x, int y, LayoutType layout );
-    ArrayList<Point> getLinePoints( LayoutType layout );
+    public void reverse();
+    /**
+     * Set the starting point of this edge in the given layout.
+     * @param x the x coordinate of the starting point
+     * @param y the y coordinate of the starting point
+     * @param layout the layout
+     */
+    public void setStartPoint( int x, int y, LayoutType layout );
+    /**
+     * Set the ending point of this edge in the given layout.
+     * @param x the x coordinate of the ending point
+     * @param y the y coordinate of the ending point
+     * @param layout the layout
+     */
+    public void setEndPoint( int x, int y, LayoutType layout );
+    /**
+     * Adds a bend point for this edge in the given layout.
+     * @param x the x coordinate of the bend point
+     * @param y the y coordinate of the bend point
+     * @param layout the layout
+     */
+    public void addBindPoint( int x, int y, LayoutType layout );
+    /**
+     * Get the list of bend points of this edge in the given layout.
+     * @param layout the layout
+     * @return the list
+     */
+    public ArrayList<Point> getLinePoints( LayoutType layout );
     /**
      * Pr�ft, ob die Kante umgedreht wurde
      * @return true, falls die Kante umgedreht wurde
      */
-    boolean isReversedEdge();
+    public boolean isReversedEdge();
     /**
      * Pr�ft, ob die Kante eine Dummy Kante ist (also ob sie von einem Dummy Knoten startet oder zu einem DummyKnoten hinf�hrt)
      * @return true, falls die Kante eine Dummy Kante ist
      */
-    boolean isDummyEdge();
+    public boolean isDummyEdge();
     /**
      * Ermittelt, welche f�r welche originale Kante diese Kante als Dummykante eingesetzt wurd
      * und entfernt all die Dummynodes und Dummykanten wieder. Anschlie�end wird die alte Kante wieder zum Graphen hinzugef�gt
      */
-    void removeDummyNodes();
+    public void removeDummyNodes();
     /**
      * Legt fest, dass es sich bei dieser Kante um eine Dummykante handelt
      */
-    void setDummyEdge();
+    public void setDummyEdge();
     /**
      * Legt fest, dass es sich bei dieser Kante um eine umgedrehte Kante handelt
      */
-    void setReversedEdge();
+    public void setReversedEdge();
     /**
      * Legt den Graphen fest, zu dem diese Kante geh�rt
      * @param graph Der Graph, zu dem die Kante geh�rt
      */
-    void setGraph( LayeredGraphNode graph );
+    public void setGraph( LayeredGraphNode graph );
 }

+ 427 - 225
src/graph/LayeredGraphNode.java

@@ -9,233 +9,435 @@ import org.eclipse.elk.graph.ElkNode;
 import bk.ExtremalLayoutCalc.LayoutType;
 
 /**
- * Ein Interface, welches die Methoden eines Knotens aus einem gelayerten Graphen beschreibt (Ein Knoten kann dabei auch einen weiteren Graphen beinhalten)
+ * Ein Interface, welches die Methoden eines Knotens aus einem gelayerten
+ * Graphen beschreibt (Ein Knoten kann dabei auch einen weiteren Graphen
+ * beinhalten)
+ * 
  * @author kolja
  *
  */
 public interface LayeredGraphNode {
-    
-    // for this node
-    
-    /**
-     * Gibt den originalen Elk Knoten zur�ck
-     * @return
-     */
-    ElkNode getOriginalNode();
-
-    public void setShift( double shift, LayoutType layout );
-    public double getShift( LayoutType layout );
-    public void setSink( LayeredGraphNode sink, LayoutType layout );
-    public LayeredGraphNode getSink( LayoutType layoutType);
-    public boolean isXUndefined( LayoutType layout );
-    public void setAlignTo( LayeredGraphNode align, LayoutType layout );
-    public LayeredGraphNode getAlignedTo( LayoutType layout );
-    public void setRoot( LayeredGraphNode root, LayoutType layout );
-    public LayeredGraphNode getRoot( LayoutType layout );
-    public void setName( String n );
-    public String getName();
-    public void setColor( Color c, LayoutType layout );
-    public Color getColor( LayoutType layout );
-    public void setSelected( LayoutType layoutType );
-    public boolean isSelected( LayoutType layout );
-    public void setDummyNode( boolean dummy );
-    public boolean isDummyNode();
-    public void unselectGraph();
-    
-    /**
-     * Setzt den Index des Layers, zu dem der Knoten geh�ren soll
-     * @param index Der Index mit 0 beginnend
-     */
-    void setLayer( int index );
-    /**
-     * Gibt den Index des Layers zur�ck, dem dieser Knoten angeh�rt
-     * @return Der Index des Layers mit 0 beginnend
-     */
-    int getLayer();
-    /**
-     * Entfernt den Knoten aus dem Graphen
-     */
-    void remove();
-    /**
-     * Ermittelt eine Liste von Kanten, die an diesem Knoten beginnen
-     * @return Liste mit Kanten
-     */
-    ArrayList< LayeredGraphEdge > getOutgoingEdges();
-    /**
-     * Ermittelt eine Liste von Kanten, die an diesem Knoten enden
-     * @return Liste mit Kanten
-     */
-    ArrayList< LayeredGraphEdge > getIncomingEdges();
-    /**
-     * Ermittelt eine Liste von Kanten, die an diesem Knoten beginnen
-     * @return Liste mit Kanten sortiert nach den positionen der Endknoten in ihrem layer
-     */
-    ArrayList< LayeredGraphEdge > getSortedOutgoingEdges();
-    /**
-     * Ermittelt eine Liste von Kanten, die an diesem Knoten enden
-     * @return Liste mit Kanten sortiert nach den positionen der Startknoten in ihrem layer
-     */
-    ArrayList< LayeredGraphEdge > getSortedIncomingEdges();
-    /**
-     * Gibt den Knoten zur�ck, zu dessen Subgraph dieser Knoten geh�rt
-     * @return Der Elternknoten
-     */
-    LayeredGraphNode parent();
-    /**
-     * Legt den Knoten fest, zu dessen Subgraph dieser Knoten geh�rt
-     * @param parent Der Elternknoten
-     */
-    void setParent( LayeredGraphNode parent );
-    /**
-     * Legt die X Koordinate des Knotens fest
-     * @param x die X Koordinate in Pixeln
-     */
-    void setX( double x, boolean def, LayoutType layout );
-    /**
-     * Legt die Y Koordinate des Knotens Fest
-     * @param y die Y Koordinate in Pixeln
-     */
-    void setY( double y, LayoutType layout );
-    /**
-     * Gibt die X Koordinate zur�ck
-     * @return die X Koordinate in Pixeln zur�ck
-     */
-    double getX( LayoutType layout );
-    /**
-     * Gibt die Y Koordinate zur�ck
-     * @return die Y Koordinate in Pixeln zur�ck
-     */
-    double getY( LayoutType layout );
-    /**
-     * Gibt die Breite des Knotens zur�ck
-     * @return die Breite in Pixeln
-     */
-    double getWidth( LayoutType layout );
-    /**
-     * Gibt die H�he des Knotens zur�ck
-     * @return die H�he in Pixeln
-     */
-    double getHeight( LayoutType layout );
-    
-    void setWidth( double w, LayoutType layout );
-    void setHeight( double h, LayoutType layout );
-    
-    // for subgraph
-    
-    /**
-     * Ermittelt den Index des Layers, dem ein Knoten angeh�rt
-     * @param n der Knoten, zu dem der Layerindex gesucht wird
-     * @return der Index des Layers mit 0 beginnend
-     */
-    int getNodeLayer( LayeredGraphNode n );
-    /**
-     * Sortiert einen Layer nach bestimmten Gewichten
-     * Die Knoten mit dem geringsten Gewicht kommen vor den Knoten mit gr��erem Gewicht
-     * @param indizes Eine Liste mit einem Gewicht f�r jeden Knoten
-     * @param layerIndex Der Index des Layers, der sortiert werden soll
-     */
-    void setOrderedLayer( ArrayList< Double > indizes, int layerIndex );
-    /**
-     * Legt fest zu welchem Layer ein bestimmter Knoten geh�rt
-     * @param n Der Knoten
-     * @param index Der Index des Layers
-     */
-    void setNodeLayer( LayeredGraphNode n, int index );
-    /**
-     * @return Eine Liste mit allen Kanten des Subgraphen
-     */
-    ArrayList< LayeredGraphEdge > getContainedEdges();
-    /**
-     * @return Eine Liste mit allen Knoten des Subgraphen
-     */
-    ArrayList< LayeredGraphNode > getContainedNodes();
-    /**
-     * @return Eine Liste mit allen Knoten des Subgraphen sortiert nach Layern und Positionen
-     */
-    ArrayList< LayeredGraphNode > getSortedContainedNodes();
-    /**
-     * @return Eine Liste mit allen Layern des Subgraphen
-     */
-    ArrayList< ArrayList< LayeredGraphNode > > getContainedLayers();
-    /**
-     * Entfernt eine Kante aus dem Subgraph
-     * @param e die Kante, die entfernt werden soll
-     */
-    void removeEdge( LayeredGraphEdge e );
-    /**
-     * Entfernt einen Knoten aus dem Subgraph
-     * @param n der Knoten, die entfernt werden soll
-     */
-    void removeNode( LayeredGraphNode n );
-    /**
-     * Ermittelt eine Liste von ausgehenden Kanten eines Knotens
-     * @param n Der Knoten
-     * @return Die Liste mit Kanten
-     */
-    ArrayList< LayeredGraphEdge > getOutgoingEdges( LayeredGraphNode n );
-    /**
-     * Ermittelt eine Liste von ausgehenden Kanten eines Knotens
-     * @param n Der Knoten
-     * @return Die Liste mit Kanten sortiert nach den positionen der Endknoten in ihren Layern
-     */
-    ArrayList< LayeredGraphEdge > getSortedOutgoingEdges( LayeredGraphNode n );
-    /**
-     * Ermittelt eine Liste von eingehenden Kanten eines Knotens
-     * @param n Der Knoten
-     * @return Die Liste mit Kanten
-     */
-    ArrayList< LayeredGraphEdge > getIncomingEdges( LayeredGraphNode n );
-    /**
-     * Ermittelt eine Liste von eingehenden Kanten eines Knotens
-     * @param n Der Knoten
-     * @return Die Liste mit Kanten sortiert nach den positionen der Startknoten in ihren Layern
-     */
-    ArrayList< LayeredGraphEdge > getSortedIncomingEdges( LayeredGraphNode n );
-    
-    /**
-     * F�gt einen neuen Knoten zum Subgraph hinzu
-     * @param original Der originale Elk Knoten
-     * @return Der neu erzeugte Knoten
-     */
-    LayeredGraphNode createNode( ElkNode original );
-    /**
-     * F�gt eine neue Kante zum Subgraph hinzu
-     * @param original Die Originale Elk Kante
-     * @param sources Eine Liste mit Startknoten
-     * @param targets Eine Liste mit Endknoten
-     * @return Die neue Kante
-     */
-    LayeredGraphEdge createEdge( ElkEdge original, ArrayList< LayeredGraphNode > sources, ArrayList< LayeredGraphNode > targets );
-    /**
-     * F�gt eine neue Kante zum Subgraph hinzu
-     * @param original Die Originale Elk Kante
-     * @param source Der Startknoten
-     * @param target Der Endknoten
-     * @return Die neue Kante
-     */
-    LayeredGraphEdge createSimpleEdge( ElkEdge original, LayeredGraphNode source, LayeredGraphNode target );
-    /**
-     * Findet zu einer Originalen Kante eine Layered Kante
-     * @param original die originale Kante
-     * @return die layered Kante
-     */
-    LayeredGraphEdge findEdgeFromOriginal( Object original );
-    /**
-     * Findet zu einem Originalen Knoten einen Layered Knoten
-     * @param original der originale Knoten
-     * @return der layered Knoten
-     */
-    LayeredGraphNode findNodeFromOriginal( Object original );
-    
-    LayeredGraphNode findNodeByName( String name );
-    /**
-     * F�gt einen Knoten zum Subgraphen hinzu
-     * @param n Der neue Knoten
-     */
-    void addNode( LayeredGraphNode n );
-    /**
-     * F�gt eine Kante zum Subgraphen hinzu
-     * @param e Die neue Kante
-     */
-    void addEdge( LayeredGraphEdge e );
+  /**
+   * Gibt den originalen Elk Knoten zur�ck
+   * 
+   * @return
+   */
+  public ElkNode getOriginalNode();
+
+  /**
+   * set the shift of this node in the given layout to the given value
+   * 
+   * @param shift
+   *          the value to set to
+   * @param layout
+   *          the layout
+   */
+  public void setShift(double shift, LayoutType layout);
+
+  /**
+   * get the shift of this node in the given layout
+   * 
+   * @param layout
+   *          the layout
+   * @return the shift
+   */
+  public double getShift(LayoutType layout);
+
+  /**
+   * set the sink of this node in the given layout
+   * 
+   * @param sink
+   *          the sink
+   * @param layout
+   *          the layout
+   */
+  public void setSink(LayeredGraphNode sink, LayoutType layout);
+
+  /**
+   * get the sink of this node in the given layout
+   * 
+   * @param layout
+   *          the layout
+   * @return the sink
+   */
+  public LayeredGraphNode getSink(LayoutType layout);
+
+  /**
+   * checks if the x coordinate of the node is defined
+   * 
+   * @param layout
+   *          the layout
+   * @return true iff the x coordinate is undefined
+   */
+  public boolean isXUndefined(LayoutType layout);
+
+  /**
+   * sets the align-attribute (the next node in the block) in the given layout
+   * 
+   * @param align
+   *          the next node in the block
+   * @param layout
+   *          the layout
+   */
+  public void setAlign(LayeredGraphNode align, LayoutType layout);
+
+  /**
+   * get the next node in the block of this node (in the given layout)
+   * 
+   * @param layout
+   *          the layout
+   * @return the next node
+   */
+  public LayeredGraphNode getAlign(LayoutType layout);
+
+  /**
+   * sets the root node of this node in the given layout which identifies the
+   * block that it belongs to
+   * 
+   * @param root
+   *          the new root node
+   * @param layout
+   *          the layout
+   */
+  public void setRoot(LayeredGraphNode root, LayoutType layout);
+
+  /**
+   * get the root node of this node in the given layout which identifies the
+   * block that it belongs to
+   * 
+   * @param layout
+   *          the layout
+   * @return the root node
+   */
+  public LayeredGraphNode getRoot(LayoutType layout);
+
+  /**
+   * set the name of this node
+   * 
+   * @param name
+   *          the name
+   */
+  public void setName(String name);
+
+  /**
+   * get the name of this node
+   * 
+   * @return the name
+   */
+  public String getName();
+
+  /**
+   * set the display color of this node in the given layout
+   * 
+   * @param c
+   *          the color
+   * @param layout
+   *          the layout
+   */
+  public void setColor(Color c, LayoutType layout);
+
+  public Color getColor(LayoutType layout);
+
+  public void setSelected(LayoutType layoutType);
+
+  public boolean isSelected(LayoutType layout);
+
+  public void setDummyNode(boolean dummy);
+
+  public boolean isDummyNode();
+
+  public void unselectGraph();
+
+  /**
+   * Setzt den Index des Layers, zu dem der Knoten geh�ren soll
+   * 
+   * @param index
+   *          Der Index mit 0 beginnend
+   */
+  public void setLayer(int index);
+
+  /**
+   * Gibt den Index des Layers zur�ck, dem dieser Knoten angeh�rt
+   * 
+   * @return Der Index des Layers mit 0 beginnend
+   */
+  public int getLayer();
+
+  /**
+   * Entfernt den Knoten aus dem Graphen
+   */
+  public void remove();
+
+  /**
+   * Ermittelt eine Liste von Kanten, die an diesem Knoten beginnen
+   * 
+   * @return Liste mit Kanten
+   */
+  public ArrayList<LayeredGraphEdge> getOutgoingEdges();
+
+  /**
+   * Ermittelt eine Liste von Kanten, die an diesem Knoten enden
+   * 
+   * @return Liste mit Kanten
+   */
+  public ArrayList<LayeredGraphEdge> getIncomingEdges();
+
+  /**
+   * Ermittelt eine Liste von Kanten, die an diesem Knoten beginnen
+   * 
+   * @return Liste mit Kanten sortiert nach den positionen der Endknoten in
+   *         ihrem layer
+   */
+  public ArrayList<LayeredGraphEdge> getSortedOutgoingEdges();
+
+  /**
+   * Ermittelt eine Liste von Kanten, die an diesem Knoten enden
+   * 
+   * @return Liste mit Kanten sortiert nach den positionen der Startknoten in
+   *         ihrem layer
+   */
+  public ArrayList<LayeredGraphEdge> getSortedIncomingEdges();
+
+  /**
+   * Gibt den Knoten zur�ck, zu dessen Subgraph dieser Knoten geh�rt
+   * 
+   * @return Der Elternknoten
+   */
+  public LayeredGraphNode parent();
+
+  /**
+   * Legt den Knoten fest, zu dessen Subgraph dieser Knoten geh�rt
+   * 
+   * @param parent
+   *          Der Elternknoten
+   */
+  public void setParent(LayeredGraphNode parent);
+
+  /**
+   * Legt die X Koordinate des Knotens fest
+   * 
+   * @param x
+   *          die X Koordinate in Pixeln
+   */
+  public void setX(double x, boolean def, LayoutType layout);
+
+  /**
+   * Legt die Y Koordinate des Knotens Fest
+   * 
+   * @param y
+   *          die Y Koordinate in Pixeln
+   */
+  public void setY(double y, LayoutType layout);
+
+  /**
+   * Gibt die X Koordinate zur�ck
+   * 
+   * @return die X Koordinate in Pixeln zur�ck
+   */
+  public double getX(LayoutType layout);
+
+  /**
+   * Gibt die Y Koordinate zur�ck
+   * 
+   * @return die Y Koordinate in Pixeln zur�ck
+   */
+  public double getY(LayoutType layout);
+
+  /**
+   * Gibt die Breite des Knotens zur�ck
+   * 
+   * @return die Breite in Pixeln
+   */
+  public double getWidth(LayoutType layout);
+
+  /**
+   * Gibt die H�he des Knotens zur�ck
+   * 
+   * @return die H�he in Pixeln
+   */
+  public double getHeight(LayoutType layout);
+
+  public void setWidth(double w, LayoutType layout);
+
+  public void setHeight(double h, LayoutType layout);
+
+  // for subgraph
+
+  /**
+   * Ermittelt den Index des Layers, dem ein Knoten angeh�rt
+   * 
+   * @param n
+   *          der Knoten, zu dem der Layerindex gesucht wird
+   * @return der Index des Layers mit 0 beginnend
+   */
+  public int getNodeLayer(LayeredGraphNode n);
+
+  /**
+   * Sortiert einen Layer nach bestimmten Gewichten Die Knoten mit dem
+   * geringsten Gewicht kommen vor den Knoten mit gr��erem Gewicht
+   * 
+   * @param indizes
+   *          Eine Liste mit einem Gewicht f�r jeden Knoten
+   * @param layerIndex
+   *          Der Index des Layers, der sortiert werden soll
+   */
+  public void setOrderedLayer(ArrayList<Double> indizes, int layerIndex);
+
+  /**
+   * Legt fest zu welchem Layer ein bestimmter Knoten geh�rt
+   * 
+   * @param n
+   *          Der Knoten
+   * @param index
+   *          Der Index des Layers
+   */
+  public void setNodeLayer(LayeredGraphNode n, int index);
+
+  /**
+   * @return Eine Liste mit allen Kanten des Subgraphen
+   */
+  public ArrayList<LayeredGraphEdge> getContainedEdges();
+
+  /**
+   * @return Eine Liste mit allen Knoten des Subgraphen
+   */
+  public ArrayList<LayeredGraphNode> getContainedNodes();
+
+  /**
+   * @return Eine Liste mit allen Knoten des Subgraphen sortiert nach Layern und
+   *         Positionen
+   */
+  public ArrayList<LayeredGraphNode> getSortedContainedNodes();
+
+  /**
+   * @return Eine Liste mit allen Layern des Subgraphen
+   */
+  public ArrayList<ArrayList<LayeredGraphNode>> getContainedLayers();
+
+  /**
+   * Entfernt eine Kante aus dem Subgraph
+   * 
+   * @param e
+   *          die Kante, die entfernt werden soll
+   */
+  public void removeEdge(LayeredGraphEdge e);
+
+  /**
+   * Entfernt einen Knoten aus dem Subgraph
+   * 
+   * @param n
+   *          der Knoten, die entfernt werden soll
+   */
+  public void removeNode(LayeredGraphNode n);
+
+  /**
+   * Ermittelt eine Liste von ausgehenden Kanten eines Knotens
+   * 
+   * @param n
+   *          Der Knoten
+   * @return Die Liste mit Kanten
+   */
+  public ArrayList<LayeredGraphEdge> getOutgoingEdges(LayeredGraphNode n);
+
+  /**
+   * Ermittelt eine Liste von ausgehenden Kanten eines Knotens
+   * 
+   * @param n
+   *          Der Knoten
+   * @return Die Liste mit Kanten sortiert nach den positionen der Endknoten in
+   *         ihren Layern
+   */
+  public ArrayList<LayeredGraphEdge> getSortedOutgoingEdges(LayeredGraphNode n);
+
+  /**
+   * Ermittelt eine Liste von eingehenden Kanten eines Knotens
+   * 
+   * @param n
+   *          Der Knoten
+   * @return Die Liste mit Kanten
+   */
+  public ArrayList<LayeredGraphEdge> getIncomingEdges(LayeredGraphNode n);
+
+  /**
+   * Ermittelt eine Liste von eingehenden Kanten eines Knotens
+   * 
+   * @param n
+   *          Der Knoten
+   * @return Die Liste mit Kanten sortiert nach den positionen der Startknoten
+   *         in ihren Layern
+   */
+  public ArrayList<LayeredGraphEdge> getSortedIncomingEdges(LayeredGraphNode n);
+
+  /**
+   * F�gt einen neuen Knoten zum Subgraph hinzu
+   * 
+   * @param original
+   *          Der originale Elk Knoten
+   * @return Der neu erzeugte Knoten
+   */
+  public LayeredGraphNode createNode(ElkNode original);
+
+  /**
+   * F�gt eine neue Kante zum Subgraph hinzu
+   * 
+   * @param original
+   *          Die Originale Elk Kante
+   * @param sources
+   *          Eine Liste mit Startknoten
+   * @param targets
+   *          Eine Liste mit Endknoten
+   * @return Die neue Kante
+   */
+  public LayeredGraphEdge createEdge(ElkEdge original, ArrayList<LayeredGraphNode> sources,
+      ArrayList<LayeredGraphNode> targets);
+
+  /**
+   * F�gt eine neue Kante zum Subgraph hinzu
+   * 
+   * @param original
+   *          Die Originale Elk Kante
+   * @param source
+   *          Der Startknoten
+   * @param target
+   *          Der Endknoten
+   * @return Die neue Kante
+   */
+  public LayeredGraphEdge createSimpleEdge(ElkEdge original, LayeredGraphNode source,
+      LayeredGraphNode target);
+
+  /**
+   * Findet zu einer Originalen Kante eine Layered Kante
+   * 
+   * @param original
+   *          die originale Kante
+   * @return die layered Kante
+   */
+  public LayeredGraphEdge findEdgeFromOriginal(Object original);
+
+  /**
+   * Findet zu einem Originalen Knoten einen Layered Knoten
+   * 
+   * @param original
+   *          der originale Knoten
+   * @return der layered Knoten
+   */
+  public LayeredGraphNode findNodeFromOriginal(Object original);
+
+  public LayeredGraphNode findNodeByName(String name);
+
+  /**
+   * F�gt einen Knoten zum Subgraphen hinzu
+   * 
+   * @param n
+   *          Der neue Knoten
+   */
+  public void addNode(LayeredGraphNode n);
+
+  /**
+   * F�gt eine Kante zum Subgraphen hinzu
+   * 
+   * @param e
+   *          Die neue Kante
+   */
+  public void addEdge(LayeredGraphEdge e);
 }

+ 32 - 7
src/graph/LayeredNode.java

@@ -3,8 +3,10 @@ package graph;
 import java.awt.Color;
 import java.util.ArrayList;
 
+import org.eclipse.elk.graph.ElkConnectableShape;
 import org.eclipse.elk.graph.ElkEdge;
 import org.eclipse.elk.graph.ElkNode;
+import org.eclipse.emf.common.util.EList;
 
 import bk.ExtremalLayoutCalc.LayoutType;
 
@@ -16,8 +18,6 @@ import bk.ExtremalLayoutCalc.LayoutType;
  *
  */
 public class LayeredNode implements LayeredGraphNode {
-
-    // for this node
     private ElkNode original;
     private LayeredGraphNode parent;
     private boolean dummy;
@@ -50,15 +50,40 @@ public class LayeredNode implements LayeredGraphNode {
         public boolean selected;
     }
     
-    LayoutInfo[] layouts;
-    CombinedLayoutInfo combined;
-    String name;
+    private LayoutInfo[] layouts;
+    private CombinedLayoutInfo combined;
+    private String name;
     
     // for subgraph in this node
     private ArrayList< LayeredGraphEdge > edges;
     private ArrayList< LayeredGraphNode > nodes;
     private ArrayList< ArrayList< LayeredGraphNode > > layers;
     
+    /**
+     * Konvertiert einen Graph aus dem Elk format in einen Graph, der mehr Informationen enthält
+     * @param n Der Graph, welcher konvertiert werden soll
+     * @return Ein layered Graph, welcher im wesentlichen ein Wrapper für den ursprünglichen Graphen ist
+     */
+    public static LayeredGraphNode convertToLayeredGraph( ElkNode n )
+    {
+        LayeredNode ln = new LayeredNode( n, null );
+        for( ElkNode node : n.getChildren() )
+            ln.addNode( convertToLayeredGraph( node ) );
+        for( ElkEdge edge : n.getContainedEdges() )
+        {
+            ArrayList< LayeredGraphNode > sources = new ArrayList<>();
+            ArrayList< LayeredGraphNode > targets = new ArrayList<>();
+            EList<ElkConnectableShape> s = edge.getSources();
+            EList<ElkConnectableShape> t = edge.getTargets();
+            for( ElkConnectableShape shape : s )
+                sources.add( ln.findNodeFromOriginal( shape ) );
+            for( ElkConnectableShape shape : t )
+                targets.add( ln.findNodeFromOriginal( shape ) );
+            ln.createEdge( edge, sources, targets );
+        }
+        return ln;
+    }
+    
     public LayeredNode( ElkNode original, LayeredGraphNode parent )
     {
         this.original = original;
@@ -193,7 +218,7 @@ public class LayeredNode implements LayeredGraphNode {
     }
 
     @Override
-    public void setAlignTo( LayeredGraphNode align, LayoutType layout )
+    public void setAlign( LayeredGraphNode align, LayoutType layout )
     {
         if( layout == null )
         {
@@ -213,7 +238,7 @@ public class LayeredNode implements LayeredGraphNode {
     }
 
     @Override
-    public LayeredGraphNode getAlignedTo( LayoutType layout )
+    public LayeredGraphNode getAlign( LayoutType layout )
     {
         if( layout == LayoutType.TOP_BOTTOM_LEFT )
             return this.layouts[ 0 ].align;

+ 81 - 81
src/graph/io/Reader.java

@@ -20,47 +20,47 @@ import graph.LayeredNode;
  */
 public class Reader {
 
-	private String fileName;
-	
-	public Reader( String inputFileName )
-	{
-		fileName = inputFileName;
-	}
-	
-	/**
-	 * read the JSON file and return its contents as a {@link LayeredGraphNode}
-	 * @return the read {@link LayeredGraphNode}
-	 */
-	public LayeredGraphNode readInputGraph()
-	{
-		String file = "";
-		try {
-			BufferedReader r = new BufferedReader( new FileReader( fileName ) );
-			String tmp = null;
-			while( (tmp = r.readLine()) != null )
-				file += tmp;
-			r.close();
-		} catch (IOException e) {
-			e.printStackTrace();
-		}
-		try {
-			JSONObject json = new JSONObject( file );
-			return parseNode( json, null );
-		} catch (JSONException e) {
-			e.printStackTrace();
-		}
-		return null;
-	}
-	
-	private LayeredGraphNode parseNode( JSONObject node, LayeredGraphNode parent ) throws JSONException
-	{
-		LayeredGraphNode newNode = new LayeredNode( null, null );
-		if( parent != null )
-			newNode = parent.createNode( null );
-		if( node.has( "dummy" ) && node.getBoolean( "dummy" ) )
-		{
-			newNode.setDummyNode( true );
-		}
+    private String fileName;
+
+    public Reader( String inputFileName )
+    {
+        fileName = inputFileName;
+    }
+
+    /**
+     * read the JSON file and return its contents as a {@link LayeredGraphNode}
+     * @return the read {@link LayeredGraphNode}
+     */
+    public LayeredGraphNode readInputGraph()
+    {
+        String file = "";
+        try {
+            BufferedReader r = new BufferedReader( new FileReader( fileName ) );
+            String tmp = null;
+            while( (tmp = r.readLine()) != null )
+                file += tmp;
+            r.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        try {
+            JSONObject json = new JSONObject( file );
+            return parseNode( json, null );
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    private LayeredGraphNode parseNode( JSONObject node, LayeredGraphNode parent ) throws JSONException
+    {
+        LayeredGraphNode newNode = new LayeredNode( null, null );
+        if( parent != null )
+            newNode = parent.createNode( null );
+        if( node.has( "dummy" ) && node.getBoolean( "dummy" ) )
+        {
+            newNode.setDummyNode( true );
+        }
         if( node.has( "name" ) )
         {
             if( parent != null && parent.findNodeByName( node.getString( "name" ) ) != null )
@@ -75,49 +75,49 @@ public class Reader {
             newNode.setHeight( node.getInt( "height" ), null );
         else
             newNode.setHeight( 40, null );
-		if( node.has( "layers" ) )
-		{
-			JSONArray layers = node.getJSONArray( "layers" );
-			for( int i = 0; i < layers.length(); i++ )
-			{
-				for( LayeredGraphNode n : parseLayer( layers.getJSONArray( i ), newNode ) )
-					n.setLayer( i );
-			}
-		}
-		if( node.has( "edges" ) )
-		{
-			JSONArray edges = node.getJSONArray( "edges" );
-			for( int i = 0; i < edges.length(); i++ )
-			{
-				JSONObject edge = edges.getJSONObject( i );
-				newNode.addEdge( parseEdge( edge, newNode ) );
-			}
-		}
-		return newNode;
-	}
-	
-	private LayeredGraphEdge parseEdge( JSONObject edge, LayeredGraphNode parent ) throws JSONException
-	{
-		if( !edge.has( "source" ) || !edge.has( "target" ) )
-			throw new JSONException( edge + " is no valid Layered Graph Edge." );
-		if( parent.findNodeByName( edge.getString( "source" ) ) == null )
+        if( node.has( "layers" ) )
+        {
+            JSONArray layers = node.getJSONArray( "layers" );
+            for( int i = 0; i < layers.length(); i++ )
+            {
+                for( LayeredGraphNode n : parseLayer( layers.getJSONArray( i ), newNode ) )
+                    n.setLayer( i );
+            }
+        }
+        if( node.has( "edges" ) )
+        {
+            JSONArray edges = node.getJSONArray( "edges" );
+            for( int i = 0; i < edges.length(); i++ )
+            {
+                JSONObject edge = edges.getJSONObject( i );
+                newNode.addEdge( parseEdge( edge, newNode ) );
+            }
+        }
+        return newNode;
+    }
+
+    private LayeredGraphEdge parseEdge( JSONObject edge, LayeredGraphNode parent ) throws JSONException
+    {
+        if( !edge.has( "source" ) || !edge.has( "target" ) )
+            throw new JSONException( edge + " is no valid Layered Graph Edge." );
+        if( parent.findNodeByName( edge.getString( "source" ) ) == null )
             throw new JSONException( edge + " is no valid Layered Graph Edge." );
         if( parent.findNodeByName( edge.getString( "target" ) ) == null )
             throw new JSONException( edge + " is no valid Layered Graph Edge." );
         LayeredGraphEdge newEdge = parent.createSimpleEdge( null, parent.findNodeByName( edge.getString( "source" ) ), parent.findNodeByName( edge.getString( "target" ) ) );
         if( parent.findNodeByName( edge.getString( "source" ) ).isDummyNode() && parent.findNodeByName( edge.getString( "target" ) ).isDummyNode() )
-        	newEdge.setDummyEdge();
-		return newEdge;
-	}
-	
-	private ArrayList<LayeredGraphNode> parseLayer( JSONArray layer, LayeredGraphNode parent ) throws JSONException
-	{
-		ArrayList<LayeredGraphNode> nodes = new ArrayList<>();
-		for( int i = 0; i < layer.length(); i++ )
-		{
-			JSONObject node = layer.getJSONObject( i );
-			nodes.add( parseNode( node, parent ) );
-		}
-		return nodes;
-	}
+            newEdge.setDummyEdge();
+        return newEdge;
+    }
+
+    private ArrayList<LayeredGraphNode> parseLayer( JSONArray layer, LayeredGraphNode parent ) throws JSONException
+    {
+        ArrayList<LayeredGraphNode> nodes = new ArrayList<>();
+        for( int i = 0; i < layer.length(); i++ )
+        {
+            JSONObject node = layer.getJSONObject( i );
+            nodes.add( parseNode( node, parent ) );
+        }
+        return nodes;
+    }
 }

+ 1 - 1
src/graph/io/Writer.java

@@ -65,7 +65,7 @@ public class Writer {
         node.put( "edges", edges );
         node.put( "name", graph.getName() );
         if( graph.isDummyNode() )
-        	node.put( "dummy", "true" );
+            node.put( "dummy", "true" );
         return node;
     }
     

+ 6 - 6
src/main/Main.java

@@ -16,11 +16,11 @@ public class Main {
      * Will be run when the application is started.
      * @param args the command line arguments, currently not in use
      */
-	public static void main(String[] args) {
-		Reader r = new Reader( "logo.json" );
-		LayeredGraphNode graph = r.readInputGraph();
-		InitializeNodePositions.placeNodes( graph );
-		new MainView( graph );
-	}
+    public static void main(String[] args) {
+        Reader r = new Reader( "logo.json" );
+        LayeredGraphNode graph = r.readInputGraph();
+        InitializeNodePositions.placeNodes( graph );
+        new MainView( graph );
+    }
 
 }

+ 2 - 2
src/view/EdgeView.java

@@ -68,7 +68,7 @@ public class EdgeView extends JPanel {
     @Override
     public Dimension getPreferredSize()
     {
-    	return new Dimension( getWidth(), getHeight() );
+        return new Dimension( getWidth(), getHeight() );
     }
     
     @Override
@@ -90,7 +90,7 @@ public class EdgeView extends JPanel {
         //System.out.println( "Clipping: x:" + g.getClip().getBounds().getX() + " y:" + g.getClip().getBounds().getY() + " w:" + g.getClip().getBounds().getWidth() + " h:" + g.getClip().getBounds().getHeight() );
         g.setColor( Color.GREEN );
         if( model.isConflicted( layout ) )
-        	g.setColor( Color.RED );
+            g.setColor( Color.RED );
         ArrayList<Point> bps = model.getLinePoints( layout );
         for( int i = 1; i < bps.size(); i++ )
         {

+ 137 - 127
src/view/MainView.java

@@ -35,6 +35,8 @@ import javax.swing.filechooser.FileNameExtensionFilter;
 import javax.swing.tree.DefaultTreeModel;
 import javax.swing.tree.TreePath;
 
+import org.eclipse.elk.graph.ElkNode;
+
 import animation.Action;
 import animation.AnimationController;
 import animation.PseudoCodeNode;
@@ -43,6 +45,7 @@ import bk.ExtremalLayoutCalc.LayoutType;
 import graph.InitializeNodePositions;
 import graph.LayeredGraphEdge;
 import graph.LayeredGraphNode;
+import graph.LayeredNode;
 import graph.RandomGraphGenerator;
 import graph.io.Reader;
 import graph.io.Writer;
@@ -62,7 +65,7 @@ public class MainView {
      */
     private static int frameCounter = 0;
     private JFrame frame;
-	private AnimationController controller;
+    private AnimationController controller;
     private JButton stepForward;
     private JButton stepForwardInto;
     private JButton stepForwardOut;
@@ -80,24 +83,24 @@ public class MainView {
     private JTextField delay;
     public JTree pseudoTree;
     private LayeredGraphNode graph;
-	
-	private String strToLen( String s, int l )
-	{
-		while( s.length() < l )
-		{
-			s = " " + s + " ";
-		}
-		if( s.length() > l )
-			return s.substring( 0, l );
-		return s;
-	}
-	
-	private String debugInfo()
-	{
-	    String info = "Debug Information Table: \n";
-	    info += "_______________________________________________________________________________________________________________________________________________________________________________________________________________________\n";
-	    info += "|" + strToLen( "Top -> Bottom :> Left", 51 ) + "| |" + strToLen( "Top -> Bottom :> Right", 51 ) + "| |" + strToLen( "Bottom -> Top :> Left", 51 ) + "| |" + strToLen( "Bottom -> Top :> Right", 51 ) + "|\n";
-	    info += "|___________________________________________________| |___________________________________________________| |___________________________________________________| |___________________________________________________|\n";
+
+    private String strToLen( String s, int l )
+    {
+        while( s.length() < l )
+        {
+            s = " " + s + " ";
+        }
+        if( s.length() > l )
+            return s.substring( 0, l );
+        return s;
+    }
+
+    private String debugInfo()
+    {
+        String info = "Debug Information Table: \n";
+        info += "_______________________________________________________________________________________________________________________________________________________________________________________________________________________\n";
+        info += "|" + strToLen( "Top -> Bottom :> Left", 51 ) + "| |" + strToLen( "Top -> Bottom :> Right", 51 ) + "| |" + strToLen( "Bottom -> Top :> Left", 51 ) + "| |" + 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() )
         {
@@ -105,59 +108,66 @@ public class MainView {
                     "|" + 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.getAlign( 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.getAlign( 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.getAlign( 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.getAlign( LayoutType.BOTTOM_TOP_RIGHT ).getName(), 7 ) + 
                     "|" + strToLen( n.getX( LayoutType.BOTTOM_TOP_RIGHT ) + "", 5 ) + 
                     "|" + strToLen( !n.isXUndefined( LayoutType.BOTTOM_TOP_RIGHT ) + "", 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 ) );
-	    info.setText( debugInfo() );
-	    JScrollPane view = new JScrollPane( 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 );
-	}
-	
-	/**
-	 * Initialize the window and its contents.
-	 * @param graph the graph that is displayed in this window.
-	 */
-	public MainView( LayeredGraphNode graph )
-	{
-	    frameCounter++;
-	    this.graph = graph;
+        debugFrame.setVisible( true );
+        System.out.println( infoS );
+    }
+
+    public MainView( ElkNode graph )
+    {
+        this( LayeredNode.convertToLayeredGraph( graph ) );
+    }
+
+    /**
+     * Initialize the window and its contents.
+     * @param graph the graph that is displayed in this window.
+     */
+    public MainView( LayeredGraphNode graph )
+    {
+        frameCounter++;
+        this.graph = graph;
         controller = new AnimationController();
         controller.setTimeBetween( 50 );
-        frame = new JFrame();
+        frame = new JFrame( "NodeShuffler" );
         frame.addWindowListener(new java.awt.event.WindowAdapter() {
             @Override
             public void windowClosing(java.awt.event.WindowEvent windowEvent) {
@@ -170,11 +180,11 @@ public class MainView {
         BKNodePlacement algorithm = new BKNodePlacement( controller, graph, frame );
         
         // 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() {
+        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) {
@@ -183,11 +193,11 @@ public class MainView {
             }
             
         });
-	    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() {
+        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) {
@@ -700,34 +710,34 @@ public class MainView {
         treeView.setBounds( 10,  110,  380, 380 );
         
         frame.setSize( (int)graph.getWidth( LayoutType.TOP_BOTTOM_LEFT ) * 2 + 575, (int)graph.getHeight( LayoutType.TOP_BOTTOM_LEFT ) * 2 + 200 );
-		frame.setLocation( 100, 100 );
-		frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
-		frame.setVisible( true );
-		
-		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 );
+        frame.setLocation( 100, 100 );
+        frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
+        frame.setVisible( true );
+
+        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 );
@@ -742,56 +752,56 @@ public class MainView {
         menue.add( randomGraph );
         menue.add( save );
         menue.add( load );
-		frame.add( menue, BorderLayout.EAST );
-		frame.setSize( frame.getWidth() + 1, frame.getHeight() );
+        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 );
-	    		
-	    		layne.remove( pl );
-	            layne.add( pl, 1 );
-	            frame.repaint();
-	        }
-		});
+        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 );
+
+                layne.remove( pl );
+                layne.add( pl, 1 );
+                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 );
-		}
+    }
+
+    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;
-	}
+        return graphView;
+    }
 }

+ 8 - 4
src/view/NiceButton.java

@@ -13,14 +13,18 @@ import java.awt.image.RGBImageFilter;
 import javax.swing.ImageIcon;
 import javax.swing.JButton;
 
+/**
+ * A {@link NiceButton} is a {@link JButton} that has an image on it.
+ * @author kolja
+ *
+ */
 public class NiceButton extends JButton implements MouseListener {
+    private static final long serialVersionUID = 1L;
 
     /**
-     * 
+     * creates a {@link NiceButton}
+     * @param name the name of the image file, e.g. name="test" would correspond to "../img/test.png"
      */
-    private static final long serialVersionUID = 1L;
-
-    
     public NiceButton( String name )
     {
         super( NiceButton.class.getResource( "../img/" + name + ".png" ) != null ? makeColorTransparent( new ImageIcon( NiceButton.class.getResource( "../img/" + name + ".png" ) ).getImage().getScaledInstance( 40, 40, Image.SCALE_AREA_AVERAGING ), Color.WHITE, 0 ) : new ImageIcon() );

+ 54 - 54
src/view/NodeView.java

@@ -20,33 +20,33 @@ import graph.LayeredGraphNode;
  *
  */
 public class NodeView extends JPanel {
-	private static final long serialVersionUID = 1L;
-	private LayeredGraphNode model;
-	private LayoutType layout;
-	
-	public NodeView( LayeredGraphNode model, LayoutType lt ) {
-		this.model = model;
-		layout = lt;
-		setSize( (int)model.getWidth( layout ), (int)model.getHeight( layout ) );
-	}
-	
-	@Override
-	public Point getLocation()
-	{
-	    return new Point( (int)model.getX( layout ), (int)model.getY( layout ) );
-	}
+    private static final long serialVersionUID = 1L;
+    private LayeredGraphNode model;
+    private LayoutType layout;
+
+    public NodeView( LayeredGraphNode model, LayoutType lt ) {
+        this.model = model;
+        layout = lt;
+        setSize( (int)model.getWidth( layout ), (int)model.getHeight( layout ) );
+    }
+
+    @Override
+    public Point getLocation()
+    {
+        return new Point( (int)model.getX( layout ), (int)model.getY( layout ) );
+    }
     
     @Override
     public Dimension getPreferredSize()
     {
-    	return new Dimension( (int)model.getWidth( layout ), (int)model.getHeight( layout ) );
+        return new Dimension( (int)model.getWidth( layout ), (int)model.getHeight( layout ) );
     }
     
     @Override
     public void paint( Graphics g )
     {
-    	if( layout == LayoutType.COMBINED && model.getColor( layout ) == null )
-    		return;
+        if( layout == LayoutType.COMBINED && model.getColor( layout ) == null )
+            return;
         double scale = Math.min( (double)super.getWidth() / (int)model.getWidth( layout ), (double)super.getHeight() / (int)model.getHeight( layout ));
         ((Graphics2D)g).scale( scale, scale );
         paintComponent( g );
@@ -65,40 +65,40 @@ public class NodeView extends JPanel {
         }
     }
 
-	@Override
-	public void paintComponent( Graphics g )
-	{
-		Graphics2D g2 = (Graphics2D)g;
-		g2.setColor( model.getColor( layout ) );
-		g2.setStroke(new BasicStroke(5));
-		if( model.getContainedNodes().size() == 0 )
-		{
-			if( model.getRoot( layout ) == model )
-				g2.fillOval( 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
-			else
-				g2.fillRect( 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
-		}
-		boolean selected = model.isSelected( layout );
-		if( selected )
-		{
-			g.setColor( Color.BLACK );
-			if( model.getContainedNodes().size() > 0 )
-			    g.setColor( Color.GRAY );
-			g.fillRect( 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
-		}
-		Border linebor = BorderFactory.createLineBorder(model.getColor( layout ), 5);
-		if( model.getRoot( layout ) != model || model.getContainedNodes().size() != 0  )
-			linebor.paintBorder( this, g2, 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
-		if( layout != LayoutType.COMBINED && model.getRoot( layout ).getSink( layout ).getColor( layout ) != model.getColor( layout ))
-		{
-    		g.setColor( model.getRoot( layout ).getSink( layout ).getColor( layout ) );
-    		if( model.getContainedNodes().size() == 0 )
-    		{
-    		    if( selected )
-    		        g.fillOval( (int)model.getWidth( layout ) / 2 - (int)model.getWidth( layout ) / 5, (int)model.getHeight( layout ) / 2 - (int)model.getHeight( layout ) / 5, (int)model.getWidth( layout ) / 5 * 2, (int)model.getHeight( layout ) / 5 * 2 );
-    		    else
-    		        g.fillOval( (int)model.getWidth( layout ) / 2 - (int)model.getWidth( layout ) / 3, (int)model.getHeight( layout ) / 2 - (int)model.getHeight( layout ) / 3, (int)model.getWidth( layout ) / 3 * 2, (int)model.getHeight( layout ) / 3 * 2 );
-    		}
-		}
-	}
+    @Override
+    public void paintComponent( Graphics g )
+    {
+        Graphics2D g2 = (Graphics2D)g;
+        g2.setColor( model.getColor( layout ) );
+        g2.setStroke(new BasicStroke(5));
+        if( model.getContainedNodes().size() == 0 )
+        {
+            if( model.getRoot( layout ) == model )
+                g2.fillOval( 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
+            else
+                g2.fillRect( 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
+        }
+        boolean selected = model.isSelected( layout );
+        if( selected )
+        {
+            g.setColor( Color.BLACK );
+            if( model.getContainedNodes().size() > 0 )
+                g.setColor( Color.GRAY );
+            g.fillRect( 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
+        }
+        Border linebor = BorderFactory.createLineBorder(model.getColor( layout ), 5);
+        if( model.getRoot( layout ) != model || model.getContainedNodes().size() != 0  )
+            linebor.paintBorder( this, g2, 0, 0, (int)model.getWidth( layout )-1, (int)model.getHeight( layout )-1 );
+        if( layout != LayoutType.COMBINED && model.getRoot( layout ).getSink( layout ).getColor( layout ) != model.getColor( layout ))
+        {
+            g.setColor( model.getRoot( layout ).getSink( layout ).getColor( layout ) );
+            if( model.getContainedNodes().size() == 0 )
+            {
+                if( selected )
+                    g.fillOval( (int)model.getWidth( layout ) / 2 - (int)model.getWidth( layout ) / 5, (int)model.getHeight( layout ) / 2 - (int)model.getHeight( layout ) / 5, (int)model.getWidth( layout ) / 5 * 2, (int)model.getHeight( layout ) / 5 * 2 );
+                else
+                    g.fillOval( (int)model.getWidth( layout ) / 2 - (int)model.getWidth( layout ) / 3, (int)model.getHeight( layout ) / 2 - (int)model.getHeight( layout ) / 3, (int)model.getWidth( layout ) / 3 * 2, (int)model.getHeight( layout ) / 3 * 2 );
+            }
+        }
+    }
 }

+ 8 - 5
src/view/PseudoCodeRenderer.java

@@ -12,14 +12,17 @@ import javax.swing.tree.TreeNode;
 
 import animation.PseudoCodeNode;
 
+/**
+ * A tree-like display of pseudocode.
+ * Extends {@link DefaultTreeCellRenderer}
+ * @author kolja
+ *
+ */
 public class PseudoCodeRenderer extends DefaultTreeCellRenderer {
-    
-    /**
-     * 
-     */
+
     private static final long serialVersionUID = 1L;
     
-    boolean specialColor = false;
+    private boolean specialColor = false;
 
     @Override
     public Color getBackgroundNonSelectionColor() {

+ 1 - 1
src/view/RenderHelper.java

@@ -12,7 +12,7 @@ import java.awt.geom.AffineTransform;
  */
 public class RenderHelper {
     /**
-     * creates an arrow shape to draw it, for example as an edge.
+     * creates an arrow shape to draw it, for example as part of an edge.
      * @param fromPt the starting point of the arrow
      * @param toPt the destination point of the arrow
      * @return the shape