Editing in a custom application
arcgissamples\editing\EditingPanelActionListener.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.editing;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

import com.esri.arcgis.beans.map.MapBean;
import com.esri.arcgis.carto.IFeatureLayer;
import com.esri.arcgis.carto.IMap;
import com.esri.arcgis.controls.ControlsEditingEditTool;
import com.esri.arcgis.controls.ControlsEditingSketchTool;
import com.esri.arcgis.controls.ControlsRedoCommand;
import com.esri.arcgis.controls.ControlsUndoCommand;
import com.esri.arcgis.controls.EngineEditor;
import com.esri.arcgis.controls.IEngineEditEventsAdapter;
import com.esri.arcgis.controls.IEngineEditEventsOnSketchModifiedEvent;
import com.esri.arcgis.controls.IEngineEditTask;
import com.esri.arcgis.geodatabase.IDataset;
import com.esri.arcgis.geodatabase.IDatasetProxy;
import com.esri.arcgis.geodatabase.IFeature;
import com.esri.arcgis.geodatabase.IFeatureClass;
import com.esri.arcgis.geodatabase.IFeatureCursor;
import com.esri.arcgis.geodatabase.ISpatialFilter;
import com.esri.arcgis.geodatabase.SpatialFilter;
import com.esri.arcgis.geodatabase.esriSpatialRelEnum;
import com.esri.arcgis.geometry.IGeometry;
import com.esri.arcgis.geometry.Polyline;
import com.esri.arcgis.interop.AutomationException;
import com.esri.arcgis.systemUI.ITool;
import com.esri.arcgis.systemUI.esriCommandStyles;

public class EditingPanelActionListener extends IEngineEditEventsAdapter implements ActionListener {

  private static final long serialVersionUID = 1L;

  private EditingPanel editingPanel;

  private MapBean mapBean;

  private EngineEditor editor;

  public EditingPanelActionListener(EditingPanel editingPanel, MapBean mapBean) {
    this.editingPanel = editingPanel;
    this.mapBean = mapBean;
    try {
      this.editor = new EngineEditor();
      this.editor.enableUndoRedo(true);
      this.editor.setStickyMoveTolerance(10000);
      Object tbr = this.editingPanel.getToolbarEditing().getObject();
      // ensures that the operationStack will function
      editor.startup(tbr);
      editor.addTask(new ReshapePolylineEditTask());

      // Listen to OnSketchModified engine editor event
      editor.addIEngineEditEventsListener(this);

    } catch (Exception e) {
      e.printStackTrace();
    }

  }

