Copy focus map
arcgissamples\pagelayoutbean\CopyFocusMap.java
/* Copyright 2010 ESRI
* 
* All rights reserved under the copyright laws of the United States
* and applicable international laws, treaties, and conventions.
* 
* You may freely redistribute and use this sample code, with or
* without modification, provided you include the original copyright
* notice and use restrictions.
* 
* See the use restrictions.
* 
*/
package arcgissamples.pagelayoutbean;

import java.awt.BorderLayout;
import java.awt.FileDialog;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.UIManager;

import com.esri.arcgis.beans.map.MapBean;
import com.esri.arcgis.beans.pagelayout.PageLayoutBean;
import com.esri.arcgis.carto.IActiveView;
import com.esri.arcgis.carto.IElement;
import com.esri.arcgis.carto.IElementProperties;
import com.esri.arcgis.carto.IGraphicsContainer;
import com.esri.arcgis.carto.Map;
import com.esri.arcgis.carto.MapFrame;
import com.esri.arcgis.carto.esriViewDrawPhase;
import com.esri.arcgis.controls.IMapControlEvents2Adapter;
import com.esri.arcgis.controls.IMapControlEvents2OnAfterScreenDrawEvent;
import com.esri.arcgis.controls.IMapControlEvents2OnBeforeScreenDrawEvent;
import com.esri.arcgis.controls.IMapControlEvents2OnMouseDownEvent;
import com.esri.arcgis.controls.IPageLayoutControlEventsAdapter;
import com.esri.arcgis.controls.IPageLayoutControlEventsOnAfterScreenDrawEvent;
import com.esri.arcgis.controls.IPageLayoutControlEventsOnBeforeScreenDrawEvent;
import com.esri.arcgis.controls.IPageLayoutControlEventsOnFocusMapChangedEvent;
import com.esri.arcgis.controls.IPageLayoutControlEventsOnMouseDownEvent;
import com.esri.arcgis.controls.IPageLayoutControlEventsOnPageLayoutReplacedEvent;
import com.esri.arcgis.controls.esriControlsMousePointer;
import com.esri.arcgis.display.IDisplayTransformation;
import com.esri.arcgis.system.AoInitialize;
import com.esri.arcgis.system.EngineInitializer;
import com.esri.arcgis.system.ObjectCopy;
import com.esri.arcgis.system.esriLicenseProductCode;
import com.esri.arcgis.system.esriLicenseStatus;

/**
 * Description:This sample demonstrates setting the PageLayoutBean's FocusMap and using the IObjecyCopy object to
 * overwrite the MapBean's Map object with a copy of the PageLayoutBean's FocusMap. The Map object has to copied because
 * the MapBean and PageLayoutBean are unable to share the same ActiveView at the same time. The file chooser dialog
 * allows users to search and select map documents, which are validated and loaded into the PageLayoutBean using the
 * checkMxFile and loadMxFile methods. This triggers the OnPageLayoutReplaced event which loops through the Elements in
 * the PageLayoutBean's GraphicsContainer finding MapFrame elements. The name of each MapFrame is set to the name of the
 * Map in the MapFrame using the IElementProperties interface. A ComboBox is populated with all Map name's to allow
 * users to change the FocusMap. The FindElementByName method is used to find the MapFrame containing the Map that is to
 * become the FocusMap.
 * <p/>
 * The PageLayoutBean's OnFocusMapChanged and OnAfterScreenDraw (when a new Map Document has been loaded into the
 * PageLayoutBean) events use the IObjectCopy Copy and Overwrite methods to overwrite the MapBean's Map with a copy of
 * the PageLayoutBean's FocusMap. The PageLayoutBean and MapBean OnMouseDown event's use the TrackRectangle and Pan
 * methods to zoomin and pan around either the PageLayoutBean's Page or the MapBean's Map. If the MapBean's display is
 * redrawn due to a change in VisibleExtent, the OnAfterScreenDraw event is used set the Extent of the PageLayoutBean's
 * FocusMap equal to that of the MapBean using the IDisplayTransformation interface.
 */
public class CopyFocusMap extends JFrame implements ActionListener
{
  private static final long serialVersionUID = 1L;
  JPanel topPanel = null;
  JPanel mainPanel = null;
  JPanel centerPanel = null;
  JPanel pageLayoutPanel = null;
  JPanel bottomPanel = null;

