// ********************************************************************** // // <copyright> // // BBN Technologies // 10 Moulton Street // Cambridge, MA 02138 // (617) 873-8000 // // Copyright (C) BBNT Solutions LLC. All rights reserved. // // </copyright> // ********************************************************************** package com.bbn.openmap.gui; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Cursor; import java.awt.Dimension; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Properties; import javax.swing.BorderFactory; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.OverlayLayout; import javax.swing.SwingUtilities; import javax.swing.border.BevelBorder; import com.bbn.openmap.LayerHandler; import com.bbn.openmap.MapBean; import com.bbn.openmap.MouseDelegator; import com.bbn.openmap.PropertyHandler; import com.bbn.openmap.event.OMMouseMode; import com.bbn.openmap.layer.shape.ShapeLayer; import com.bbn.openmap.omGraphics.DrawingAttributes; import com.bbn.openmap.omGraphics.OMGraphicConstants; import com.bbn.openmap.proj.ProjectionStack; import com.bbn.openmap.util.PropUtils; /** * An extension of the BasicMapPanel that uses an OverlayLayout on the panel in * the BorderLayout.CENTER position. Contains a transparent widgets JPanel for * placing components floating on top of the map. The default implementation of * layoutPanel() adds an EmbeddedNavPanel in the upper left position of the map, * as well as a ProjectionStack for it to use. * <p> * If a property prefix is set on this MapPanel, that property prefix can be * used to designate MapPanelChild objects for this MapPanel. The setName * variable should be set to true, and the children's parent name should match * whatever property prefix is given to the panel. */ public class OverlayMapPanel extends BasicMapPanel implements PropertyChangeListener { private static final long serialVersionUID = 1L; public final static String ACTIVE_WIDGET_COLOR_PROPERTY = "activeWidgets"; public final static String INACTIVE_WIDGET_COLOR_PROPERTY = "inactiveWidgets"; public final static String WIDGET_SIZE_PROPERTY = "widgetSize"; protected int DEFAULT_WIDGET_BUTTON_SIZE = 15; /** * May be null, in which case the widgets should decide. */ protected DrawingAttributes activeWidgetColors; /** * May be null, in which case the widgets should decide. */ protected DrawingAttributes inactiveWidgetColors; /** * Defaults to 15; */ protected int widgetButtonSize = DEFAULT_WIDGET_BUTTON_SIZE; /** * A transparent JPanel with a border layout, residing on top of the MapBean. */ protected JPanel widgets; private JPanel centerContainer; /** * Creates an empty OverlayMapPanel that creates its own empty * PropertyHandler. The MapPanel will contain a MapBean, a MapHandler, * EmbeddedNavPanel and a PropertyHandler with no properties. The constructor * to use to create a blank map framework to add components to. */ public OverlayMapPanel() { super(new PropertyHandler(new Properties()), false); } /** * Create a OverlayMapPanel with the option of delaying the search for * properties until the <code>create()</code> call is made. * * @param delayCreation true to let the MapPanel know that the artful * programmer will call <code>create()</code> */ public OverlayMapPanel(boolean delayCreation) { super(null, delayCreation); } /** * Create a OverlayMapPanel that configures itself with the properties * contained in the PropertyHandler provided. If the PropertyHandler is null, * a new one will be created. */ public OverlayMapPanel(PropertyHandler propertyHandler) { super(propertyHandler, false); } /** * Create a OverlayMapPanel that configures itself with properties contained * in the PropertyHandler provided, and with the option of delaying the * search for properties until the <code>create()</code> call is made. * * @param delayCreation true to let the MapPanel know that the artful * programmer will call <code>create()</code> */ public OverlayMapPanel(PropertyHandler propertyHandler, boolean delayCreation) { super(propertyHandler, delayCreation); } /** * Calls layoutPanel(MapBean), which configures the panel. */ protected void addMapBeanToPanel(MapBean map) { layoutPanel(map); map.addPropertyChangeListener(this); } public DrawingAttributes getActiveWidgetColors() { return activeWidgetColors; } public void setActiveWidgetColors(DrawingAttributes activeWidgetColors) { this.activeWidgetColors = activeWidgetColors; } public DrawingAttributes getInactiveWidgetColors() { return inactiveWidgetColors; } public void setInactiveWidgetColors(DrawingAttributes inactiveWidgetColors) { this.inactiveWidgetColors = inactiveWidgetColors; } public int getWidgetButtonSize() { return widgetButtonSize; } public void setWidgetButtonSize(int widgetButtonSize) { this.widgetButtonSize = widgetButtonSize; } /** * New method added, called from addMapBeanToPanel(MapBean). * * @param map */ protected void layoutPanel(MapBean map) { Dimension minimumSize = new Dimension(MapBean.DEFAULT_WIDTH, MapBean.DEFAULT_HEIGHT); JPanel hackPanel = new JPanel(); hackPanel.setLayout(new BorderLayout()); hackPanel.setOpaque(false); hackPanel.add(map, BorderLayout.CENTER); centerContainer = new JPanel(); centerContainer.setLayout(new OverlayLayout(centerContainer)); // These may be null, but the EmbeddedNavPanel will choose it's own // default colors if that is so. DrawingAttributes activeWidgetColors = getActiveWidgetColors(); DrawingAttributes inactiveWidgetColors = getInactiveWidgetColors(); int widgetButtonSize = getWidgetButtonSize(); EmbeddedNavPanel navPanel = new EmbeddedNavPanel(activeWidgetColors, inactiveWidgetColors, widgetButtonSize); navPanel.setBounds(12, 12, navPanel.getMinimumSize().width, navPanel.getMinimumSize().height); addMapComponent(navPanel); addMapComponent(new ProjectionStack()); EmbeddedScaleDisplayPanel scaleDisplay = new EmbeddedScaleDisplayPanel(); addMapComponent(scaleDisplay); widgets = new JPanel(); widgets.setLayout(new BorderLayout()); widgets.setBackground(OMGraphicConstants.clear); widgets.setOpaque(false); widgets.setBounds(0, 0, map.getWidth(), map.getHeight()); widgets.setMinimumSize(minimumSize); widgets.add(navPanel, BorderLayout.WEST); widgets.add(scaleDisplay, BorderLayout.EAST); setBorders(map, widgets); centerContainer.add(widgets); centerContainer.add(hackPanel); add(centerContainer, BorderLayout.CENTER); } /** * If you want different borders or color them differently, override this * method. * * @param map * @param widgets */ protected void setBorders(MapBean map, JPanel widgets) { if (map != null) { map.setBorder(null); } if (widgets != null) { widgets.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED, Color.GRAY, Color.DARK_GRAY)); } } /** Include exit in the File menu. Call this before create(). */ public void includeExitMenuItem() { addProperty("quitMenu.class", "com.bbn.openmap.gui.map.QuitMenuItem"); appendProperty("fileMenu.items", "quitMenu"); } public void setProperties(String prefix, Properties props) { super.setProperties(prefix, props); prefix = PropUtils.getScopedPropertyPrefix(prefix); DrawingAttributes awc = getActiveWidgetColors(); if (awc == null) { awc = DrawingAttributes.getDefaultClone(); } DrawingAttributes iwc = getInactiveWidgetColors(); if (iwc == null) { iwc = DrawingAttributes.getDefaultClone(); } // If no properties have been set for them, reset to null so the // EmbeddedNavPanel default colors are used. awc.setProperties(prefix + ACTIVE_WIDGET_COLOR_PROPERTY, props); if (awc.equals(DrawingAttributes.getDefaultClone())) { awc = null; } iwc.setProperties(prefix + INACTIVE_WIDGET_COLOR_PROPERTY, props); if (iwc.equals(DrawingAttributes.getDefaultClone())) { iwc = null; } setActiveWidgetColors(awc); setInactiveWidgetColors(iwc); setWidgetButtonSize(PropUtils.intFromProperties(props, prefix + WIDGET_SIZE_PROPERTY, getWidgetButtonSize())); } public Properties getProperties(Properties props) { props = super.getProperties(props); String prefix = PropUtils.getScopedPropertyPrefix(this); DrawingAttributes awc = getActiveWidgetColors(); if (awc != null) { awc.setPropertyPrefix(PropUtils.getScopedPropertyPrefix(this) + ACTIVE_WIDGET_COLOR_PROPERTY); awc.getProperties(props); } DrawingAttributes iwc = getInactiveWidgetColors(); if (iwc != null) { iwc.setPropertyPrefix(PropUtils.getScopedPropertyPrefix(this) + INACTIVE_WIDGET_COLOR_PROPERTY); iwc.getProperties(props); } int widgetSize = getWidgetButtonSize(); if (widgetSize != DEFAULT_WIDGET_BUTTON_SIZE) { props.put(prefix + WIDGET_SIZE_PROPERTY, Integer.toString(widgetSize)); } return props; } /** A main() method that just brings up a JFrame containing the MapPanel. */ public static void main(String argv[]) { SwingUtilities.invokeLater(new Runnable() { public void run() { JFrame f = new JFrame("Map"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); OverlayMapPanel map = new OverlayMapPanel(new PropertyHandler(new Properties()), true); map.create(); map.getMapBean().setBackgroundColor(new Color(0x99b3cc)); map.addMapComponent(new LayerHandler()); map.addMapComponent(new MouseDelegator()); map.addMapComponent(new OMMouseMode()); ShapeLayer shapeLayer = new ShapeLayer("share/data/shape/cntry02/cntry02.shp"); // shapeLayer.setAddAsBackground(true); map.addMapComponent(shapeLayer); map.includeExitMenuItem(); f.setJMenuBar(map.getMapMenuBar()); f.getContentPane().add(map); f.setSize(800, 600); f.setVisible(true); } }); } /* * (non-Javadoc) * * @see java.beans.PropertyChangeListener#propertyChange(java.beans. * PropertyChangeEvent) */ public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equals(MapBean.CursorProperty)) { centerContainer.setCursor(((Cursor) evt.getNewValue())); } } }