Rotate display
arcgissamples\mapbean\RotateDisplay.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.mapbean;

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

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

import com.esri.arcgis.beans.map.MapBean;
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.IMapControlEvents2OnMouseMoveEvent;
import com.esri.arcgis.controls.IMapControlEvents2OnMouseUpEvent;
import com.esri.arcgis.controls.esriControlsMousePointer;
import com.esri.arcgis.geometry.IEnvelope;
import com.esri.arcgis.geometry.Point;
import com.esri.arcgis.system.AoInitialize;
import com.esri.arcgis.system.EngineInitializer;
import com.esri.arcgis.system.esriLicenseProductCode;
import com.esri.arcgis.system.esriLicenseStatus;


/**
 * Description:This sample primarily demonstrates setting the MapBean's Rotation property, and
 *    secondly demonstrates setting the MapBean MouseIcon and MousePointer properties.<p/>
 *
 *    The file chooser dialog allows users to search and
 *    select map documents, which are validated and loaded into the MapBean using
 *    the CheckMxFile and LoadMxFile methods. The OnBeforeScreenDraw and OnAfterScreenDraw
 *    events are used to set the MousePointer while the display is refreshing due to Extent
 *    changes.
 *
 *    The OnMouseDown event uses either the TrackRectangle method to zoom in or the
 *    IScreenDisplay RotateStart method to start rotating around the centre of the
 *    display based upon the current mouse location. The OnMouseMove event uses the
 *    IScreenDisplay RotateMoveTo and RotateTimer methods to move and re-draw the
 *    display to the screen. The OnMouseUp event uses the IScreenDisplay RotateStop
 *    method to determine the angle of rotation. The MapBean's Rotation property
 *    is set to this angle, and the display is refreshed is reflect the change.
 *    Note: Creating custom cursor for rotation is not implemented.
 */
public class RotateDisplay extends JFrame implements ActionListener {
  JPanel topPanel = null;
  JPanel mainPanel = null;
  JPanel bottomPanel = null;

  JButton loadMapDocumentButton = null;
  JButton zoomToFullButton = null;
  JTextField pathField;

  String helpLabelString = "Left mouse button to zoomin and Right mouse button to rotate";

  JLabel helpLabel = null;

  MapBean mapBean = null;
  Point mPoint = null;
  boolean rotating;
  
  static AoInitialize aoInit;

  public RotateDisplay() {
    super("Rotate Display");
    buildFrame();
    setSize(500, 400);
    setVisible(true);
    initControl();
  }

  /**This method builds 'this' frame as per the following diagram:
   *
   *   /----------------------------------------------------------\
   *   | JButton    BorderLayout.NORTH                            |
   *   | JTextField                                               |
   *   |----------------------------------------------------------|
   *   |                                                          |
   *   |                                                          |
   *   |                    MapBean                               |
   *   |                   BorderLayout.CENTER                    |
   *   |                                                          |
   *   |                                                          |
   *   |                                                          |
   *   |                                                          |
   *   |----------------------------------------------------------|
   *   |                  BorderLayout.SOUTH                      |
   *   |                                                          |
   *   | JButton          JLabel                                  |
   *   |                                                          |
   *   \----------------------------------------------------------/
   */


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

    topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS));
    mainPanel.setLayout(new BorderLayout());
    bottomPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 0));

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

    pathField = new JTextField();
    pathField.setEditable(false);
    pathField.setAlignmentX(0);
    pathField.setAlignmentY(0);
    topPanel.add(loadMapDocumentButton);
    topPanel.add(Box.createVerticalStrut(5));
    topPanel.add(pathField);
    topPanel.add(Box.createVerticalStrut(5));

    zoomToFullButton = new JButton("ZoomToFullButton");
    zoomToFullButton.addActionListener(this);

    helpLabel = new JLabel(helpLabelString);
    bottomPanel.add(zoomToFullButton);
    bottomPanel.add(helpLabel);

    mapBean = new MapBean();
    mainPanel.add(topPanel, BorderLayout.NORTH);
    mainPanel.add(mapBean, BorderLayout.CENTER);
    mainPanel.add(bottomPanel, BorderLayout.SOUTH);
    mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

    getContentPane().add(mainPanel, BorderLayout.CENTER);
  }

  /** Initilizes control
   *  creates and intializes member variables
   * */


  public void initControl() {
    try {
      //Disbale the MapBean
      mapBean.setEnabled(false);
      mPoint = new Point();
      rotating = false;
      //Add map control listener
      mapBean.addIMapControlEvents2Listener(new MapControlListener());
    }
    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() == loadMapDocumentButton) {
      try {
        loadFile();
      }
      catch (IOException ex) {
        System.out.println("Exception in loadMapDocumentButton#actionPerformed" + ex);
        ex.printStackTrace();
      }
    }

    if(event.getSource() == zoomToFullButton) {
      try {
        mapBean.setExtent(mapBean.getFullExtent());
      }
      catch (IOException ex) {
        System.out.println("Exception in zoomToFullButton#actionPerformed" +
            ex);
        ex.printStackTrace();
      }
    }
  }

  /**
   * Method loadFile loads the specified mxd file
   */
  public void loadFile() throws IOException {
    FileDialog fileDialog = new FileDialog(new JFrame(), "Open MXD file", FileDialog.LOAD);
    fileDialog.setVisible(true);
    String path = fileDialog.getDirectory();
    String name = fileDialog.getFile();
    String fileChosen = path + File.separator + name;
    if (mapBean.checkMxFile(fileChosen)) {
      System.out.print("Loading " + name + " ... ");
      mapBean.loadMxFile(fileChosen, null, null);
      System.out.println("done");
      pathField.setText(name);
    }
    else {
      pathField.setText(name + " could not be loaded.");
      JOptionPane.showMessageDialog(null, name + " could not be loaded.");
    }
    return;
  }

  /**
   * Description: Class which extends map control event class IMapControlEvents2Adapter
   * @see com.esri.arcgis.beans.map.IMapControlEvents2Adapter
   */
  class MapControlListener extends IMapControlEvents2Adapter {
    /**
     * @see com.esri.arcgis.beans.map.IMapControlEvents2Adapter#onMouseMove(IMapControlEvents2OnMouseMoveEvent theEvent)
     * @param theEvent
     */
    public void onMouseMove(IMapControlEvents2OnMouseMoveEvent theEvent) {
      try {
        if(!rotating) return;
        //Create point object.
        Point point = new Point();
        //Set the coordinates of current mouse location
        point.putCoords(theEvent.getMapX(), theEvent.getMapY());

        //Rotate the display based upon the current mouse location
        mapBean.getActiveView().getScreenDisplay().rotateMoveTo(point);
        //Draw the rotated display
        mapBean.getActiveView().getScreenDisplay().rotateTimer();
      }
      catch(Exception ex) {
        System.out.println("Exception in MapControlListener#onMouseMove : " + ex);
        ex.printStackTrace();
      }
    }

    /**
     * @see com.esri.arcgis.beans.map.IMapControlEvents2Adapter#onMouseDown(IMapControlEvents2OnMouseDownEvent theEvent)
     * @param theEvent
     */

    public void onMouseDown(IMapControlEvents2OnMouseDownEvent theEvent) {
      try {
        //If left mouse button
        if(theEvent.getButton() == 1) {
          //User not rotating
          rotating = false;
          //Get IEnvelope interface
          IEnvelope envelope = null;
          envelope = mapBean.trackRectangle();
          //If user dragged a rectangle
          if(envelope != null)
            mapBean.setExtent(envelope);
        }
        else if(theEvent.getButton() == 2) {
          rotating = true;
          Point point = new Point();
          //Set the coordinates of current mouse location
          point.putCoords(theEvent.getMapX(), theEvent.getMapY());
          //Set the coordinates of the center of the current extent
          double x = mapBean.getExtent().getXMin() + (mapBean.getExtent().getWidth()/2);
          double y = mapBean.getExtent().getYMin() + (mapBean.getExtent().getHeight()/2);
          mPoint.setX(x);
          mPoint.setY(y);
          //Start rotating the display
          mapBean.getActiveView().getScreenDisplay().rotateStart(point, mPoint);
        }
      }
      catch(Exception ex) {
        System.out.println("Exception in MapControlListener#onMouseDown : " + ex);
        ex.printStackTrace();
      }
    }

    /**
     * @see com.esri.arcgis.beans.map.IMapControlEvents2Adapter#onMouseUp(IMapControlEvents2OnMouseUpEvent theEvent)
     * @param theEvent
     */


    public void onMouseUp(IMapControlEvents2OnMouseUpEvent theEvent)  {
      try {
        rotating = false;
        //Get rotation angle
        double rotationAngle = mapBean.getActiveView().getScreenDisplay().rotateStop();
        //Rotate the MapBean's display
        mapBean.setRotation(rotationAngle);
        //Refresh the display
        mapBean.refresh(esriViewDrawPhase.esriViewBackground, null, null);
      }
      catch(Exception ex) {
        System.out.println("Exception in MapControlListener#onMouseUp : " + ex);
        ex.printStackTrace();
      }
    }

    /**
     * @see com.esri.arcgis.beans.map.IMapControlEvents2Adapter#onAfterScreenDraw(IMapControlEvents2OnAfterScreenDrawEvent theEvent)
     * @param theEvent
     */


    public void onAfterScreenDraw(IMapControlEvents2OnAfterScreenDrawEvent theEvent) {
      try {
        if(!rotating)
          mapBean.setMousePointer(esriControlsMousePointer.esriPointerDefault);
      }
      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 {
        if(!rotating)
          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[]) {
    System.out.println("Starting RotateDisplay - An ArcObjects Java SDK Developer Sample");

    try {
      EngineInitializer.initializeVisualBeans();
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      
      aoInit = new AoInitialize();
      initializeArcGISLicenses(aoInit);
      
      
      RotateDisplay thisApp = new RotateDisplay();
      thisApp.setDefaultCloseOperation(RotateDisplay.EXIT_ON_CLOSE);
    } catch (Exception ex) {
      System.out.println("Sample failed: " + ex.getMessage());
      ex.printStackTrace();
    }
  }

  static void initializeArcGISLicenses(AoInitialize aoInit) {
    try {
      if (aoInit.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeEngine) 
          == esriLicenseStatus.esriLicenseAvailable)
        aoInit.initialize(esriLicenseProductCode.esriLicenseProductCodeEngine);
      else if (aoInit.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeArcView) 
          == esriLicenseStatus.esriLicenseAvailable)
        aoInit.initialize(esriLicenseProductCode.esriLicenseProductCodeArcView);
      else if (aoInit.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeArcEditor) 
          == esriLicenseStatus.esriLicenseAvailable)
        aoInit.initialize(esriLicenseProductCode.esriLicenseProductCodeArcEditor);
      else if (aoInit.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeArcInfo) 
          == esriLicenseStatus.esriLicenseAvailable)
        aoInit.initialize(esriLicenseProductCode.esriLicenseProductCodeArcInfo);
    } catch (Exception e) {e.printStackTrace();}
  }
}