  JButton loadDocumentButton = null;
  JTextField pathField = null;
  String helpString = "Use right mouse button to pan page or data, and left button to zoom in";
  JLabel helpLabel = null;
  JButton zoomToPageButton = null;
  JButton zoomToFullDataButton = null;
  JComboBox focusMapCombo = null;

  PageLayoutBean pageLayoutBean;
  MapBean mapBean;
  boolean updateFocusMap;
  boolean replacedPageLayout;

  public CopyFocusMap()
  {
    super("Copy Focus Map Example");
    buildFrame();
    setSize(700, 500);
    setVisible(true);
    initControl();
  }

  public void buildFrame()
  {
    topPanel = new JPanel();
    mainPanel = new JPanel();
    centerPanel = new JPanel();
    pageLayoutPanel = new JPanel();
    bottomPanel = new JPanel();

    topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.X_AXIS));
    mainPanel.setLayout(new BorderLayout());
    centerPanel.setLayout(new GridLayout(1, 2, 10, 0));
    pageLayoutPanel.setLayout(new BorderLayout());
    bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.X_AXIS));

    loadDocumentButton = new JButton("Load Document");
    loadDocumentButton.addActionListener(this);

    pathField = new JTextField();
    pathField.setEditable(false);
    topPanel.add(loadDocumentButton);
    topPanel.add(Box.createHorizontalStrut(5));
    topPanel.add(pathField);
    topPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0));

    pageLayoutBean = new PageLayoutBean();
    focusMapCombo = new JComboBox();
    focusMapCombo.addActionListener(this);
    focusMapCombo.setLightWeightPopupEnabled(false);

    pageLayoutPanel.add(focusMapCombo, BorderLayout.NORTH);
    pageLayoutPanel.add(pageLayoutBean, BorderLayout.CENTER);

    mapBean = new MapBean();
    centerPanel.add(pageLayoutPanel);
    centerPanel.add(mapBean);

    zoomToPageButton = new JButton("Zoom To Page");
    zoomToPageButton.addActionListener(this);

    helpLabel = new JLabel(helpString);
    helpLabel.setHorizontalTextPosition(SwingConstants.CENTER);
    zoomToFullDataButton = new JButton("Zoom to Full Data Extent");
    zoomToFullDataButton.addActionListener(this);

    bottomPanel.add(zoomToPageButton);
    bottomPanel.add(Box.createHorizontalStrut(30));
    bottomPanel.add(helpLabel);
    bottomPanel.add(Box.createHorizontalStrut(10));
    bottomPanel.add(zoomToFullDataButton);

    // Create page layout control add it to the center of the main panel.
    mainPanel.add(topPanel, BorderLayout.NORTH);
    mainPanel.add(centerPanel, BorderLayout.CENTER);
    mainPanel.add(bottomPanel, BorderLayout.SOUTH);
    mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
    getContentPane().add(mainPanel, BorderLayout.CENTER);
  }

  /*
   * Intializes control
   */
  public void initControl()
  {
    try
    {
      updateFocusMap = false;
      replacedPageLayout = false;
      mapBean.setShowScrollbars(false);
      // Add control listener
      mapBean.addIMapControlEvents2Listener(new MapControlListener());
      pageLayoutBean.addIPageLayoutControlEventsListener(new PageLayoutControlListener());
    }
    catch (IOException ex)
    {
      System.out.println("Exception in initControl : " + ex);
      ex.printStackTrace();
    }
  }

  /**
   * @see java.awt.event.ActionListener#actionPerformed(ActionEvent event)
   * @param event
   */
  public void actionPerformed(ActionEvent event)
  {
    if (event.getSource() == focusMapCombo)
    {
      try
      {
        // Get IMapFrame interface
        if (focusMapCombo.getSelectedItem() != null)
        {
          IElement element = pageLayoutBean.findElementByName((String) focusMapCombo.getSelectedItem(), 1);
          // Set the focusMap
          MapFrame mapFrame = (MapFrame) element;
          pageLayoutBean.getActiveView().setFocusMapByRef(mapFrame.getMap());
        }
      }
      catch (IOException ex)
      {
        System.out.println("Exception in focusMapCombo#actionPerformed: " + ex);
        ex.printStackTrace();
      }
    }

    if (event.getSource() == zoomToPageButton)
    {
      try
      {
        // Zoom to the whole page
        pageLayoutBean.zoomToWholePage();
      }
      catch (IOException ex)
      {
        System.out.println("Exception in zoomToPageButton#actionPerformed: " + ex);
        ex.printStackTrace();
      }
    }

    if (event.getSource() == zoomToFullDataButton)
    {
      try
      {
        // Assign map controls extent property to the full extent of all the layers
        mapBean.setExtent(mapBean.getFullExtent());
      }
      catch (IOException ex)
      {
        System.out.println("Exception in zoomToFullDataButton#actionPerformed : " + ex);
        ex.printStackTrace();
      }
    }

    if (event.getSource() == loadDocumentButton)
    {
      try
      {
        loadFile();
      }
      catch (IOException ex)
      {
        System.out.println("Exception in loadDocumentButton#actionPerformed: " + ex);
        ex.printStackTrace();
      }
    }
  }

  /**
   * Method loadFile loads the specified mxd file.
   */
  public boolean loadFile() throws IOException
  {
    FileDialog fileDialog = new FileDialog(this, "Select map document (.mxd, .mxt, .pmf)", FileDialog.LOAD);
    fileDialog.setVisible(true);
    String fileChosen = fileDialog.getDirectory() + fileDialog.getFile();
    // Check if the selected document can be loaded into control
    // Update the textfiled with the file name.
    pathField.setText(fileChosen);
    // Validate and load map document
    if (pageLayoutBean.checkMxFile(fileChosen))
    {
      pageLayoutBean.setMousePointer(esriControlsMousePointer.esriPointerHourglass);
      mapBean.setMousePointer(esriControlsMousePointer.esriPointerHourglass);
      // Reset controls
      mapBean.getActiveView().clear();
      mapBean.getActiveView().getGraphicsContainer().deleteAllElements();
      mapBean.refresh(esriViewDrawPhase.esriViewForeground, null, null);
      focusMapCombo.removeAllItems();
      // Load map document
      pageLayoutBean.loadMxFile(fileChosen, null);
      // Set mouse pointers
      pageLayoutBean.setMousePointer(esriControlsMousePointer.esriPointerDefault);
      mapBean.setMousePointer(esriControlsMousePointer.esriPointerDefault);
      return true;
    }
    return false;
  }

  /**
   * Method which overwrites map controls map object with the pagelayout's focus map
   */
  public void copyAndOverwriteMap()
  {
    try
    {
      // Get IObjectCopy interface
      ObjectCopy objectCopy = new ObjectCopy();
      // Get the map to copy
      Object toCopyMap = pageLayoutBean.getActiveView().getFocusMap();
      // Get the map to be overwritten
      Object toOverwriteMap[] =
      { mapBean.getMap() };
      // Overwrite the MapBean's map
      objectCopy.overwrite(objectCopy.copy(toCopyMap), toOverwriteMap);
      // Update map control's extent
      setMapExtent();
    }
    catch (IOException ex)
    {
      System.out.println("Exception in copyAndOverwriteMap : " + ex);
      ex.printStackTrace();
    }
  }

  /**
   * Method which sets the Extent of the pageLayoutBean's FocusMap equal to that of the MapBean using the
   * IDisplayTransformation interface
   */
  public void setMapExtent()
  {
    try
    {
      // Get active map
      Map map = (Map) pageLayoutBean.getActiveView().getFocusMap();
      // Set the control's extent
      mapBean.setExtent(map.getExtent());
      // Refresh the display
      mapBean.refresh(esriViewDrawPhase.esriViewBackground, null, null);
    }
    catch (IOException ex)
    {
      System.out.println("Exception in setMapExtent : " + ex);
      ex.printStackTrace();
    }
  }

  /**
   * Method which populates the combobox with the list of maps in the pagelayout control. it also sets the selected
   * item in the combo box to that of the pagelayouts focus map.
   */
  public void listMaps()
  {
    try
    {
      // Get IGraphicsContainer interface
      IGraphicsContainer graphicsContainer;
      graphicsContainer = pageLayoutBean.getGraphicsContainer();
      graphicsContainer.reset();
      // Query Interface for IElement interface
      IElement element = graphicsContainer.next();
      // Loop through the elements
      while (element != null)
      {
        // Create a MapFrame class using element.
        MapFrame mapFrame;
        String mapName;
        try
        {
          mapFrame = (MapFrame) element;
          // Get the name of the Map in the MapFrame
          mapName = mapFrame.getMap().getName();
        }
        catch (Exception NotAnInstanceOfMapFrame)
        {
          element = graphicsContainer.next();
          continue;
        }
        // Get IElementProperties interface . Set the name of the MapFrame to the Map's name
        IElementProperties elementProperties = (IElementProperties) (element);
        elementProperties.setName(mapName);
        // Add the map name to the ComboBox
        focusMapCombo.addItem(mapName);
        // If the Map is the FocusMap select the MapName in the ComboBox
        if (mapName.equals(pageLayoutBean.getActiveView().getFocusMap().getName()))
          focusMapCombo.setSelectedItem(mapName);
        element = graphicsContainer.next();
      }
    }
    catch (IOException ex)
    {
      System.out.println("Exception in listMaps : " + ex);
      ex.printStackTrace();
    }
  }

  /**
   * Description: Class which extends pagelayout control event class IPageLayoutControlEvents2Adapter
   * 
   * @see com.esri.arcgis.beans.pagelayout.IPageLayoutControlEventsAdapter
   */
  class PageLayoutControlListener extends IPageLayoutControlEventsAdapter
  {
    private static final long serialVersionUID = 1L;

    /**
     * @see com.esri.arcgis.beans.pagelayout.onAfterScreenDraw(IPageLayoutControlEventsOnAfterScreenDrawEvent
     *      theEvent)
     * @param theEvent
     */
    public void onAfterScreenDraw(IPageLayoutControlEventsOnAfterScreenDrawEvent theEvent)
    {
      try
      {
        // Set mouse pointer
        pageLayoutBean.setMousePointer(esriControlsMousePointer.esriPointerDefault);
        mapBean.setMousePointer(esriControlsMousePointer.esriPointerDefault);

        if (!replacedPageLayout)
          return;
        copyAndOverwriteMap();
        replacedPageLayout = false;
      }
      catch (Exception ex)
      {
        System.out.println("Exception in PageLayoutControlListener#onAfterScreenDraw : " + ex);
        ex.printStackTrace();

      }
    }

    /**
     * @see com.esri.arcgis.beans.onBeforeScreenDraw(IPageLayoutControlEventsOnBeforeScreenDrawEvent theEvent) {
     * @param theEvent
     */
    public void onBeforeScreenDraw(IPageLayoutControlEventsOnBeforeScreenDrawEvent theEvent)
    {
      try
      {
        // Set mouse pointer
        pageLayoutBean.setMousePointer(esriControlsMousePointer.esriPointerHourglass);
      }
      catch (Exception ex)
      {
        System.out.println("Exception in PageLayoutControlListener#onBeforeScreenDraw : " + ex);
        ex.printStackTrace();
      }
    }

    /**
     * @see com.esri.arcgis.beans.pagelayout.onPageLayoutReplaced(IPageLayoutControlEventsOnPageLayoutReplacedEvent
     *      theEvent) {
     * @param theEvent
     */

    public void onPageLayoutReplaced(IPageLayoutControlEventsOnPageLayoutReplacedEvent theEvent)
    {
      try
      {
        replacedPageLayout = true;
        listMaps();
      }
      catch (Exception ex)
      {
        System.out.println("Exception in PageLayoutControlListener#onPageLayoutReplaced : " + ex);
        ex.printStackTrace();
      }
    }

    /**
     * @see com.esri.arcgis.beans.pagelayout.onMouseDown(IPageLayoutControlEventsOnMouseDownEvent theEvent)
     * @param theEvent
     */
    public void onMouseDown(IPageLayoutControlEventsOnMouseDownEvent theEvent)
    {
      try
      {
        // Zoom in
        if (theEvent.getButton() == 1)
        {
          pageLayoutBean.setExtent(pageLayoutBean.trackRectangle());
        }
        else if (theEvent.getButton() == 2)
          pageLayoutBean.pan();
      }
      catch (Exception ex)
      {
        System.out.println("Exception in PageLayoutControlListener#onMouseDown : " + ex);
        ex.printStackTrace();
      }
    }

    /**
     * @see com.esri.arcgis.beans.pagelayout.onFocusMapChanged(IPageLayoutControlEventsOnFocusMapChangedEvent
     *      theEvent) {
     * @param theEvent
     */
    public void onFocusMapChanged(IPageLayoutControlEventsOnFocusMapChangedEvent theEvent)
    {
      try
      {
        copyAndOverwriteMap();
      }
      catch (Exception ex)
      {
        System.out.println("Exception in PageLayoutControlListener#onFocusMapChanged : " + ex);
        ex.printStackTrace();
      }
    }
  } // End of PageLayoutListener class

  /**
   * Description: Class which extends map control event class IMapControlEvents2Adapter
   * 
   * @see com.esri.arcgis.beans.map.IMapControlEvents2Adapter
   */

  class MapControlListener extends IMapControlEvents2Adapter
  {
    private static final long serialVersionUID = 1L;

    /**
     * @see com.esri.arcgis.beans.map.IMapControlEvents2Adapter#onMouseDown(IMapControlEvents2OnMouseDownEvent
     *      theEvent)
     * @param theEvent
     */
    public void onMouseDown(IMapControlEvents2OnMouseDownEvent theEvent)
    {
      try
      {
        updateFocusMap = true;
        // If left mouse button
        if (theEvent.getButton() == 1)
        {
          // If user dragged a rectangle
          mapBean.setExtent(mapBean.trackRectangle());
        }
        else if (theEvent.getButton() == 2)
          mapBean.pan();
      }
      catch (Exception ex)
      {
        System.out.println("Exception in MapControlListener#onMouseDown : " + ex);
        ex.printStackTrace();
      }
    }

    /**
     * @see com.esri.arcgis.beans.map.IMapControlEvents2Adapter#onAfterScreenDraw(IMapControlEvents2OnAfterScreenDrawEvent
     *      theEvent)
     * @param theEvent
     */
    public void onAfterScreenDraw(IMapControlEvents2OnAfterScreenDrawEvent theEvent)
    {
      try
      {
        // Set mouse pointers
        pageLayoutBean.setMousePointer(esriControlsMousePointer.esriPointerDefault);
        mapBean.setMousePointer(esriControlsMousePointer.esriPointerDefault);
        if (!updateFocusMap)
          return;
        // Get IActiveView interface
        IActiveView activeView = pageLayoutBean.getActiveView();
        // Get IDisplayTransformation interface
        IDisplayTransformation displayTransformation = activeView.getScreenDisplay().getDisplayTransformation();
        // Set the visible extent of the focus map
        displayTransformation.setVisibleBounds(mapBean.getExtent());
        // Refresh the focus map
        activeView.refresh();
        updateFocusMap = false;
      }
      catch (Exception ex)
      {
        System.out.println("Exception in MapControlListener#onAfterScreenDraw : " + ex);
        ex.printStackTrace();
      }
    }

    /**
     * @see com.esri.arcgis.beans.map.IMapControlEvents2Adapter#onBeforeScreenDraw(IMapControlEvents2OnBeforeScreenDrawEvent
     *      theEvent)
     * @param theEvent
     */
    public void onBeforeScreenDraw(IMapControlEvents2OnBeforeScreenDrawEvent theEvent)
    {
      try
      {
        // Set mouse pointer
        pageLayoutBean.setMousePointer(esriControlsMousePointer.esriPointerHourglass);
        mapBean.setMousePointer(esriControlsMousePointer.esriPointerHourglass);
      }
      catch (Exception ex)
      {
        System.out.println("Exception in MapControlListener#onBeforeScreenDraw : " + ex);
        ex.printStackTrace();
      }
    }
  }// End of MapControlListener class

  /**
   * Main program to start the program execution.
   * 
   * @param s
   */
  public static void main(String s[])
  {
    try
    {
      EngineInitializer.initializeVisualBeans();
      // Set the system look and feel
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

      initializeArcGISLicenses();

      CopyFocusMap copyFocusMap = new CopyFocusMap();
      copyFocusMap.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    catch (Exception ex)
    {
      ex.printStackTrace();
    }
  }
  
  static void initializeArcGISLicenses() {
    try {
      AoInitialize ao = new AoInitialize();
      
      if (ao.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeEngine) 
          == esriLicenseStatus.esriLicenseAvailable)
        ao.initialize(esriLicenseProductCode.esriLicenseProductCodeEngine);
      else if (ao.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeArcView) 
          == esriLicenseStatus.esriLicenseAvailable)
        ao.initialize(esriLicenseProductCode.esriLicenseProductCodeArcView);
      else if (ao.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeArcEditor) 
          == esriLicenseStatus.esriLicenseAvailable)
        ao.initialize(esriLicenseProductCode.esriLicenseProductCodeArcEditor);
      else if (ao.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeArcInfo) 
          == esriLicenseStatus.esriLicenseAvailable)
        ao.initialize(esriLicenseProductCode.esriLicenseProductCodeArcInfo);
    } catch (Exception e) {e.printStackTrace();}
  }  
}