// ********************************************************************** // // <copyright> // // BBN Technologies // 10 Moulton Street // Cambridge, MA 02138 // (617) 873-8000 // // Copyright (C) BBNT Solutions LLC. All rights reserved. // // </copyright> // ********************************************************************** // // $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/layer/link/amp/AmpLinkLayer.java,v $ // $RCSfile: AmpLinkLayer.java,v $ // $Revision: 1.6 $ // $Date: 2006/03/06 16:14:00 $ // $Author: dietrick $ // // ********************************************************************** package com.bbn.openmap.layer.link.amp; import java.awt.Color; import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.net.UnknownHostException; import javax.swing.JButton; import javax.swing.JPanel; import javax.swing.SwingConstants; import com.bbn.openmap.gui.Tool; import com.bbn.openmap.layer.link.ClientLink; import com.bbn.openmap.layer.link.Link; import com.bbn.openmap.layer.link.LinkActionList; import com.bbn.openmap.layer.link.LinkGraphic; import com.bbn.openmap.layer.link.LinkLayer; import com.bbn.openmap.layer.link.LinkOMGraphicList; import com.bbn.openmap.layer.link.LinkProperties; import com.bbn.openmap.omGraphics.GraphicAttributes; import com.bbn.openmap.omGraphics.OMAction; import com.bbn.openmap.omGraphics.OMCircle; import com.bbn.openmap.omGraphics.OMGraphic; import com.bbn.openmap.omGraphics.OMGraphicList; import com.bbn.openmap.omGraphics.OMRangeRings; import com.bbn.openmap.proj.Projection; import com.bbn.openmap.tools.drawing.DrawingTool; import com.bbn.openmap.util.Debug; /** * The AmpLinkLayer is an extension to the LinkLayer. The difference * is that this layer provides some components to the ToolBar for the * creation of certain graphics to be sent to the LinkServer. This * layer also wants access to the DrawingTool. * <P> * * The entry in the openmap.properties file looks like this: * <P> * * <pre> * * * * # port number of server * link.port=3031 * # host name of server * link.host=host.com * # URL of properties file for server attributes * link.propertiesURL=http://location.of.properties.file.com * * * * </pre> */ public class AmpLinkLayer extends LinkLayer implements Tool { public final static String RRIntervalUnitsProperty = ".rangeRingIntervalUnits"; public final static String RRIntervalProperty = ".rangeRingInterval"; protected OMGraphicList extraGraphics = new OMGraphicList(); protected DrawingTool drawingTool = null; protected int orientation = SwingConstants.HORIZONTAL; /** * The default constructor for the Layer. All of the attributes * are set to their default values. */ public AmpLinkLayer() {} /** * Constructor to use when LinkLayer is not being used with * OpenMap application. * * @param host the hostname of the server's computer. * @param port the port number of the server. * @param propertiesURL the URL of a properties file that contains * parameters for the server. */ public AmpLinkLayer(String host, int port, String propertiesURL) { super(host, port, propertiesURL); } /** * Set all the Link properties from a properties object. * * @param prefix the prefix to the properties that might * individualize it to a particular layer. * @param properties the properties for the layer. */ public void setProperties(String prefix, java.util.Properties properties) { super.setProperties(prefix, properties); setAddToBeanContext(true); } /** * Prepares the graphics for the layer. This is where the * getRectangle() method call is made on the link. * <p> * Occasionally it is necessary to abort a prepare call. When this * happens, the map will set the cancel bit in the LayerThread, * (the thread that is running the prepare). If this Layer needs * to do any cleanups during the abort, it should do so, but * return out of the prepare asap. * * @return a list of graphics. */ public synchronized OMGraphicList prepare() { Projection projection = getProjection(); if (projection != null) { extraGraphics.generate(projection); } return super.prepare(); } /** * Paints the layer. * * @param g the Graphics context for painting */ public void paint(java.awt.Graphics g) { if (Debug.debugging("link")) { System.out.println(getName() + "|AmpLinkLayer.paint()"); } if (extraGraphics != null) { extraGraphics.render(g); } super.paint(g); } /** * Just need to check here if one of the new extra graphics (range * ring) was clicked on, so that it can be sent to the drawing * tool for modification if desired. */ public boolean mouseClicked(MouseEvent e) { Debug.message("link", "AmpLinkLayer mouseClicked"); LinkOMGraphicList graphics = getGraphicList(); // Get old list OMGraphic gesGraphic = null; gesGraphic = graphics.findClosest(e.getX(), e.getY(), distanceLimit); if (gesGraphic == null) { gesGraphic = extraGraphics.findClosest(e.getX(), e.getY(), distanceLimit); } if (gesGraphic != null && drawingTool != null) { DrawingTool dt = getDrawingTool(); OMGraphic graphic = null; if (dt != null) { graphic = dt.edit(gesGraphic, layer); } if (graphic != null) { Debug.message("link", "AmpLinkLayer editing graphic"); return true; } else { Debug.message("link", "AmpLinkLayer unable to edit graphic"); } } return super.mouseClicked(e); } protected final com.bbn.openmap.tools.drawing.DrawingToolRequestor layer = this; // DrawingToolRequestor method public void drawingComplete(OMGraphic omg, OMAction action) { ////////////// send the new graphic, along with instructions //on what to do with it, to the server. String id = null; // unknown Object obj = omg.getAttribute(OMGraphic.APP_OBJECT); LinkProperties lp = null; if (obj instanceof LinkProperties) { lp = (LinkProperties) obj; id = lp.getProperty(LPC_GRAPHICID); Debug.message("link", "AmpLinkLayer: received modified server graphic " + lp); } else { Debug.message("link", "AmpLinkLayer: received new graphic from dt"); } if (id == null) { // Doesn't look like it was a modified graphic already // received from the server, so we should tell the server // to add it to its list. action.setMask(OMAction.ADD_GRAPHIC_MASK); } else { action.setMask(OMAction.UPDATE_GRAPHIC_MASK); } if (omg instanceof OMRangeRings) { extraGraphics.doAction(omg, action); repaint(); return; } try { // We do want the link object here... If another thread is // using the link, wait. ClientLink l = linkManager.getLink(true); if (l == null) { System.err.println("LinkLayer.drawingComplete: unable to get link."); return; } synchronized (l) { LinkActionList lal = new LinkActionList(l, new LinkProperties()); if (action.isMask(OMAction.ADD_GRAPHIC_MASK) || action.isMask(OMAction.UPDATE_GRAPHIC_MASK)) { lal.writeGraphicGestureHeader(action.getValue()); LinkGraphic.write(omg, l); } else { // This shouldn't ever get called with a null lp // properties object. If the object is new or // doesn't have an ID, the upper paragraph will // get called. lal.modifyGraphic(action.getValue(), lp); } lal.end(Link.END_TOTAL); } l.readAndParse(getProjection(), currentGenerator); linkManager.finLink(); } catch (UnknownHostException uhe) { Debug.error("LinkLayer: unknown host!"); } catch (java.io.IOException ioe) { Debug.error("LinkLayer: Communication error between " + getName() + " layer\nand Link Server: Host: " + host + ", Port: " + port + "LinkLayer: IOException contacting server!\n" + ioe.getMessage()); linkManager.resetLink(); if (!quiet) { fireRequestMessage("Communication error between " + getName() + " layer\nand Link Server: Host: " + host + ", Port: " + port); } } doPrepare(); } /////////////////////////////////////////////////// // Tool interface - to put controls for the layer // on the tool bar. protected Container gui; protected JButton rrButton, eZone; /** * The retrieval tool's interface. This is added to the tool bar. * * @return String The key for this tool. */ public Container getFace() { if (gui == null) { gui = new JPanel(); rrButton = new JButton("RR"); rrButton.setToolTipText("Create Range Ring"); rrButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { DrawingTool dt = getDrawingTool(); GraphicAttributes ga = new GraphicAttributes(); ga.setLinePaint(Color.yellow); if (dt != null) { OMRangeRings rr = (OMRangeRings) getDrawingTool().create("com.bbn.openmap.omGraphics.OMRangeRings", ga, layer); if (rr != null) { // rr.setInterval(25, Length.MILE); } else { Debug.error("AmpLinkLayer: Drawing tool can't create OMRangeRings"); } } else { Debug.output("AmpLinkLayer can't find a drawing tool"); } } }); eZone = new JButton("EZ"); eZone.setToolTipText("Create Exclusion Zone"); eZone.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { DrawingTool dt = getDrawingTool(); GraphicAttributes ga = new GraphicAttributes(); ga.setRenderType(OMGraphic.RENDERTYPE_LATLON); ga.setLinePaint(Color.red); if (dt != null) { OMCircle circle = (OMCircle) getDrawingTool().create("com.bbn.openmap.omGraphics.OMCircle", ga, layer); if (circle == null) { Debug.error("AmpLinkLayer: Drawing tool can't create Exclusion Zones"); } } else { Debug.output("AmpLinkLayer can't find a drawing tool"); } } }); gui.add(rrButton); gui.add(eZone); } return gui; } protected String key = "AMPControls"; /** * The retrieval key for this tool * * @return String The key for this tool. */ public String getKey() { return key; } /** * Set the retrieval key for this tool * * @param aKey The key for this tool. */ public void setKey(String aKey) { key = aKey; } public void findAndInit(Object someObj) { if (someObj instanceof DrawingTool) { Debug.message("link", "AmpLinkLayer: found a drawing tool"); setDrawingTool((DrawingTool) someObj); } } public void findAndUndo(Object someObj) { if (someObj instanceof DrawingTool) { if (getDrawingTool() == (DrawingTool) someObj) { setDrawingTool(null); } } } public void setDrawingTool(DrawingTool dt) { drawingTool = dt; } public DrawingTool getDrawingTool() { return drawingTool; } public int getOrientation() { return orientation; } public void setOrientation(int orientation) { this.orientation = orientation; } }