[TeamTalk 127]: [664] TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder: Made an undocked always-on-top version of the map canvas.

tk@edam.speech.cs.cmu.edu tk at edam.speech.cs.cmu.edu
Fri Jul 20 07:34:31 EDT 2007


An HTML attachment was scrubbed...
URL: http://mailman.srv.cs.cmu.edu/pipermail/teamtalk-developers/attachments/20070720/57abb678/attachment-0001.html
-------------- next part --------------
Modified: TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder/MapCanvas.java
===================================================================
--- TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder/MapCanvas.java	2007-07-20 02:49:22 UTC (rev 663)
+++ TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder/MapCanvas.java	2007-07-20 11:34:30 UTC (rev 664)
@@ -20,283 +20,267 @@
 import javax.swing.*;
 import javax.imageio.ImageIO;
 
-public class MapCanvas extends JComponent implements Scrollable {
+/**
+ * Displays a scrollable map with annotations.
+ */
+public class MapCanvas extends JComponent implements Scrollable {    
   
-  protected PenDecoderDisplay drawingPad = null;
-  protected MapCanvasListener drawingCanvasListener;
-  static public String opTraderFrameHolder; //[2005-09-30] (tk): hack
-  
-  /**
-   * The width and height of the area that the map represents (in centimeters)
-   */
-  protected float native_width, native_height;
-  
-  /**
-   * A vector from the upper left corner of the map to the world origin (in centimeters)
-   */
-  protected float x_origin, y_origin;
-  
-  /**
-   * The width and height of the actual map image (in pixels)
-   */
-  protected float image_width_in_pixels, image_height_in_pixels;
-  
-  public MapCanvas() {
-    colorGenerator = new ColorGenerator(new Color[] {
-        Color.BLACK,     //clear space
-        Color.DARK_GRAY, //hash marks
-        Color.GRAY,      //unknown space
-        Color.GREEN,     //obstructed space
-        Color.YELLOW     //highlights
-    });   
-                                                     
-    String mapfile = null;
-    try {
-      Properties properties = new Properties();
-      properties.load(new FileInputStream("map.properties"));
-      mapfile = properties.getProperty("edu.cmu.ravenclaw.pendecoder.mapfile");
-      if(mapfile == null) throw new Exception("mapfile is missing");
-      String widthstr = properties.getProperty("edu.cmu.ravenclaw.pendecoder.mapwidth");
-      if(widthstr == null) throw new Exception("mapwidth is missing");
-      String heightstr = properties.getProperty("edu.cmu.ravenclaw.pendecoder.mapheight");
-      native_width = Float.parseFloat(widthstr);
-      native_height = Float.parseFloat(heightstr);
-    } catch (NumberFormatException e) {
-      System.err.println("Can't parse double:" + e.toString());
-      System.exit(1);
-    } catch (Exception e) {
-      System.err.println("Problem with properties" + e.toString());
-      System.exit(1);
+    /**
+     * Constructor for map canvas.
+     * @param penDecoderDisplay Link to parent class.
+     */
+    public MapCanvas(PenDecoderDisplay penDecoderDisplay) {
+        this.penDecoderDisplay = penDecoderDisplay;
+        
+        colorGenerator = new ColorGenerator(new Color[] {
+            Color.BLACK,     //clear space
+            Color.DARK_GRAY, //hash marks
+            Color.GRAY,      //unknown space
+            Color.GREEN,     //obstructed space
+            Color.YELLOW     //highlights
+        });
+        
+        String mapfile = null;
+        try {
+            Properties properties = new Properties();
+            properties.load(new FileInputStream("map.properties"));
+            mapfile = properties.getProperty("edu.cmu.ravenclaw.pendecoder.mapfile");
+            if(mapfile == null) throw new Exception("mapfile is missing");
+            String widthstr = properties.getProperty("edu.cmu.ravenclaw.pendecoder.mapwidth");
+            if(widthstr == null) throw new Exception("mapwidth is missing");
+            String heightstr = properties.getProperty("edu.cmu.ravenclaw.pendecoder.mapheight");
+            native_width = Float.parseFloat(widthstr);
+            native_height = Float.parseFloat(heightstr);
+        } catch (NumberFormatException e) {
+            System.err.println("Can't parse double:" + e.toString());
+            System.exit(1);
+        } catch (Exception e) {
+            System.err.println("Problem with properties" + e.toString());
+            System.exit(1);
+        }
+        try {
+            backImage = new MapBufferedImage(ImageIO.read(new File(mapfile)));
+            image_width_in_pixels = backImage.getWidth(this);
+            image_height_in_pixels = backImage.getHeight(this);
+            setPreferredSize(new Dimension((int)image_width_in_pixels,
+                    (int)image_height_in_pixels));
+        } catch(Exception e) {
+            System.err.println("Problem reading or converting PNG: " + e.toString());
+            System.exit(1);
+        }
+        mapCanvasListener = new MapCanvasListener(this);
+        addMouseListener((MouseListener) mapCanvasListener);
+        addMouseMotionListener((MouseMotionListener) mapCanvasListener);
     }
-    try {
-      backImage = new MapBufferedImage(ImageIO.read(new File(mapfile)));
-      image_width_in_pixels = backImage.getWidth(this);
-      image_height_in_pixels = backImage.getHeight(this);
-      setPreferredSize(new Dimension((int)image_width_in_pixels, 
-              (int)image_height_in_pixels));
-    } catch(Exception e) {
-      System.err.println("Problem reading or converting PNG: " + e.toString());
-      System.exit(1);
+    
+    /**
+     * Dock components
+     */
+    public void dock() {
+        penDecoderDisplay.dock();
     }
-    drawingCanvasListener = makeCanvasListener();
-    addMouseListener((MouseListener) listener);
-    addMouseMotionListener((MouseMotionListener) listener);
-  }
-  
-  public MapCanvas(Image backImage, PenDecoderDisplay drawingPad) {
-    //calling factory method
-    System.err.println("scribble w/backimage");
-    drawingCanvasListener = makeCanvasListener();
-    addMouseListener((MouseListener) listener);
-    addMouseMotionListener((MouseMotionListener) listener);
-    backImage = new MapBufferedImage(backImage);
-    this.drawingPad = drawingPad;
-  }
-  
-  public MapCanvas(PenDecoderDisplay drawingPad) {
-    this.drawingPad = drawingPad;
-  }
-  
-  public void setTool(Tool tool) {
-    drawingCanvasListener.setTool(tool);
-  }
-  
-  public Tool getTool() {
-    return drawingCanvasListener.getTool();
-  }
-  
-  /**
-   * factory method
-   */
-  protected MapCanvasListener makeCanvasListener() {
-    return new MapCanvasListener(this);
-  }
-  
-  public void saySelectBot(String name) {
-    drawingPad.saySelectBot(name);
-  }
-  
-  public void zoomOut() {
-    int width = getPreferredSize().width;
-    int height = getPreferredSize().height;
-    JViewport viewport = (JViewport) getParent();
-    Dimension d = viewport.getSize();
-    Point center = new Point(
-            viewport.getViewPosition().x+
-            viewport.getExtentSize().width/2,
-            viewport.getViewPosition().y+
-            viewport.getExtentSize().height/2);
-    setPreferredSize(new Dimension(width/2,height/2));
-    setSize(getPreferredSize());
-    revalidate();
-    viewport.setViewPosition(new Point((center.x-d.width)/2, (center.y-d.height)/2));
-  }
-  
-  public void zoomIn(Point p) {
-    int width = getPreferredSize().width;
-    int height = getPreferredSize().height;
-    JViewport viewport = (JViewport) getParent();
-    Dimension d = viewport.getSize();
-    setPreferredSize(new Dimension(width*2,height*2));
-    setSize(getPreferredSize());
-    revalidate();
-    viewport.setViewPosition(new Point(2*(p.x-d.width/4), 2*(p.y-d.height/4)));
-  }
-
-  public void selectBot(String name) {
-    if (shapes != null) {
-      Iterator<Shape> i = shapes.iterator();
-      while(i.hasNext()) {
-        Shape shape = i.next();
-        if(!(shape instanceof BotShape)) continue; 
-        if(name.equalsIgnoreCase("EVERYONE") || name.equalsIgnoreCase(shape.getName())) {
-          shape.highlight();
-        } else {
-          shape.unhighlight();
-        }
-      }
-      repaint();
-    } else {
-      System.err.println("no shapes!");
+    
+    /**
+     * Are we docked?
+     * @return true - docked; false - not docked
+     */
+    public boolean isDocked() {
+        return penDecoderDisplay.isDocked();
     }
-  }
-  
-  /**
-   * this informs the bot that it should be at the screen position and orientation 
-   * indicated by the point
-   */
-  public void placeSelectedBot(Point p, float theta) {
-    screen_to_map.transform(p, p);
-    if(shapes != null) {
-      Iterator<Shape> i = shapes.iterator();
-      while(i.hasNext()) {
-        Shape shape = i.next();
-        if(shape.isSelected()) {
-          BotShape selectedBot = (BotShape) shape;
-          drawingPad.placeBot(shape.getName(), p, theta);
-          return;
-        }
-      }
+    
+    /**
+     * Sets the current tool mode. This is the context in which mouse events are
+     * interpreted.
+     * @param tool The tool mode to set.
+     */
+    public void setTool(Tool tool) {
+        mapCanvasListener.setTool(tool);
     }
-  }
-  
-  public void search(RectangleShape shape) {
-    //find translator bot and do translation here
-    BotShape bot = BotOf(opTraderFrameHolder); //[2005-10-02] (tk): hack
-    AffineTransform placement = bot.getPlacement();
-    try {
-      shape.transform(placement.createInverse());
-    } catch (NoninvertibleTransformException e) {
-      System.err.println("Can't invert transform: " + e.toString());
-      System.exit(1);
+    
+    /**
+     * Gets the current tool mode. This is the context in which mouse events are
+     * interpreted.
+     * @return The current tool mode.
+     */
+    public Tool getTool() {
+        return mapCanvasListener.getTool();
     }
-    drawingPad.search(shape);
-  }
-  
-  public void explore(PolyLineShape shape) {
-    //find translator bot and do translation here
-    System.err.println("exploring here");
-    BotShape bot = BotOf(opTraderFrameHolder); //[2005-10-02] (tk): hack
-    AffineTransform placement = bot.getPlacement();
-    PolyLineShape searchShape = new PolyLineShape(shape);
-    try {
-      searchShape.transform(placement.createInverse());
-    } catch (NoninvertibleTransformException e) {
-      System.err.println("Can't invert transform: " + e.toString());
-      System.exit(1);
+    
+    /**
+     * Inform the penDecoderDisplay (which informs Olympus) that a bot has been
+     * selected.
+     * @param name The name of the selected bot
+     */
+    public void saySelectBot(String name) {
+        penDecoderDisplay.saySelectBot(name);
     }
-    drawingPad.explore(searchShape);
-  }
-  
-  public void search(PolyLineShape shape) {
-    //find translator bot and do translation here
-    System.err.println("searching here");
-    BotShape bot = BotOf(opTraderFrameHolder); //[2005-10-02] (tk): hack
-    AffineTransform placement = bot.getPlacement();
-    PolyLineShape searchShape = new PolyLineShape(shape);
-    try {
-      searchShape.transform(placement.createInverse());
-    } catch (NoninvertibleTransformException e) {
-      System.err.println("Can't invert transform: " + e.toString());
-      System.exit(1);
+    
+    /**
+     * Zoom out on the map display. Virtual eye elevation is doubled.
+     */
+    public void zoomOut() {
+        int width = getPreferredSize().width;
+        int height = getPreferredSize().height;
+        JViewport viewport = (JViewport) getParent();
+        Dimension d = viewport.getSize();
+        Point center = new Point(
+                viewport.getViewPosition().x+
+                viewport.getExtentSize().width/2,
+                viewport.getViewPosition().y+
+                viewport.getExtentSize().height/2);
+        setPreferredSize(new Dimension(width/2,height/2));
+        setSize(getPreferredSize());
+        revalidate();
+        viewport.setViewPosition(new Point((center.x-d.width)/2, (center.y-d.height)/2));
     }
-    drawingPad.search(searchShape);
-  }
-  
-  public BotShape BotOf(String name) {
-    ListIterator<Shape> i = shapes.listIterator();
-    while(i.hasNext()) {
-      Shape shape = i.next();
-      if(shape.getName().equalsIgnoreCase(name)) return (BotShape)shape;
+    
+    /**
+     * Zoom in on the map display. Virtual eye is repositioned directly over the
+     * specified point, then the eye elevation is halved.
+     * @param p The point (in screen coordinates) over which to reposition
+     */
+    public void zoomIn(Point p) {
+        int width = getPreferredSize().width;
+        int height = getPreferredSize().height;
+        JViewport viewport = (JViewport) getParent();
+        Dimension d = viewport.getSize();
+        setPreferredSize(new Dimension(width*2,height*2));
+        setSize(getPreferredSize());
+        revalidate();
+        viewport.setViewPosition(new Point(2*(p.x-d.width/4), 2*(p.y-d.height/4)));
     }
-    return null;
-  }
-  
-  public void debugPoint(Point p) {
-      drawingPad.interpreter.print_human(null, null, "clicked on (pixels): " + p.toString() 
-                + " map coord (cm): " + screen_to_map.transform(p, null).toString()
-                + " map dimentions (pixels): (" + image_width_in_pixels + ", " + image_height_in_pixels + ")"
-                + " map dimentions (cm): (" + native_width + ", " + native_height + ")"
-                + " origin (cm): (" + x_origin + ", " + y_origin + ")");
-  }
-  
-  private static final long serialVersionUID = 2665310629710366124L;
-
+    
     /**
-     * 
-     * The list of shapes of the drawing
+     * Highlight the selected bot(s).
+     * @param name The name of the selected bot.
      */
-    protected List<Shape> shapes = new ArrayList<Shape>();
-
-    protected Color curColor = Color.black;
-
-    protected EventListener listener;
-
-    protected boolean mouseButtonDown = false;
-
-    protected int x;
-
-    protected int y;
-
+    public void selectBot(String name) {
+        if (shapes != null) {
+            for(Shape shape: shapes) {
+                if(!(shape instanceof BotShape)) continue;
+                if(name.equalsIgnoreCase("EVERYONE") || name.equalsIgnoreCase(shape.getName())) {
+                    shape.highlight();
+                } else {
+                    shape.unhighlight();
+                }
+            }
+            repaint();
+        } else {
+            System.err.println("no shapes!");
+        }
+    }
+    
     /**
-     * The image to display as the background (the map)
+     * Inform the bot that it should be at the screen position and orientation
+     * indicated by the point. The frame of reference should be considered the same
+     * as the maps.
+     * @param p The point at which the bot should think it is (units in meters).
+     * @param theta The yaw of which the bot should think it has (units in radians).
      */
-    protected MapBufferedImage backImage = null;
-
+    public void placeSelectedBot(Point p, float theta) {
+        screen_to_map.transform(p, p);
+        if(shapes != null) {
+            Iterator<Shape> i = shapes.iterator();
+            while(i.hasNext()) {
+                Shape shape = i.next();
+                if(shape.isSelected()) {
+                    BotShape selectedBot = (BotShape) shape;
+                    penDecoderDisplay.placeBot(shape.getName(), p, theta);
+                    return;
+                }
+            }
+        }
+    }
+    
     /**
-     * An image of hashmarks for the transparent portions of the backImage
+     * Tell the bots to search within the specified rectangle.
+     * @param shape A rectangle (in screen coordinates)
      */
-    protected BufferedImage hashImage = null;
-
+    public void search(RectangleShape shape) {
+        //find translator bot and do translation here
+        BotShape bot = BotOf(opTraderFrameHolder); //[2005-10-02] (tk): hack
+        AffineTransform placement = bot.getPlacement();
+        try {
+            shape.transform(placement.createInverse());
+        } catch (NoninvertibleTransformException e) {
+            System.err.println("Can't invert transform: " + e.toString());
+            System.exit(1);
+        }
+        penDecoderDisplay.search(shape);
+    }
+    
     /**
-     * The width and height of the rendered map image (in pixels).
-     * The map is streched when the application window grows or during zooming, etc.
+     * Tell the bots to explore along the specified waypoints.
+     * @param shape A set of waypoints (in screen coordinates)
      */
-    protected Dimension view_size;
-
+    public void explore(PolyLineShape shape) {
+        //find translator bot and do translation here
+        System.err.println("exploring here");
+        BotShape bot = BotOf(opTraderFrameHolder); //[2005-10-02] (tk): hack
+        AffineTransform placement = bot.getPlacement();
+        PolyLineShape searchShape = new PolyLineShape(shape);
+        try {
+            searchShape.transform(placement.createInverse());
+        } catch (NoninvertibleTransformException e) {
+            System.err.println("Can't invert transform: " + e.toString());
+            System.exit(1);
+        }
+        penDecoderDisplay.explore(searchShape);
+    }
+    
     /**
-     * A transform from the map image to the rendered map image
-     * The map is streched when the application window grows or during zooming, etc.
+     * Tell the bots to search along the specified waypoints.
+     * @param shape A set of waypoints (in screen coordinates)
      */
-    protected AffineTransform mapScale = new AffineTransform();
-
+    public void search(PolyLineShape shape) {
+        //find translator bot and do translation here
+        System.err.println("searching here");
+        BotShape bot = BotOf(opTraderFrameHolder); //[2005-10-02] (tk): hack
+        AffineTransform placement = bot.getPlacement();
+        PolyLineShape searchShape = new PolyLineShape(shape);
+        try {
+            searchShape.transform(placement.createInverse());
+        } catch (NoninvertibleTransformException e) {
+            System.err.println("Can't invert transform: " + e.toString());
+            System.exit(1);
+        }
+        penDecoderDisplay.search(searchShape);
+    }
+    
     /**
-     * A transform from screen coordinates (pixels, left-handed) 
-     * to map coordinates (centimeters, right-handed)
+     * Find the bot avatar given a bot name.
+     * @param name A bot name.
+     * @return A bot avatar.
      */
-    protected AffineTransform screen_to_map = new AffineTransform();
-
+    public BotShape BotOf(String name) {
+        for(Shape shape: shapes) {
+            if(shape.getName().equalsIgnoreCase(name)) return (BotShape)shape;
+        }
+        return null;
+    }
+    
     /**
-     * A transform from map coordinates (centimeters, right-handed) 
-     * to screen coordinates (pixels, left-handed)
+     * For debugging. Print out some info about where the mouse clicks.
+     * @param p The point of interest.
      */
-    protected AffineTransform map_to_screen = new AffineTransform();
-
+    public void debugPoint(Point p) {
+        penDecoderDisplay.interpreter.print_human(null, null, "clicked on (pixels): " + p.toString()
+        + " map coord (cm): " + screen_to_map.transform(p, null).toString()
+        + " map dimentions (pixels): (" + image_width_in_pixels + ", " + image_height_in_pixels + ")"
+                + " map dimentions (cm): (" + native_width + ", " + native_height + ")"
+                + " origin (cm): (" + x_origin + ", " + y_origin + ")");
+    }
+    
     /**
-     * A class to generate new colors, maximally distinct from an existing set.
+     * Update the map.
+     * @param type Is this a full map or just a diff?
+     * @param x_dim The width of the map (in cells)
+     * @param y_dim The height of the map (in cells)
+     * @param x_origin The vector from the left-hand side of the map to the y-axis
+     * @param y_origin The vector from the top of the map to the x-axis
+     * @param resolution The length of a side of a cell (in centimeters)
+     * @param encoded_map The run-length compressed map
      */
-    public ColorGenerator colorGenerator = null;
-
     public void mapUpdate(int type, int x_dim, int y_dim, float x_origin, float y_origin, int resolution, int[] encoded_map) {
         byte[] decoded_map = new byte[x_dim * y_dim];
         decodeMap(decoded_map, x_dim, y_dim, encoded_map);
@@ -313,7 +297,7 @@
                     for (int i = 0; i < x_dim; i++) {
                         if (j % hashing == 0 || i % hashing == 0)
                             wr.setSample(i, j, 0, 2); else
-                            wr.setSample(i, j, 0, 1);
+                                wr.setSample(i, j, 0, 1);
                     }
                 }
                 setPreferredSize(new Dimension(x_dim, y_dim));
@@ -329,17 +313,24 @@
             repaint();
         } else
             if (type == MapBufferedImage.DIFF) {
-                if (x_dim != image_width_in_pixels || y_dim != image_height_in_pixels) {
-                    System.err.println("diff map for different full map");
-                } else {
-                    backImage.setDiffMap(decoded_map);
-                    repaint();
-                }
+            if (x_dim != image_width_in_pixels || y_dim != image_height_in_pixels) {
+                System.err.println("diff map for different full map");
             } else {
-                System.err.println("unknown map type: " + type);
+                backImage.setDiffMap(decoded_map);
+                repaint();
             }
+            } else {
+            System.err.println("unknown map type: " + type);
+            }
     }
-
+    
+    /**
+     * Perform the run-length decompression as described in boeingLib.
+     * @param decoded_map The byte array in which the decoded map is returned.
+     * @param x The width of the map (in cells)
+     * @param y The height of the map (in cells)
+     * @param encoded_map The run-length compressed map
+     */
     protected void decodeMap(byte[] decoded_map, int x, int y, int[] encoded_map) {
         System.err.println("x: " + x + " y: " + y + " encoded_len: " + encoded_map.length);
         int j = 0, k = 0;
@@ -354,25 +345,52 @@
             k = j;
         }
     }
-
+    
+    /**
+     * Set the canvas color.
+     * @param curColor The new canvas color.
+     */
     public void setCurColor(Color curColor) {
         this.curColor = curColor;
     }
-
+    
+    /**
+     * Get the current canvas color.
+     * @return The current canvas color.
+     */
     public Color getCurColor() {
         return curColor;
     }
-
+    
+    /**
+     * Add an object to the map. These are such things as robots, paths, and other
+     * annotations.
+     * @param shape The object to add.
+     */
     public void addShape(Shape shape) {
         if (shape != null) {
             shapes.add(shape);
         }
     }
-
+    
+    /**
+     * Remove an object from the map.
+     * @param shape The object to remove.
+     */
     public void removeShape(Shape shape) {
         shapes.remove(shape);
     }
-
+    
+    /**
+     * Paint the map.
+     * 1. Transforms the graphics context for the map.
+     * 2. Draw the hash marks.
+     * 3. Draw the map (backImage) on top of the hash marks (hash marks will show
+     *    through on transparent areas of the map).
+     * 4. Transform the graphics context for the shapes.
+     * 5. Draw the shapes and the shape labels.
+     * @param g The graphics context.
+     */
     public void paintComponent(Graphics g) {
         Dimension viewportDim = ((JViewport) getParent()).getExtentSize();
         if (view_size.width < viewportDim.width || view_size.height < viewportDim.height) {
@@ -393,9 +411,7 @@
         shapeG.transform(map_to_screen);
         shapeG.setFont(BotShape.labelFont);
         if (shapes != null) {
-            Iterator iter = shapes.iterator();
-            while (iter.hasNext()) {
-                Shape shape = (Shape) iter.next();
+            for(Shape shape: shapes) {
                 if (shape != null) {
                     shape.draw(shapeG);
                     if (shape instanceof BotShape) {
@@ -405,46 +421,20 @@
             }
         }
     }
-
-    public void newFile() {
-        shapes.clear();
-        repaint();
-    }
-
-    public void openFile(String filename) {
-        try {
-            ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename));
-            try {
-                List l = (List) in.readObject();
-                Iterator li = l.iterator();
-                while (li.hasNext()) {
-                    shapes.add((Shape) li.next());
-                }
-            } catch (Exception e) {
-                System.err.println("Some problem with reading: " + e);
-            }
-            in.close();
-            repaint();
-        } catch (IOException e1) {
-            System.out.println("Unable to open file: " + filename);
-        }
-    }
-
-    public void saveFile(String filename) {
-        try {
-            ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(filename));
-            out.writeObject(shapes);
-            out.close();
-            System.out.println("Save drawing to " + filename);
-        } catch (IOException e) {
-            System.out.println("Unable to write file: " + filename);
-        }
-    }
-
+    
+    /**
+     * Get the transform from the screen (this JComponent) frame to the map's frame.
+     * @return An affine tranform from the screen frame to the map frame.
+     */
     public AffineTransform getScreenToMap() {
         return screen_to_map;
     }
-
+    
+    /**
+     * Select the object at a point.
+     * @param p A point inside an object.
+     * @return The selected object.
+     */
     public String selectObj(Point p) {
         String retval = null;
         screen_to_map.transform(p, p);
@@ -463,7 +453,11 @@
         }
         return retval;
     }
-
+    
+    /**
+     * When the size of the component chages, update the map and object transforms.
+     * @param d The preferred size of the component (in pixels)
+     */
     public void setPreferredSize(Dimension d) {
         view_size = d;
         map_to_screen.setToScale(view_size.width / native_width, view_size.height / native_height);
@@ -473,33 +467,167 @@
         } catch (NoninvertibleTransformException e) {
             System.err.println("couldn't build map_to_screen");
         }
-        mapScale.setToScale(view_size.width / image_width_in_pixels, view_size.height / image_height_in_pixels);
-        mapScale.translate(0, image_height_in_pixels);
+        mapScale.setToScale(view_size.width / image_width_in_pixels, -view_size.height / image_height_in_pixels);
+        mapScale.translate(0, -image_height_in_pixels);
     }
-
+    
+    /**
+     * Get the current preffered size of the component.
+     * @return the current view size (in pixels)
+     */
     public Dimension getPreferredSize() {
         return view_size;
     }
-
+    
+    /**
+     * Get the scrollable viewport size.
+     * @return The dimentions of the scrollable viewport.
+     */
     public Dimension getPreferredScrollableViewportSize() {
         return getPreferredSize();
     }
-
+    
+    /**
+     * Get the scrollable unit increment. How many pixels to we scroll when someone
+     * click on the arrow keys.
+     * @param visibleRect The current visible rectangle
+     * @param orientation The current orientation
+     * @param direction The direction that we'd like to scroll
+     * @return Always returns 1.
+     */
     public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
         return 1;
     }
-
+    
+    /**
+     * Get the scrollable block increment. How many pixels do we scroll when the
+     * mouse wheel is used. Or is it pgup pgdn?
+     * @param visibleRect The current visible rectangle
+     * @param orientation The current orientation
+     * @param direction The direction that we'd like to scroll
+     * @return Returns half of the visible region. E.g. the former extent becomes
+     * centered.
+     */
     public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
         if (orientation == SwingConstants.VERTICAL)
             return visibleRect.height / 2; else
-            return visibleRect.width / 2;
+                return visibleRect.width / 2;
     }
-
+    
+    /**
+     * We don't want a scroll track.
+     * @return false
+     */
     public boolean getScrollableTracksViewportWidth() {
         return false;
     }
-
+    
+    /**
+     * We don't want a scroll track.
+     * @return false
+     */
     public boolean getScrollableTracksViewportHeight() {
         return false;
     }
+
+    /**
+     * An entry point that displays a static map
+     * @param args Unused.
+     */
+    public static void main(String[] args) {
+        JScrollPane pane = new JScrollPane(new MapCanvas(null));
+        pane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
+        pane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
+        JRootPane root = new JRootPane();
+        root.setContentPane(pane);
+        JFrame frame = new JFrame();
+        frame.getContentPane().add(root);
+        frame.validate();
+        frame.setVisible(true);
+    }
+    
+    /**
+     * Link to parent class
+     */
+    protected PenDecoderDisplay penDecoderDisplay = null;
+    
+    /**
+     * Canvas mouse event listener
+     */
+    protected MapCanvasListener mapCanvasListener;
+    
+    /**
+     * hack
+     */
+    static public String opTraderFrameHolder;
+    
+    /**
+     * The width and height of the area that the map represents (in centimeters)
+     */
+    protected float native_width, native_height;
+    
+    /**
+     * A vector from the upper left corner of the map to the world origin (in centimeters)
+     */
+    protected float x_origin, y_origin;
+    
+    /**
+     * The width and height of the actual map image (in pixels)
+     */
+    protected float image_width_in_pixels, image_height_in_pixels;
+
+    /**
+     * The list of objects or annotations to the map.
+     */
+    protected List<Shape> shapes = new ArrayList<Shape>();
+    
+    /**
+     * The current canvas color.
+     */
+    protected Color curColor = Color.black;
+    
+    protected int x;
+    
+    protected int y;
+    
+    /**
+     * The image to display as the background (the map)
+     */
+    protected MapBufferedImage backImage = null;
+    
+    /**
+     * An image of hashmarks for the transparent portions of the backImage
+     */
+    protected BufferedImage hashImage = null;
+    
+    /**
+     * The width and height of the rendered map image (in pixels).
+     * The map is streched when the application window grows or during zooming, etc.
+     */
+    protected Dimension view_size;
+    
+    /**
+     * A transform from the map image to the rendered map image
+     * The map is streched when the application window grows or during zooming, etc.
+     */
+    protected AffineTransform mapScale = new AffineTransform();
+    
+    /**
+     * A transform from screen coordinates (pixels, left-handed)
+     * to map coordinates (centimeters, right-handed)
+     */
+    protected AffineTransform screen_to_map = new AffineTransform();
+    
+    /**
+     * A transform from map coordinates (centimeters, right-handed)
+     * to screen coordinates (pixels, left-handed)
+     */
+    protected AffineTransform map_to_screen = new AffineTransform();
+    
+    /**
+     * A class to generate new colors, maximally distinct from an existing set.
+     */
+    public ColorGenerator colorGenerator = null;
+    
+    private static final long serialVersionUID = 2665310629710366124L;
 }

Modified: TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder/MapCanvasListener.java
===================================================================
--- TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder/MapCanvasListener.java	2007-07-20 02:49:22 UTC (rev 663)
+++ TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder/MapCanvasListener.java	2007-07-20 11:34:30 UTC (rev 664)
@@ -1,66 +1,134 @@
-package edu.cmu.ravenclaw.pendecoder; 
+package edu.cmu.ravenclaw.pendecoder;
 
 import java.awt.*;
 import java.awt.event.*;
 
-public class MapCanvasListener implements MouseListener, MouseMotionListener  { 
-
-  protected MapCanvas canvas; 
-  protected Tool tool; 
-
-  public MapCanvasListener(MapCanvas canvas) { 
-    this.canvas = canvas; 
-    tool = new DrawingTool(canvas, "Scribble"); 
-  }
-
-  public void mousePressed(MouseEvent e) {
-    Point p = e.getPoint(); 
-    tool.mouseDownAt(p);    
-    canvas.mouseButtonDown = true;
-    canvas.x = p.x; 
-    canvas.y = p.y; 
-  } 
-
-  public void mouseDragged(MouseEvent e) {
-    Point p = e.getPoint(); 
-    if (canvas.mouseButtonDown) {
-      tool.mouseDraggedTo(p);
-      canvas.x = p.x; 
-      canvas.y = p.y; 
-    }       
-  }
-
-  public void mouseReleased(MouseEvent e) {
-    Point p = e.getPoint(); 
-    tool.mouseReleasedAt(p);       
-    canvas.mouseButtonDown = false;       
-  }    
-  
-  public void mouseClicked(MouseEvent e) {
-    Point p = e.getPoint();
-    if(e.getClickCount() == 1) {
-      if(e.getButton() == e.BUTTON1)
-        tool.mouseClickedAt(p);
-      else
-        tool.mouseRightClickedAt(p);
-    } else {
-        tool.mouseDoubleClickedAt(p);
+/**
+ * Listener for mouse events on the map canvas. Mostly just keeps track of mouse
+ * state and calls the appropriate tool methods.
+ */
+public class MapCanvasListener implements MouseListener, MouseMotionListener  {
+    
+    /**
+     * The map canvas that we're listening to mouse events for.
+     */
+    protected MapCanvas canvas;
+    
+    /**
+     * The current tool, or mouse event context.
+     */
+    protected Tool tool;
+    
+    /**
+     * Is the mouse button down? We keep track of this to distinguish mouseovers
+     * from drags.
+     */
+    protected boolean mouseButtonDown = false;
+    
+    /**
+     * Constructor for the map cnvas listener.
+     * @param canvas The map canvas that we are listening to mouse events for.
+     */
+    public MapCanvasListener(MapCanvas canvas) {
+        this.canvas = canvas;
+        tool = null;
     }
-  }
-  
-  public void mouseEntered(MouseEvent e) {}  
-  public void mouseExited(MouseEvent e) {}
-  public void mouseMoved(MouseEvent e) {
-    Point p = e.getPoint();
-    tool.mouseMovedTo(p);
-  }     
-
-  public Tool getTool() { 
-    return tool; 
-  }
-
-  public void setTool(Tool tool) { 
-    this.tool = tool;
-  }
-
+    
+    /**
+     * Catch mouse pressed events.
+     * @param e The event.
+     */
+    public void mousePressed(MouseEvent e) {
+        if(canvas.isDocked()) {
+            Point p = e.getPoint();
+            if (tool != null) tool.mouseDownAt(p);
+            mouseButtonDown = true;
+            canvas.x = p.x;
+            canvas.y = p.y;
+        } else {
+            canvas.dock();
+        }
+    }
+    
+    /**
+     * Catch mouse pressed dragged.
+     * @param e The event.
+     */
+    public void mouseDragged(MouseEvent e) {
+        if(canvas.isDocked()) {
+            Point p = e.getPoint();
+            if (mouseButtonDown) {
+                if (tool != null) tool.mouseDraggedTo(p);
+                canvas.x = p.x;
+                canvas.y = p.y;
+            }
+        }
+    }
+    
+    /**
+     * Catch mouse released events.
+     * @param e The event.
+     */
+    public void mouseReleased(MouseEvent e) {
+        if(canvas.isDocked()) {
+            Point p = e.getPoint();
+            if (tool != null) tool.mouseReleasedAt(p);
+            mouseButtonDown = false;
+        }
+    }
+    
+    /**
+     * Catch mouse clicked events.
+     * @param e The mousepressed event.
+     */
+    public void mouseClicked(MouseEvent e) {
+        if(canvas.isDocked()) {
+            Point p = e.getPoint();
+            if(tool == null) return;
+            if(e.getClickCount() == 1) {
+                if(e.getButton() == e.BUTTON1)
+                    tool.mouseClickedAt(p);
+                else
+                    tool.mouseRightClickedAt(p);
+            } else {
+                tool.mouseDoubleClickedAt(p);
+            }
+        } else {
+            canvas.dock();
+        }
+    }
+    
+    /**
+     * Catch mouse entered events. We do nothing.
+     * @param e The event.
+     */
+    public void mouseEntered(MouseEvent e) {}
+    
+    /**
+     * Catch mouse exited events. We do nothing.
+     * @param e The event.
+     */
+    public void mouseExited(MouseEvent e) {}
+    
+    /**
+     * Catch mouse moved events. We do nothing.
+     * @param e The event.
+     */
+    public void mouseMoved(MouseEvent e) {}
+    
+    /**
+     * Get the current tool.
+     * @return The current tool.
+     */
+    public Tool getTool() {
+        return tool;
+    }
+    
+    /**
+     * Set the current tool.
+     * @param The new tool.
+     */
+    public void setTool(Tool tool) {
+        this.tool = tool;
+    }
 }

Modified: TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder/PenDecoderDisplay.java
===================================================================
--- TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder/PenDecoderDisplay.java	2007-07-20 02:49:22 UTC (rev 663)
+++ TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder/PenDecoderDisplay.java	2007-07-20 11:34:30 UTC (rev 664)
@@ -3,7 +3,6 @@
 import java.awt.*;
 import java.awt.event.*;
 import java.awt.image.BufferedImage;
-import java.util.*;
 import javax.swing.*;
 
 import bsh.util.JConsole;
@@ -14,7 +13,7 @@
  * (MapCanvas), the console, the tool buttons, and the camera images
  * (imager).
  */
-public class PenDecoderDisplay extends JFrame {
+public class PenDecoderDisplay {
     
     /**
      * Constrcuct the components of the drawing pad: console, map,
@@ -22,42 +21,27 @@
      * @param title The title for the JFrame (when docked)
      */
     public PenDecoderDisplay(String title) {
-        super(title);
-        // calling factory method
-        drawingCanvas = makeCanvas();
-        getContentPane().setLayout(new BorderLayout());
+        //menu bar
         menuBar = createMenuBar();
-        getContentPane().add(menuBar, BorderLayout.NORTH);
-        pane = new JScrollPane(drawingCanvas);
-        JRootPane rootPane = new JRootPane();
-        rootPane.setContentPane(pane);
-        LogoViewport logopane = new LogoViewport();
-        rootPane.setGlassPane(logopane);
-        logopane.setVisible(true);
-        pane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
-        pane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
-        getContentPane().add(rootPane, BorderLayout.CENTER);
-        addWindowListener(new WindowAdapter() {
-            public void windowClosing(WindowEvent e) {
-                if (exitAction != null) {
-                    exitAction.actionPerformed(new ActionEvent(PenDecoderDisplay.this, 0, null));
-                }
-            }
-        });
         
-        //add toolbar
+        //map canvas
+        mapCanvas = new MapCanvas(this);
+
+        //toolbar
         toolkit = createToolkit();
-        drawingCanvas.setTool(toolkit.getTool(0));
+        mapCanvas.setTool(toolkit.getTool(0));
         ActionListener toolListener = new ActionListener() {
             public void actionPerformed(ActionEvent event) {
                 Object source = event.getSource();
                 if (source instanceof AbstractButton) {
                     AbstractButton button = (AbstractButton) source;
                     Tool tool = toolkit.setSelectedTool(button.getText());
-                    drawingCanvas.setTool(tool);
+                    mapCanvas.setTool(tool);
                     try {
                         if(tool.getName() == "Zoom Out") {
-                            drawingCanvas.zoomOut();
+                            mapCanvas.zoomOut();
+                        } else if(tool.getName() == "Undock") {
+                            undock();
                         } else if(tool.getName() == "Cancel Task") {
                             Integer lastAdded = taskKeeper.getLastAdded();
                             if(lastAdded == null) System.err.println("There are no tasks.");
@@ -79,34 +63,156 @@
             }
         };
         toolbar = createToolBar(toolListener);
-        getContentPane().add(toolbar, BorderLayout.WEST);
         
-        JPanel lowerContainer = new JPanel(new BorderLayout());
-        
-        //add console to lowerContainer
-        JConsole console = new JConsole();
-        console.setPreferredSize(new Dimension(1000, 100));
+        //console
+        console = new JConsole();
+        console.setPreferredSize(new Dimension(2000, 100));
         console.getViewport().getView().setBackground(Color.black);
         console.getViewport().getView().setForeground(Color.white);
-        lowerContainer.add(console, BorderLayout.CENTER);
         interpreter = new DecoderInterpreter(console, this);
         interpreter.start();
         
-        //add imager
+        //imager
         imager = new Imager();
+        
+        buildUndockedFrames();
+        buildDockedFrame(title);
+        
+        undock();
+    }
+    
+    /**
+     * Undock components
+     */
+    public void undock() {
+        dockedFrame.setVisible(false);
+        dockSize = mapCanvas.getPreferredSize();
+        JViewport viewport = (JViewport) mapCanvas.getParent();
+        Dimension oldViewSize = null;
+        if(viewport != null) {
+            dockAnchor = viewport.getViewPosition();
+            oldViewSize = viewport.getSize();
+            dockedRootPane.setContentPane(new JPanel());
+        
+            //zoom out
+            Dimension newSize = new Dimension(dockSize.width*320/oldViewSize.width, 
+                    dockSize.height*320/oldViewSize.width);
+            Dimension newViewSize = new Dimension(320, 
+                    320*oldViewSize.height/oldViewSize.width);
+            mapCanvas.setPreferredSize(newSize);
+            mapCanvas.setSize(newSize);
+            Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+            mapCanvasFrame.setBounds(0, screenSize.height-newViewSize.height,
+                    newViewSize.width, newViewSize.height);
+        }
+        
+        JScrollPane pane = new JScrollPane(mapCanvas);
+        pane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
+        pane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
+        mapCanvasFrame.setContentPane(pane);
+        if(oldViewSize != null) 
+            pane.getViewport().setViewPosition(new Point(dockAnchor.x*320/oldViewSize.width,
+                    dockAnchor.y*320/oldViewSize.width));
+        mapCanvasFrame.setVisible(true);
+        docked = false;
+    }
+    
+    /**
+     * Dock components
+     */
+    public void dock() {
+        mapCanvasFrame.setVisible(false);
+        mapCanvasFrame.setContentPane(new JPanel());
+        mapCanvas.setPreferredSize(dockSize);
+        mapCanvas.setSize(dockSize);
+        JScrollPane pane = new JScrollPane(mapCanvas);
+        pane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
+        pane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
+        dockedRootPane.setContentPane(pane);
+        if(dockAnchor != null) pane.getViewport().setViewPosition(dockAnchor);
+        dockedFrame.setVisible(true);
+        docked = true;
+    }
+    
+    /**
+     * Are we docked?
+     * @return true - docked; false - not docked
+     */
+    public boolean isDocked() {
+        return docked;
+    }
+    
+    /**
+     * Build the docked root JFrame
+     * @param title The title for the JFrame
+     * @return The docked root JFrame
+     */
+    protected JFrame buildDockedFrame(String title) {
+        dockedFrame = new JFrame(title);
+        dockedFrame.getContentPane().setLayout(new BorderLayout());
+        
+        //menu bar
+        dockedFrame.getContentPane().add(menuBar, BorderLayout.NORTH);
+        dockedFrame.addWindowListener(new WindowAdapter() {
+            public void windowClosing(WindowEvent e) {
+                if (exitAction != null) {
+                    exitAction.actionPerformed(new ActionEvent(PenDecoderDisplay.this, 0, null));
+                }
+            }
+        });
+
+        //map canvas
+        LogoViewport logopane = new LogoViewport();
+        logopane.setVisible(true);
+        dockedRootPane = new JRootPane();
+        dockedRootPane.setGlassPane(logopane);
+        dockedFrame.getContentPane().add(dockedRootPane, BorderLayout.CENTER);
+        
+        //toolbar
+        dockedFrame.getContentPane().add(toolbar, BorderLayout.WEST);
+        
+        //console and imager
+        JPanel lowerContainer = new JPanel(new BorderLayout());
+        lowerContainer.add(console, BorderLayout.CENTER);
         lowerContainer.add(imager, BorderLayout.EAST);
+        dockedFrame.getContentPane().add(lowerContainer, BorderLayout.SOUTH);
         
-        //add lowerContainer to this
-        getContentPane().add(lowerContainer, BorderLayout.SOUTH);
+        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+        dockedFrame.setSize(screenSize.width/2, screenSize.height/2);
+        dockedFrame.setLocation(screenSize.width/4, screenSize.height/4);
+        dockedFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);
+
+        return dockedFrame;
     }
+
+    /**
+     * Builds the undocked frames
+     */
+    protected void buildUndockedFrames() {
+        mapCanvasFrame = new JFrame();
+        mapCanvasFrame.setUndecorated(true);
+        mapCanvasFrame.setAlwaysOnTop(true);
+        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+        mapCanvasFrame.setBounds(0, screenSize.height-200, 320, 200);
+    }
     
     /**
+     * Repaints things based on docked or non-docked
+     */
+    public void repaint() {
+        if(docked) {
+            dockedFrame.repaint();
+        }
+    }
+    /**
      * Replace camera image in imager.
      * @param i image to paint in imager panel
      */
     public void image(BufferedImage i) {
         imager.setImage(i);
-        getRootPane().revalidate();
+        if(docked) {
+            dockedFrame.getRootPane().revalidate();
+        }
         imager.repaint();
     }
     
@@ -123,7 +229,7 @@
      * @param encoded_map the map, which may be compressed or otherwize encoded
      */
     public void mapUpdate(int type, int x_dim, int y_dim, float x_origin, float y_origin, int resolution, int[] encoded_map) {
-        drawingCanvas.mapUpdate(type, x_dim, y_dim, x_origin, y_origin, resolution, encoded_map);
+        mapCanvas.mapUpdate(type, x_dim, y_dim, x_origin, y_origin, resolution, encoded_map);
     }
     
     /**
@@ -154,44 +260,37 @@
      */
     protected ToolKit createToolkit() {
         ToolKit t = new ToolKit();
-        t.addTool(new ToggleButtonTool(drawingCanvas,
+        t.addTool(new ToggleButtonTool(mapCanvas,
                 "Start Session",
                 "Click to start speaking",
                 "Stop Session",
                 "Click to mute"));
-        t.addTool(new PointTool(drawingCanvas,
+        t.addTool(new PointTool(mapCanvas,
                 "Select",
                 "Click on a robot to select it.",
                 PointTool.POINT));
-        t.addTool(new PlacementTool(drawingCanvas,
+        t.addTool(new PlacementTool(mapCanvas,
                 "Re-position",
                 "Click to reposition the selected robot. Drag to orient it at the new position."));
-        t.addTool(new PointTool(drawingCanvas,
+        t.addTool(new PointTool(mapCanvas,
                 "Zoom In",
                 "Click to zoom into a point on the map.",
                 PointTool.ZOOMIN));
-        t.addTool(new ButtonTool(drawingCanvas, "Zoom Out", "Zoom out to see the entire map."));
-        t.addTool(new ButtonTool(drawingCanvas, "Cancel Task", "Cancel the last task."));
-        t.addTool(new NPointTool(drawingCanvas,
+        t.addTool(new ButtonTool(mapCanvas, "Zoom Out", "Zoom out to see the entire map."));
+        t.addTool(new ButtonTool(mapCanvas, "Cancel Task", "Cancel the last task."));
+        t.addTool(new NPointTool(mapCanvas,
                 "Search",
                 "Select waypoints along which to search.",
                 NPointTool.POLYLINE));
-        t.addTool(new NPointTool(drawingCanvas,
+        t.addTool(new NPointTool(mapCanvas,
                 "Explore",
                 "Select waypoints along which to explore.",
                 NPointTool.POLYLINE_EXPLORE));
+        t.addTool(new ButtonTool(mapCanvas, "Undock", "Click to undock application components."));
         return t;
     }
     
     /**
-     * Factory method for the map
-     * @return The map canvas.
-     */
-    protected MapCanvas makeCanvas() {
-        return (drawingCanvas = new MapCanvas(this));
-    }
-    
-    /**
      * Sends text out to each of the PenDecoderServers. The text is interpreted
      * as if it were a transcription of what the user said. This is mostly used
      * via the console as a debugging tool.
@@ -228,7 +327,7 @@
      * @param name The name of the bot.
      */
     public void selectBot(String name) {
-        drawingCanvas.selectBot(name);
+        mapCanvas.selectBot(name);
     }
     
     /**
@@ -291,7 +390,7 @@
      * @return The map canvas.
      */
     public MapCanvas getCanvas() {
-        return drawingCanvas;
+        return mapCanvas;
     }
     
     /**
@@ -390,19 +489,9 @@
      */
     public static void main(String[] args) {
         PenDecoderDisplay frame = new PenDecoderDisplay("Treasure Hunt GUI");
-        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
-        frame.setSize(screenSize.width/2, screenSize.height/2);
-        frame.setLocation(screenSize.width/4, screenSize.height/4);
-        frame.setExtendedState(MAXIMIZED_BOTH);
-        frame.setVisible(true);
     }
     
     /**
-     * The scrolling pane that houses the map canvas.
-     */
-    protected JScrollPane pane;
-    
-    /**
      * The menu bar (only shown in docked mode)
      */
     protected JMenuBar menuBar;
@@ -435,7 +524,7 @@
     /**
      * The canvas that displays the map and its annotations.
      */
-    protected MapCanvas drawingCanvas;
+    protected MapCanvas mapCanvas;
     
     /**
      * The object that interprets typed text in the console.
@@ -455,6 +544,11 @@
     protected Imager imager;
     
     /**
+     * The debugging console.
+     */
+    protected JConsole console;
+    
+    /**
      * The object that keeps track of pending and completed tasks.
      */
     public TaskKeeper taskKeeper = new TaskKeeper();
@@ -467,7 +561,23 @@
      * components has menubars or titlebars. They are typically distributed to the
      * corners of the screen to promote their use as a persistent background.
      */
-    protected boolean docked;
+    protected boolean docked = false;
+    
+    /**
+     * The docked root JFrame
+     */
+    protected JFrame dockedFrame;
+    
+    /**
+     * The undocked map canvas frame
+     */
+    protected JFrame mapCanvasFrame;
+    
+    protected JRootPane dockedRootPane;
+    
+    protected Dimension dockSize;
+    
+    protected Point dockAnchor = null;
 
     private static final long serialVersionUID = -3941481106291332264L;
 }

Modified: TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder/PenDecoderServer.java
===================================================================
--- TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder/PenDecoderServer.java	2007-07-20 02:49:22 UTC (rev 663)
+++ TeamTalk/Agents/PenDecoder/src/edu/cmu/ravenclaw/pendecoder/PenDecoderServer.java	2007-07-20 11:34:30 UTC (rev 664)
@@ -32,8 +32,6 @@
     super(mainserver,  socket);
     if(frame == null) {
       frame = new PenDecoderDisplay("Treasure Hunt GUI");
-      frame.setExtendedState(PenDecoderDisplay.MAXIMIZED_BOTH);
-      frame.setVisible(true);
     
       //start tracking bots
       botTracker = new BotTracker(frame.getCanvas());


More information about the TeamTalk-developers mailing list