/* ********************************************************************** * * Use, duplication, or disclosure by the Government is subject to * restricted rights as set forth in the DFARS. * * BBNT Solutions LLC * A Part of * Verizon * 10 Moulton Street * Cambridge, MA 02138 * (617) 873-3000 * * Copyright (C) 2002 by BBNT Solutions, LLC * All Rights Reserved. * ********************************************************************** */ package com.bbn.openmap.layer.beanbox; import java.awt.Image; import java.awt.Point; import java.awt.event.MouseEvent; import java.awt.geom.Point2D; import java.beans.BeanInfo; import java.util.Vector; import com.bbn.openmap.event.MapMouseListener; import com.bbn.openmap.event.SelectMouseMode; import com.bbn.openmap.omGraphics.OMGraphic; import com.bbn.openmap.omGraphics.OMRasterObject; import com.bbn.openmap.proj.coords.LatLonPoint; import com.bbn.openmap.tools.beanbox.BeanBox; import com.bbn.openmap.tools.beanbox.BeanContainer; /** * SimpleBeanBox is a sample implementation of the * {@link com.bbn.openmap.tools.beanbox.BeanBox}class. SimpleBeanBox manages * beans of type SimpleBeanObject. */ public class SimpleBeanBox extends BeanBox implements MapMouseListener { private SimpleBeanLayer layer; private static SimpleBeanBox thisBeanBox = null; public SimpleBeanBox(SimpleBeanLayer l) { super(); layer = l; } public String[] getMouseModeServiceList() { return new String[] { SelectMouseMode.modeID }; } public boolean mousePressed(MouseEvent evt) { return true; } public boolean mouseReleased(MouseEvent evt) { return true; } public boolean mouseClicked(MouseEvent evt) { return true; } public void mouseEntered(MouseEvent evt) { } public void mouseExited(MouseEvent evt) { } public boolean mouseDragged(MouseEvent evt) { return true; } public boolean mouseMoved(MouseEvent evt) { return true; } public void mouseMoved() { } /** * adds the specified bean to SimpleBeanLayer. This method is called by the * <code>com.bbn.openmap.tools.beanbox.BeanBoxDnDCatcher</code> class to add * the specified bean to a openmap layer. * * @throws an IllegalArgumentException if bean is not of type * SimpleBeanObject */ public void addBean(Object bean) { // System.out.println("Enter> SimpleBeanBox.addBean"); if (!(bean instanceof SimpleBeanObject)) throw new IllegalArgumentException("not instanceof SimpleBeanObject"); layer.addObject((SimpleBeanObject) bean); // System.out.println("Exit> SimpleBeanBox.addBean"); } /** * removes the specified bean from SimpleBeanLayer. This method is called by * the <code>com.bbn.openmap.tools.beanbox.BeanBoxDnDCatcher</code> class to * remove the specified bean from a openmap layer. * * @throws an IllegalArgumentException if bean is not of type * SimpleBeanObject */ public void removeBean(Object bean) { // System.out.println("Enter> SimpleBeanBox.removeBean"); if (!(bean instanceof SimpleBeanObject)) throw new IllegalArgumentException("not instanceof SimpleBeanObject"); layer.removeObject(((SimpleBeanObject) bean).getId()); // System.out.println("Exit> SimpleBeanBox.removeBean"); } /** * checks if the specified bean is present in SimpleBeanLayer. returns true * if present, false otherwise. * * @throws an IllegalArgumentException if bean is not of type * SimpleBeanObject */ public boolean containsBean(Object bean) { // System.out.println("Called> SimpleBeanBox.containsBean"); if (!(bean instanceof SimpleBeanObject)) throw new IllegalArgumentException("not instanceof SimpleBeanObject " + bean); return (layer.getObject(((SimpleBeanObject) bean).getId()) != null); } /** * Sets the image associated with the bean using the image present in the * BeanInfo. Also sets the bean's location. This method is called by the * <code>com.bbn.openmap.tools.beanbox.BeanBoxDnDCatcher</code> class to set * the bean's properties before it is displayed in a property sheet prior to * adding to an openmap layer. * * @throws an IllegalArgumentException if bean is not of type * SimpleBeanObject */ public void setBeanProperties(Object bean, BeanInfo beanInfo, Point location) { // System.out.println("Enter> // SimpleBeanBox.setBeanProperties"); if (!(bean instanceof SimpleBeanObject)) throw new IllegalArgumentException("not instanceof SimpleBeanObject " + bean); SimpleBeanObject obj = (SimpleBeanObject) bean; Image img = beanInfo.getIcon(BeanInfo.ICON_COLOR_32x32); obj.setGraphicImage(img); Point2D llp = layer.getProjection().inverse(location.x, location.y); obj.setLatitude((float) llp.getY()); obj.setLongitude((float) llp.getX()); // System.out.println("Exit> // SimpleBeanBox.setBeanProperties"); } /** * gets a Vector of beans that implement the * <code>com.bbn.openmap.tools.beanbox.BeanContainer</code> interface. * * @return a possibly empty vector of container beans. */ Vector getAllContainers() { Vector containers = new Vector(); Vector list = layer.getObjects(); if (list == null || list.isEmpty()) return containers; for (int i = 0; i < list.size(); i++) { Object obj = list.get(i); if (obj instanceof BeanContainer) containers.add(obj); } return containers; } /** * returns a <code>BeanContainer</code> bean that contains the specified * bean object. * * @throws an IllegalArgumentException if bean is not of type * SimpleBeanObject */ public BeanContainer findEnclosingContainer(Object bean) { // System.out.println("Called> // SimpleBeanBox.findEnclosingContainer"); if (!(bean instanceof SimpleBeanObject)) { return null; } SimpleBeanObject obj = (SimpleBeanObject) bean; float objLat = obj.getLatitude(); float objLon = obj.getLongitude(); LatLonPoint llp = new LatLonPoint.Float(objLat, objLon); return findEnclosingContainer(llp); } /** * returns a SimpleBeanContainer bean that contains the specified * <code>LatLonPoint</code> on the map. */ public SimpleBeanContainer findEnclosingContainer(LatLonPoint llp) { Vector containers = getAllContainers(); for (int i = 0; i < containers.size(); i++) { SimpleBeanContainer container = (SimpleBeanContainer) containers.get(i); if (encloses(container, llp)) return container; } return null; } /** * helper method returns true if the specified <code>LatLonPoint</code> is * contained within the specified <code>SimpleBeanContainer</code>. */ boolean encloses(SimpleBeanContainer container, Point2D llp) { float topLat = container.getTopLatitude(); float leftLon = container.getLeftLongitude(); float botLat = container.getBottomLatitude(); float rightLon = container.getRightLongitude(); float lat = (float) llp.getY(); float lon = (float) llp.getX(); if ((lon > rightLon) || (lon < leftLon)) return false; if ((lat > topLat) || (lat < botLat)) return false; return true; } /** * finds a bean of type * <code>com.bbn.openmap.tools.beanbox.BeanContainer</code> that encloses * the specified (x,y) point. In case more than one container encloses the * specified point the first one found is returned. Returns null if none is * found. */ BeanContainer findContainerBean(Point pointOnMap) { if (layer != null && layer.getProjection() != null) { Point2D llp = layer.getProjection().inverse(pointOnMap.x, pointOnMap.y); return findEnclosingContainer(llp); } else { return null; } } /** * returns a bean that does NOT implement * <code>com.bbn.openmap.tools.beanbox.BeanContainer</code> and which lies * closest to and within 10 pixels of the specified (x,y) point. Returns * null if no such object is found. */ SimpleBeanObject findNonContainerBean(Point pointOnMap) { Vector list = layer.getObjects(); double minSep = Double.MAX_VALUE; SimpleBeanObject closest = null; for (int i = 0; i < list.size(); i++) { Object o = list.get(i); SimpleBeanObject obj = (SimpleBeanObject) o; if (obj instanceof SimpleBeanContainer) continue; Point2D p2 = layer.getProjection().forward(new LatLonPoint.Float(obj.getLatitude(), obj.getLongitude())); double sep = almostEquals(pointOnMap, p2, 20); if (sep < minSep) { minSep = sep; closest = obj; } } return closest; } /** * return bean at specified location giving preference to non-container * beans over container beans. If neither type of bean is found to be close * enough to the specified location, a null is returned. */ public Object getBeanAtLocation(Point pointOnMap) { // System.out.println("Called> // SimpleBeanBox.getBeanAtLocation"); SimpleBeanObject obj = findNonContainerBean(pointOnMap); if (obj != null) return obj; BeanContainer container = findContainerBean(pointOnMap); if (container != null) return container; return null; } /** * returns the straight line separation in pixels between the specified * points if separation is equal to or less than the specified tolerance * amount, else returns Double.MAX_VALUE */ double almostEquals(Point2D p1, Point2D p2, double tol) { double sepX = p1.getX() - p2.getX(); double sepY = p1.getY() - p2.getY(); double sep = Math.sqrt(sepX * sepX + sepY * sepY); if (sep <= tol) return sep; else return Double.MAX_VALUE; } /** * relocates the specified bean to the new location. This method is called * by the <code>com.bbn.openmap.tools.beanbox.BeanBoxDnDCatcher</code> * whenever the user moves a bean on the map within the same openmap layer. * * @throws IllegalArgumentException is specified bean is not of type * SimpleBeanObject. */ public void relocateBean(Object bean, BeanInfo beanInfo, Point newLocation) { // System.out.println("Enter> SimpleBeanBox.relocateBean"); if (!(bean instanceof SimpleBeanObject)) throw new IllegalArgumentException("not instanceof SimpleBeanObject " + bean); SimpleBeanObject obj = (SimpleBeanObject) bean; Point2D llp = layer.getProjection().inverse(newLocation.x, newLocation.y); relocateSimpleBeanObject(obj, llp); layer.updateGraphics(); // System.out.println("Exit> SimpleBeanBox.relocateBean"); } /** relocates the specified SimpleBeanObject to the new location. */ void relocateSimpleBeanObject(SimpleBeanObject obj, Point2D newllp) { SimpleBeanContainer oldContainer = null; // no support yet for containers within containers because // of unresolved issues regarding partially over-lapping // containers. if (!(obj instanceof SimpleBeanContainer)) { oldContainer = (SimpleBeanContainer) findEnclosingContainer(obj); } if (oldContainer != null) { oldContainer.remove(obj); } obj.setLatitude((float) newllp.getY()); obj.setLongitude((float) newllp.getX()); if (obj instanceof SimpleBeanContainer) ((SimpleBeanContainer) obj).validate(); SimpleBeanContainer newContainer = null; if (!(obj instanceof SimpleBeanContainer)) { newContainer = (SimpleBeanContainer) findEnclosingContainer(obj); } if (newContainer != null) { newContainer.add(obj); } } /** * this method is a callback method that is called by a * <code>com.bbn.openmap.tools.beanbox.GenericPropertySheet</code> when the * user closes the property sheet. */ public void beanChanged(Object bean, String changedPropertyName) { // System.out.println("Enter> SimpleBeanBox.beanChanged"); if (!(bean instanceof SimpleBeanObject)) throw new IllegalArgumentException("not instanceof SimpleBeanObject " + bean); SimpleBeanObject obj = (SimpleBeanObject) bean; layer.updateObject(obj); // System.out.println("Exit> SimpleBeanBox.beanChanged"); } /** * returns the image that the cursor is set to when the specified bean is * dragged on the map. */ protected Image getDragImage(Object bean) { // System.out.println("Called> SimpleBeanBox.getDragImage"); if (!(bean instanceof SimpleBeanObject)) throw new IllegalArgumentException("not instanceof SimpleBeanObject " + bean); SimpleBeanObject obj = (SimpleBeanObject) bean; OMGraphic graphic = layer.getGraphic(obj.getId()); if (graphic instanceof OMRasterObject) { return ((OMRasterObject) graphic).getImage(); } else return super.getDragImage(bean); } }