[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