浏览代码

added runtime debug info in tooltips of pseudocode tree nodes

Kolja Strohm 6 年之前
父节点
当前提交
047672092b

+ 4 - 0
src/animation/AnimatedAlgorithm.java

@@ -88,6 +88,10 @@ public abstract class AnimatedAlgorithm extends Thread implements AlgorithmStage
     @Override
     public abstract PseudoCodeNode createPseudocodeTree( JTree tree );
     
+    public PseudoCodeProcessor getProcessor() {
+        return processor;
+    }
+    
     public String getDebugString()
     {
         if( processor == null )

+ 5 - 0
src/animation/PseudoCodeProcessor.java

@@ -185,6 +185,11 @@ public class PseudoCodeProcessor {
         return status;
     }
     
+    public Memory getMemory()
+    {
+        return mem;
+    }
+    
     public String getDebugOutput()
     {
         return currentDebugOutput;

+ 15 - 0
src/lib/TextLayoutHelper.java

@@ -1,5 +1,9 @@
 package lib;
 
+import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 public class TextLayoutHelper {
     /**
      * Modifies the given string such that its lenght matches the given length.
@@ -57,4 +61,15 @@ public class TextLayoutHelper {
         System.out.println( ret );
         return ret;
     }
+    
+    public static String[] getVariables( String s )
+    {
+        ArrayList<String> list = new ArrayList<>();
+        Matcher m = Pattern.compile( "<font color=#3BB9FF>(.*?)</font>" ).matcher( s );
+        while( m.find())
+        {
+            list.add( s.substring( m.start( 1 ), m.end( 1 ) ) );
+        }
+        return list.toArray( new String[ list.size() ] );
+    }
 }

+ 2 - 0
src/view/MainView.java

@@ -418,6 +418,7 @@ public class MainView {
         pseudoTree.setModel( new DefaultTreeModel( tree ) );
         pseudoTree.setCellRenderer( new PseudoCodeRenderer() );
         pseudoTree.setSelectionModel( null );
+        pseudoTree.setToolTipText("");
         pseudoTree.addMouseListener( new MouseAdapter() {
             public void mousePressed(MouseEvent e) {
                 TreePath selPath = pseudoTree.getPathForLocation(e.getX(), e.getY());
@@ -439,6 +440,7 @@ public class MainView {
             }
         } );
         pseudoTree.setRowHeight(15);
+        ((PseudoCodeRenderer)pseudoTree.getCellRenderer()).setMemory( algorithm.getProcessor().getMemory());
         JScrollPane treeView = new JScrollPane( pseudoTree );
         treeView.setBounds( 10,  110,  390, 380 );
         

+ 57 - 0
src/view/PseudoCodeRenderer.java

@@ -12,7 +12,12 @@ import javax.swing.JTree;
 import javax.swing.tree.DefaultTreeCellRenderer;
 import javax.swing.tree.TreeNode;
 
+import animation.Memory;
+import animation.Memory.MemoryType;
 import animation.PseudoCodeNode;
+import graph.LayeredGraphEdge;
+import graph.LayeredGraphNode;
+import lib.TextLayoutHelper;
 
 /**
  * A tree-like display of pseudocode.
@@ -26,6 +31,14 @@ public class PseudoCodeRenderer extends DefaultTreeCellRenderer {
     private static ImageIcon currentLine = new ImageIcon( PseudoCodeNode.class.getResource( "/img/current_line.png" ) );
     
     private Color specialColor = null;
+    
+    private Memory mem;
+    private String toolTip = "";
+    
+    public void setMemory( Memory m )
+    {
+        mem = m;
+    }
 
     @Override
     public Color getBackgroundNonSelectionColor() {
@@ -76,6 +89,12 @@ public class PseudoCodeRenderer extends DefaultTreeCellRenderer {
         return new Font("Monospaced", Font.PLAIN, 12);
     }
     
+    @Override
+    public String getToolTipText()
+    {
+        return toolTip;
+    }
+    
     @Override
     public Component getTreeCellRendererComponent(JTree tree, Object value, boolean arg2, boolean arg3, boolean arg4, int arg5, boolean arg6) {
 
@@ -118,6 +137,44 @@ public class PseudoCodeRenderer extends DefaultTreeCellRenderer {
             specialColor = RenderHelper.BREAKPOINT_COLOR;
         }
         setText((String)node.getUserObject());
+        toolTip = "<html>";
+        for( String var : TextLayoutHelper.getVariables( (String)node.getUserObject() ) )
+        {
+            if( mem != null && mem.isSomewhereDefined( var, MemoryType.LOCAL ) )
+            {
+                Object val = mem.read( var, MemoryType.LOCAL );
+                String sVal = "";
+                if( val instanceof LayeredGraphNode )
+                {
+                    if( ((LayeredGraphNode)val).getName() == null )
+                        sVal = "unnamed Node";
+                    else
+                        sVal = ((LayeredGraphNode)val).getName();
+                }
+                else if( val instanceof LayeredGraphEdge )
+                {
+                    sVal = "(";
+                    if( ((LayeredGraphEdge)val).getSources().get( 0 ).getName() == null )
+                        sVal += "unnamed Node";
+                    else
+                        sVal += ((LayeredGraphEdge)val).getSources().get( 0 ).getName();
+                    sVal += ",";
+                    if( ((LayeredGraphEdge)val).getTargets().get( 0 ).getName() == null )
+                        sVal += "unnamed Node";
+                    else
+                        sVal += ((LayeredGraphEdge)val).getTargets().get( 0 ).getName();
+                    sVal += ")";
+                }
+                else
+                    sVal = val.toString();
+                toolTip += var + "=" + sVal + "<br>";
+            }
+        }
+        if( toolTip.equals( "<html>" ) )
+            toolTip += "no variables found in the stack";
+        else
+            toolTip = toolTip.substring( 0, toolTip.length() - 4 );
+        toolTip += "</html>";
         return this;
     }