  /* This method is executed on Swing's Event Dispatching Thread (EDT). Normally, we don't
   * execute lengthy arcobjects operations on this thread so as keep the application responsive.
   * In this case we do execute some arcobjects methods on the EDT because the methods are
   * relatively inexpensive. */
  public void actionPerformed(ActionEvent event) {
    try {
      if (event.getSource() == editingPanel.getBtnStart()) {
        // start editing on the highways layer
        IFeatureLayer featlayer = findFeatureLayer("ushigh");
        editor.startEditing(new IDatasetProxy(featlayer.getFeatureClass())
        .getWorkspace(), this.mapBean.getMap());
        editor.setTargetLayer(featlayer, 0);
        //adjust the state of the editing buttons
        editingPanel.getBtnCreate().setEnabled(true);
        editingPanel.getBtnReshape().setEnabled(true);
        editingPanel.getBtnModify().setEnabled(true);
        editingPanel.getBtnFinish().setVisible(true);
        editingPanel.getBtnStart().setVisible(false);

      } else if (event.getSource() == editingPanel.getBtnFinish()) {
        // reset the toolbars
        editingPanel.getToolbarEditing().removeAllItems();
        editingPanel.getToolbarEditing().setCurrentToolByRef(null);
        editingPanel.getToolbarUndoRedo().removeAllItems();
        // prompt the user to save the edits
        boolean saveEdits = false;
        if (editor.hasEdits())
          if (JOptionPane.showConfirmDialog(null,
              "Do you want to save your edits?", "Save Edits?",
              JOptionPane.YES_NO_OPTION) == JOptionPane.OK_OPTION)
            saveEdits = true;
        // stop editing
        editor.stopEditing(saveEdits);
        // adjust the state of the editing buttons
        editingPanel.getBtnCreate().setEnabled(false);
        editingPanel.getBtnCreate().setSelected(false);
        editingPanel.getBtnReshape().setEnabled(false);
        editingPanel.getBtnReshape().setSelected(false);
        editingPanel.getBtnModify().setEnabled(false);
        editingPanel.getBtnModify().setSelected(false);
        editingPanel.getBtnFinish().setVisible(false);
        editingPanel.getBtnStart().setVisible(true);
      } else if (event.getSource() == editingPanel.getBtnCreate()) {
        // adjust the state of the editing buttons
        editingPanel.getBtnCreate().setSelected(true);
        editingPanel.getBtnCreate().setEnabled(false);
        editingPanel.getBtnReshape().setSelected(false);
        editingPanel.getBtnReshape().setEnabled(true);
        editingPanel.getBtnModify().setSelected(false);
        editingPanel.getBtnModify().setEnabled(true);
        // reset the toolbars
        editingPanel.getToolbarEditing().removeAllItems();
        editingPanel.getToolbarUndoRedo().removeAllItems();
        // add sketch tool to the editing toolbar
        ITool sketchTool = new ControlsEditingSketchTool();
        editingPanel.getToolbarEditing().addItem(sketchTool, 0, 0, false, 0,
            esriCommandStyles.esriCommandStyleIconOnly);
        // activate the sketch tool
        editingPanel.getToolbarEditing().setCurrentToolByRef(sketchTool);
        // add Undo and Redo tools to the other toolbar
        editingPanel.getToolbarUndoRedo().addItem(ControlsUndoCommand.getClsid(),0,0,false,0,esriCommandStyles.esriCommandStyleIconOnly);
        editingPanel.getToolbarUndoRedo().addItem(ControlsRedoCommand.getClsid(),0,1,false,0,esriCommandStyles.esriCommandStyleIconOnly);
        // activate the  CreateNewFeature task
        IEngineEditTask editTask = editor
        .getTaskByUniqueName("ControlToolsEditing_CreateNewFeatureTask");
        editor.setCurrentTaskByRef(editTask);
      } else if (event.getSource() == editingPanel.getBtnModify()) {
        // adjust the state of the editing buttons
        editingPanel.getBtnModify().setSelected(true);
        editingPanel.getBtnModify().setEnabled(false);
        editingPanel.getBtnReshape().setSelected(false);
        editingPanel.getBtnReshape().setEnabled(true);
        editingPanel.getBtnCreate().setSelected(false);
        editingPanel.getBtnCreate().setEnabled(true);
        // reset the toolbars
        editingPanel.getToolbarEditing().removeAllItems();
        editingPanel.getToolbarUndoRedo().removeAllItems();
        // add the Edit, InsertVertex and DeleteVertext tools
        ITool editTool = new ControlsEditingEditTool();
        editingPanel.getToolbarEditing().addItem(editTool, 0, 0, false, 0,
            esriCommandStyles.esriCommandStyleIconOnly);
        editingPanel.getToolbarEditing().addItem(new CustomVertexTools(), 1,
            1, true, 0, esriCommandStyles.esriCommandStyleIconOnly);
        editingPanel.getToolbarEditing().addItem(new CustomVertexTools(), 2,
            2, false, 0, esriCommandStyles.esriCommandStyleIconOnly);
        // activate the Edit tool
        editingPanel.getToolbarEditing().setCurrentToolByRef(editTool);
        // add the Undo and Redo tools to the other toolbar
        editingPanel.getToolbarUndoRedo().addItem(ControlsUndoCommand.getClsid(),0,0,false,0,esriCommandStyles.esriCommandStyleIconOnly);
        editingPanel.getToolbarUndoRedo().addItem(ControlsRedoCommand.getClsid(),0,1,false,0,esriCommandStyles.esriCommandStyleIconOnly);
        // activate the ModifyFeature task
        IEngineEditTask editTask = editor
        .getTaskByUniqueName("ControlToolsEditing_ModifyFeatureTask");
        editor.setCurrentTaskByRef(editTask);
      } else if (event.getSource() == editingPanel.getBtnReshape()) {
        // adjust the state of the editing buttons
        editingPanel.getBtnReshape().setSelected(true);
        editingPanel.getBtnReshape().setEnabled(false);
        editingPanel.getBtnCreate().setSelected(false);
        editingPanel.getBtnCreate().setEnabled(true);
        editingPanel.getBtnModify().setSelected(false);
        editingPanel.getBtnModify().setEnabled(true);
        // reset the toolbars
        editingPanel.getToolbarEditing().removeAllItems();
        editingPanel.getToolbarUndoRedo().removeAllItems();
        // Add the Edit and Sketch tools to the editing toolbar
        ITool editTool = new ControlsEditingEditTool();
        editingPanel.getToolbarEditing().addItem(editTool, 0, 0, false, 0,
            esriCommandStyles.esriCommandStyleIconOnly);
        editingPanel.getToolbarEditing().addItem(
            ControlsEditingSketchTool.getClsid(), 0, 1, false, 0,
            esriCommandStyles.esriCommandStyleIconOnly);
        editingPanel.getToolbarEditing().setCurrentToolByRef(editTool);
        editingPanel.getToolbarUndoRedo().addItem(ControlsUndoCommand.getClsid(),0,0,false,0,esriCommandStyles.esriCommandStyleIconOnly);
        editingPanel.getToolbarUndoRedo().addItem(ControlsRedoCommand.getClsid(),0,1,false,0,esriCommandStyles.esriCommandStyleIconOnly);
        // activate the ReshapePolyline java task
        IEngineEditTask editTask = editor
        .getTaskByUniqueName("Reshape_Polyline_Java");
        editor.setCurrentTaskByRef(editTask);
      }

    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  /*Logic to decide if the edit just made is invalid*/
  public void onSketchModified(IEngineEditEventsOnSketchModifiedEvent arg0)
  throws IOException, AutomationException {
    //prompt the user if the highway feature crosses a lake, and undo the sketch
    if (!isHighwaysEditValid()) {
      //Use Swing's Event Dispatching Thread (EDT) to display the JOptionPane
      SwingUtilities.invokeLater(new Runnable(){
        public void run() {
          JOptionPane.showMessageDialog(null, "Highway feature cannot cross a lake.", "Invalid Edit", JOptionPane.ERROR_MESSAGE);
        }
      });
      editingPanel.getToolbarEditing().getOperationStack().undo();
    }
  }

  private IFeatureLayer findFeatureLayer(String name) throws IOException,
  AutomationException {

    IFeatureLayer foundLayer = null;
    IDataset dataset = null;
    IMap map = this.mapBean.getMap();

    for (int i = 0; i < map.getLayerCount(); i++) {
      IFeatureLayer layer = (IFeatureLayer) map.getLayer(i);
      dataset = new IDatasetProxy(layer.getFeatureClass());
      if (dataset.getName().equals(name)) {
        foundLayer = layer;
        break;
      }
    }

    return foundLayer;
  }

  private boolean isHighwaysEditValid() throws IOException, AutomationException {
    {
      // put in all business logic here
      // In this example highways are not allowed to intersect the lakes layer
      boolean success = true;

      // get the protected areas layer
      IFeatureLayer lakesLayer = findFeatureLayer("us_lakes");

      // do a spatial filter
      if (editor.getGeometry() != null && editor.getGeometry() instanceof Polyline) {
        // crashes here
        IFeatureCursor cursor = findFeatures(editor.getGeometry(), lakesLayer
            .getFeatureClass(), esriSpatialRelEnum.esriSpatialRelIntersects,
            this.mapBean.getMap());
        IFeature feature = cursor.nextFeature();

        // could put more sophistictated logic in here
        if (feature != null)
          success = false;
      }

      return success;
    }

  }

  private IFeatureCursor findFeatures(IGeometry geometry,
      IFeatureClass featureClass, int spatialRelationship, IMap map)
  throws IOException, AutomationException {
    // 1 = esriSpatialRelIntersects
    // 7 = esriSpatialWithin
    // 8 = esriSpatialRelContains

    ISpatialFilter spatialFilter = new SpatialFilter();
    spatialFilter.setGeometryByRef(geometry);
    spatialFilter.setOutputSpatialReferenceByRef(featureClass
        .getShapeFieldName(), map.getSpatialReference());
    spatialFilter.setGeometryField(featureClass.getShapeFieldName());
    spatialFilter.setSpatialRel(spatialRelationship);

    IFeatureCursor featureCursor = featureClass.search(spatialFilter, false);
    return featureCursor;
  }
}