GIS Client
arcgissamples\scenario\map\DrawTool.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.scenario.map;

/**This class extends a JComponent which can be added to map for receiving
 * mouse listeners that occurs in the map.
 * Only one tool is selected at any point in time
 * When zoomin, zoomout tool is slected a rubber band is drawn on the screen as mouse is dragged.
 * When the pan tool is selected mouse clicked event will cause the map to begin panning.
 * When identify is selected, a single click in the map causes this tool to obtain one or more feature
 * location near the mouse click location.
 *
 */

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.SwingUtilities;


public class DrawTool extends javax.swing.JComponent implements  MouseListener,MouseMotionListener{

  private static final long serialVersionUID = 1L;
//  Active Tool is set to a negative value to indicate that there is no tool selected
  public static int ACTIVETOOL = -1;
  //zoomin tool
  public static final int ZOOMIN = 0;
  //zoomout
  public static final int ZOOMOUT = 1;
  //pan
  public static final int PAN = 2;
  //identify
  public static final int IDENTIFY = 3;


  //Defines rubberband shape.
  public int DRAWTYPE = -1;
  //rectangle
  public final static int RECTANGLE = 2;
  private final static int NONE = -1;

  //buffer width for identify
  protected double identifyRectangleWidth = 6.0;

  //Map component
  protected MapComponent _mapComponent;

  //Start and end click mouse click positions
  private int X = 0;
  private int Y = 0;
  private int X1 = 0;
  private int Y1 = 0;

  //Indicate mouse pressed and mouse released
  private boolean mousePressed = false;
  private boolean mouseReleased = false;

  //To hold the rubber band image drawn on map
  protected Shape shape;

  public DrawTool(){
    this(null);
  }

  public DrawTool(MapComponent mc){
    _mapComponent = mc;
  }

  /**Sets the map component
   * @param mc
   */

  public void setMapComonentByRef(MapComponent mc) {
    _mapComponent = mc;
  }

  /**Sets the active tool
   * Only one active tool is selected at any time
   * @param tool
   */

  public void setActiveTool(int tool) {
    ACTIVETOOL = tool;
    switch(tool) {
    case PAN: 
    case IDENTIFY:
      //Don't draw anything on the map
      DRAWTYPE = NONE;
      break;
    default :
      //Zoom in or Zoom out draw rectangle
      DRAWTYPE = RECTANGLE;
    }
  }

  public void paint(Graphics g) {
    //Check if the component is zero
    java.awt.Rectangle rect = getBounds();
    if(rect.width > 0 || rect.height > 0) {
      //If drawing is initiated,
      if(X1 > 0 && Y1 > 0) {
        //get the graphic object
        Graphics2D g2D = (Graphics2D)g;
        //Draw with new coordinates
        draw(X1, Y1, g2D);
        X1 = 0;
        Y1 = 0;
      }
    }
  }

  /**Draws the rectangle on the screen
   * @param X1
   * @param Y1
   * @param g2D
   */

  public void draw(int X1, int Y1, Graphics2D g2D) {
    switch(DRAWTYPE) {
    case RECTANGLE:
      //Get the difference of original and new point
      int diffx = X1 - X;
      int diffy = Y1 - Y;
      //Get the absolute value of width and height
      int w = Math.abs(diffx);
      int h = Math.abs(diffy);
      //Create point object
      Point p = new Point(X, Y);
      if(diffx <0) {
        w = -diffx;
        p.x = X1;
      }
      if(diffy <0){
        h = -diffy;
        p.y = Y1;
      }
      //Create shape object
      shape = new Rectangle(p.x, p.y, w, h);
      break;
    }
    //Set color to red
    g2D.setColor(Color.red);
    if(!mouseReleased) {
      //Draw the shape on the component
      g2D.draw(shape);
    }
    mouseReleased = false;
  }

  /**Stores initial posistion of the mouse click positions.
   * If identify tool is selected. MapComponents identify method is called to
   * display identify dialog.
   * @param e
   */

  public void mousePressed(MouseEvent e) {
    switch(ACTIVETOOL) {
    case NONE:
      break;
    case ZOOMIN: case ZOOMOUT: case PAN:
      //If mouse is pressed before and not released
      //Don't do anything
      if (mousePressed)
        return;
      //Set mouse pressed flag
      mousePressed = true;
      //Check if it is left click
      if (SwingUtilities.isLeftMouseButton(e)) {
        //Store the initial x and y coordinates.
        X = e.getX();
        Y = e.getY();
      }
      break;
    case IDENTIFY:
      //Buffer identify area
      double widthby2 = identifyRectangleWidth * 0.5;
      try {
        //Create an envelope rectangle
        Envelope1 envelope = new Envelope1(
            e.getX()-widthby2,
            e.getY() - widthby2,
            identifyRectangleWidth,
            identifyRectangleWidth);
        _mapComponent.identify(envelope);
      }
      catch (Exception ex) {
      }
    }

  }

  /**Creates the envelope using mouseclick and released positions.
   * and calls corresponding methods in the map control based on the
   * selected tool
   * @see java.awt.event.MouseListener#mouseReleased
   * @param e MouseEvent
   */

  public void mouseReleased(MouseEvent e) {
    switch(ACTIVETOOL) {
    case NONE:
      break;
    case ZOOMIN:
    case ZOOMOUT:
      if (SwingUtilities.isLeftMouseButton(e)) {
        mouseReleased = true;
        //Clear the map component
        repaint();
        Envelope1 env = null;
        //Get the final rectangle drawn on the map
        if(shape != null) {
          Rectangle rect = shape.getBounds();
          env = new Envelope1(rect.x, rect.y, rect.width, rect.height);
        }
        if (ACTIVETOOL == ZOOMIN)
          //Perform zoomin
          _mapComponent.setZoomInExtent(env);
        else
          //Do zoomout
          _mapComponent.setZoomOutExtent(env);
        //Reset the x and y coordinates
        X = 0;
        Y = 0;
        //Reset the shape
        shape = null;
      }
      //Set mouse pressed to false
      mousePressed = false;
      break;
    case PAN :
      if (SwingUtilities.isLeftMouseButton(e)) {
        mouseReleased = true;
        mousePressed = false;
        mouseDragged(e);
        //Get the pan offset
        _mapComponent.panWithCurrentExtent(X - e.getX(), Y - e.getY());
      }
      break;
    }

  }

  /**Draws rubberband for  zoomin and zoomout operations
   * Gets the pan offset if the active tool selected is pan
   * @param e MouseEvent
   */

  public void mouseDragged(MouseEvent e) {
    switch (ACTIVETOOL) {
    case NONE:
      break;
    case ZOOMIN:
    case ZOOMOUT:
      if (SwingUtilities.isLeftMouseButton(e)) {
        //Get the new points
        X1 = e.getX();
        Y1 = e.getY();
        //Draw the rectangle
        repaint();
      }
      break;
    }
  }

  public void mouseClicked(MouseEvent e) {}

  public void mouseEntered(MouseEvent e) {}

  public void mouseExited(MouseEvent e) {}

  public void mouseMoved(MouseEvent e) {}

}